views:

186

answers:

4

I want what's "behind" the yellow to show through.

EDIT 1: But, if I'm drawing on "white", I'd like the marker color to retain its pure yellowness.

EDIT 2: @Kevin's answer is probably correct, and I marked it correct, even though I didn't code it up. In my code, I'm settling for @Guffa's answer, using Color.FromArgb.

+3  A: 

You use a semi transparent color, for example with a 50% alpha opacity:

Color.FromArgb(128, Color.Yellow)

With a lower alpha value more of the background will show through.

Guffa
Thanks - This works, but not quite how I had hoped. I want the yellow itself to be more.... yellow.
Corey Trager
@Corey: Yes, it's not exactly the effect of a yellow marker, but it's as close as you can get with the built in drawing capabilities. Increasing the alpha value will make the yellow more distinct, but it will make less of the background shine through.
Guffa
A: 

Try using a SolidBrush initialised with a Color value with an alpha of less then 255. This should create a semi-transparent brush of the colour you use.

AakashM
+7  A: 

A highlighter is pigment, so it's essentially subtractive — you want to turn white into yellow, but not black into yellow. I don't know .NET, but what you want is a non-standard “blending mode”, specifically subtract. Specifically, set the blending mode to subtract and your color to pure blue (the color you want to subtract, leaving yellow). Black will be left alone, since there's no blue to subtract, and white will become yellow.

Unfortunately, many modern drawing interfaces leave out blending modes other than alpha, and it looks like this might be one of them. If you have access to the bitmap, you can implement it yourself — take each pixel value and set the blue component to zero. Or if the area you want to highlight is complicated, then: make a copy of your image, draw black over the highlighted area in the copy, then combine the red and green channels from the original and the blue channel from the copy into the final result image.

Kevin Reid
Yikes! This is beyond my level of ambition, but it's looking like your answer is the right answer if I don't want to compromise the effect, if I want the yellow to be yellow.
Corey Trager
Well, it's very simple — just one parameter setting — *if* you have a drawing system which supports blend modes.
Kevin Reid
Is this the same thing as "color burn" in some graphics apps? E.g., paint.net? (Learning something new every day! :D )
Greg D
Never heard of color burn. If http://www.adobetutorialz.com/articles/656/1/Feel-the-Color-Burn is accurate, then it isn't the same: in that article's Example 1, using subtract mode would, firstly, have the greatest effect in the *white* areas, not the black, and secondly, would not increase the saturation of the preexisting colors, but rather make them closer to black (given that you're blending in white (goes to black) rather than blue (goes to yellow))
Kevin Reid
+1  A: 

This is the code you need:

    protected override void OnPaint( PaintEventArgs e )
    {
        using ( var bmp = new Bitmap( 100, 100 ) )
        using ( var g = Graphics.FromImage( bmp ) )
        using ( var ia = new ImageAttributes() )
        {
            // 1. create a sample bitmap
            g.Clear( Color.White );
            var p = Point.Empty;
            foreach ( var color in new Color[] { Color.Black, Color.Gray, Color.LightBlue, Color.Green, Color.Red, Color.Magenta } )
                using ( var brush = new SolidBrush( color ) )
                {
                    g.DrawString( "Some sample text", SystemFonts.DefaultFont, brush, p );
                    p.Offset( 0, 16 );
                }
            // 2. transfer the bitmap on screen
            e.Graphics.DrawImage( bmp, Point.Empty );
            // 3. transfer a part of the bitmap on screen again, this time removing all blue
            ia.SetColorMatrix( new ColorMatrix( new float[][] {
                        new float[] {1, 0, 0, 0, 0},
                        new float[] {0, 1, 0, 0, 0},
                        new float[] {0, 0, 0, 0, 0},
                        new float[] {0, 0, 0, 1, 0},
                        new float[] {0, 0, 0, 0, 1}} ) );
            e.Graphics.DrawImage(
                bmp,
                new Rectangle( 30, 0, 40, 100 ),
                30, 0, 40, 100,
                GraphicsUnit.Pixel,
                ia );
        }
    }
danbystrom