Drawing over background but still being shown?

S

Sharon

Hello Gurus,

I'm using VS2005, .NET Framework 2.0.

I'm drawing lines/rectangles/arrow etc. over a background image.
The background image might change it's colors so the lines/rectangles/arrow
I'm drawing will bled in the background and the user may not see it clear
enough.

I want draw the lines/rectangles/arrow so their color will very according to
the behind background image color.
Any idea how to do that?
 
J

Jeff Johnson

I'm using VS2005, .NET Framework 2.0.

I'm drawing lines/rectangles/arrow etc. over a background image.
The background image might change it's colors so the
lines/rectangles/arrow
I'm drawing will bled in the background and the user may not see it clear
enough.

I want draw the lines/rectangles/arrow so their color will very according
to
the behind background image color.
Any idea how to do that?

[Adding microsoft.public.dotnet.framework.drawing to the newsgroups list]

You might be able to construct some sort of color matrix that you can apply
to your graphics so that they will always have a good contrast to the
background color, but I can't suggest any particular implementation to you,
just a concept. In fact, I don't know if there's a single matrix that'll do
what you want. I did something a while back where I was generating a bunch
of colors in Excel for cell backgrounds and I wanted to put the name of the
color in the cell. When the color got "dark enough" I wanted to switch the
cell text to white instead of black. I found a formula to calculate the
luminescence of a color and just picked a threshhold. Above that threshhold
I deemed the background to be "light enough" and used black. Below, I used
white. In other words, you'll probably have to do some manual twiddling with
whatever method you ultimately choose.
 
J

Jeff Johnson

Jeff Johnson said:
I'm using VS2005, .NET Framework 2.0.

I'm drawing lines/rectangles/arrow etc. over a background image.
The background image might change it's colors so the
lines/rectangles/arrow
I'm drawing will bled in the background and the user may not see it clear
enough.

I want draw the lines/rectangles/arrow so their color will very according
to
the behind background image color.
Any idea how to do that?

[Adding microsoft.public.dotnet.framework.drawing to the newsgroups list]

You might be able to construct some sort of color matrix that you can
apply to your graphics so that they will always have a good contrast to
the background color, but I can't suggest any particular implementation to
you, just a concept. In fact, I don't know if there's a single matrix
that'll do what you want. I did something a while back where I was
generating a bunch of colors in Excel for cell backgrounds and I wanted to
put the name of the color in the cell. When the color got "dark enough" I
wanted to switch the cell text to white instead of black. I found a
formula to calculate the luminescence of a color and just picked a
threshhold. Above that threshhold I deemed the background to be "light
enough" and used black. Below, I used white. In other words, you'll
probably have to do some manual twiddling with whatever method you
ultimately choose.

So while driving home yesterday I thought about a potential method which
should give you some very different colors in most cases: you could flip the
bits of the red, green, and blue components of the background color. The
only place where this won't give you colors with much contrast is mid-range
grays. Take, for example, (128, 128, 128). Flipping these bits gives you
(127, 127, 127), which isn't very different. The further you get from 128,
though, the more contrast you'll get.
 
T

Tom Shelton

Jeff Johnson said:
I'm using VS2005, .NET Framework 2.0.

I'm drawing lines/rectangles/arrow etc. over a background image.
The background image might change it's colors so the
lines/rectangles/arrow
I'm drawing will bled in the background and the user may not see it clear
enough.

I want draw the lines/rectangles/arrow so their color will very according
to
the behind background image color.
Any idea how to do that?

[Adding microsoft.public.dotnet.framework.drawing to the newsgroups list]

You might be able to construct some sort of color matrix that you can
apply to your graphics so that they will always have a good contrast to
the background color, but I can't suggest any particular implementation to
you, just a concept. In fact, I don't know if there's a single matrix
that'll do what you want. I did something a while back where I was
generating a bunch of colors in Excel for cell backgrounds and I wanted to
put the name of the color in the cell. When the color got "dark enough" I
wanted to switch the cell text to white instead of black. I found a
formula to calculate the luminescence of a color and just picked a
threshhold. Above that threshhold I deemed the background to be "light
enough" and used black. Below, I used white. In other words, you'll
probably have to do some manual twiddling with whatever method you
ultimately choose.

So while driving home yesterday I thought about a potential method which
should give you some very different colors in most cases: you could flip the
bits of the red, green, and blue components of the background color. The
only place where this won't give you colors with much contrast is mid-range
grays. Take, for example, (128, 128, 128). Flipping these bits gives you
(127, 127, 127), which isn't very different. The further you get from 128,
though, the more contrast you'll get.

Here is something I came up with once... The idea was to find the inverse
color, but give it a bit of a white shift to overcome the 128,128,128 problem.
Seems to work ok...

Color ComputeBalancedInverse (Color original)
{
int red = 255 - original.R;
int green = 255 - original.G;
int blue = 255 - original.B;

double kr = (red != 0) ? 255.0 / red : 1.0;
double kg = (green != 0) ? 255.0 / green : 1.0;
double kb = (blue != 0) ? 255.0 / blue : 1.0;

return Color.FromArgb ((int)(red * kr), (int)(green * kg), (int)(blue * kb));
}

Well, anyway that should be close - the original was VB.NET, so I just
converted it in my head...

But, the results look somehthing like:

Input Output
808080 FFFFFF
FFFFFF 000000
FF0000 00FFFF
FFFF00 0000FF

Basically, if you had text and you set the foreground and background colors to
one of these pairs, the text should be readable...
 
B

Bob Powell [MVP]

Hello,
Actually this was one of my biggest bugbears with the GDI+ system when I
started out many years ago. I didn't like that many of the standard GDI
functions had not been brought into the GDI+ world..

In this case, you can do one of two things. You could resort to drawing in
GDI using interop and specifying an XOR operation for the drawing or you
could be clever about the use of GDI+ and draw your content onto an
in-memory bitmap then combine that one with a hand-coded colour contrast
mechanism using LockBits for maximum speed.

As you've probably discovered, a ColorMatrix is applied to the image as a
whole and does not take two images as input so no matter how you draw it,
you'll always get some colours that resemble ones already on your
background.

In the WPF world of course you could be dreadfully clever and write a shader
to do the job for you.

--
--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.


Tom Shelton said:
Jeff Johnson said:
I'm using VS2005, .NET Framework 2.0.

I'm drawing lines/rectangles/arrow etc. over a background image.
The background image might change it's colors so the
lines/rectangles/arrow
I'm drawing will bled in the background and the user may not see it
clear
enough.

I want draw the lines/rectangles/arrow so their color will very
according
to
the behind background image color.
Any idea how to do that?

[Adding microsoft.public.dotnet.framework.drawing to the newsgroups
list]

You might be able to construct some sort of color matrix that you can
apply to your graphics so that they will always have a good contrast to
the background color, but I can't suggest any particular implementation
to
you, just a concept. In fact, I don't know if there's a single matrix
that'll do what you want. I did something a while back where I was
generating a bunch of colors in Excel for cell backgrounds and I wanted
to
put the name of the color in the cell. When the color got "dark enough"
I
wanted to switch the cell text to white instead of black. I found a
formula to calculate the luminescence of a color and just picked a
threshhold. Above that threshhold I deemed the background to be "light
enough" and used black. Below, I used white. In other words, you'll
probably have to do some manual twiddling with whatever method you
ultimately choose.

So while driving home yesterday I thought about a potential method which
should give you some very different colors in most cases: you could flip
the
bits of the red, green, and blue components of the background color. The
only place where this won't give you colors with much contrast is
mid-range
grays. Take, for example, (128, 128, 128). Flipping these bits gives you
(127, 127, 127), which isn't very different. The further you get from
128,
though, the more contrast you'll get.

Here is something I came up with once... The idea was to find the inverse
color, but give it a bit of a white shift to overcome the 128,128,128
problem.
Seems to work ok...

Color ComputeBalancedInverse (Color original)
{
int red = 255 - original.R;
int green = 255 - original.G;
int blue = 255 - original.B;

double kr = (red != 0) ? 255.0 / red : 1.0;
double kg = (green != 0) ? 255.0 / green : 1.0;
double kb = (blue != 0) ? 255.0 / blue : 1.0;

return Color.FromArgb ((int)(red * kr), (int)(green * kg), (int)(blue *
kb));
}

Well, anyway that should be close - the original was VB.NET, so I just
converted it in my head...

But, the results look somehthing like:

Input Output
808080 FFFFFF
FFFFFF 000000
FF0000 00FFFF
FFFF00 0000FF

Basically, if you had text and you set the foreground and background
colors to
one of these pairs, the text should be readable...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top