문제

I have a mask bitmap (bmpMask) that I am drawing onto a destination bitmap (bmpDest). Both bitmaps have alpha channels but are already full of opaque content.

What I want to do is produce transparent areas using GDI+ 'Draw...' methods on bmpMask so that bmpDest shows through when I draw bmpMask over it.

Of course gMask.DrawLine(Pens.Transparent, 0, y, wMax, y) causes no change to bmpMask, because GDI+ works as designed and doesn't draw anything when transparent. Even with semitransparent colors, only the r,g,b values of bmpMask's pixels are updated.

But what I want to do is issue a draw method that will change the alpha channel of bmpMask so it is transparent when drawn onto bmpDest. I know I can do this with SetPixel or speedier unsafe or Marshall alternatives, but that would cause a much more complicated solution. Thanks.

도움이 되었습니까?

해결책

Found 'the' answer after 3 years!

I never did get around to trying Dan's solution, so I don't want to take away from it, but this does exactly what I want:

    ' (setting composting mode is the key to getting the transparent
    ' line to actually result in setting the pixels to transparent-
    ' instead of just not drawing anything 'because it's transparent dummy' - 
    ' because it turns off the 'math' that is done to cause transparent
    ' image drawing to occur and just verbatim copies the bits).
    g1.CompositingMode = Drawing2D.CompositingMode.SourceCopy
    g1.DrawLine(Pens.Transparent, 0, y, wMax, y)
    g1.CompositingMode = Drawing2D.CompositingMode.SourceOver

CompostingMode is the Key! I was finally trying to fix this lack again in my program, and a Google search turned up this item that has nothing to do with what I searched for (hey, google can read your mind).

Is Graphics.DrawImage too slow for bigger images?

Wonderful! Now 10 bucks says, nobody in the whole wide world ever reads this. 755

다른 팁

To my knowledge, the only way to alter the alpha channel is, as you say, to use SetPixel or (of course, much better) pointers. Depending on what you're trying to do to, you could get by with creative use of a ColorMatrix. That will let you alter a DrawImage operation in such a way that you can interchange the meaning of R/G/B/A as you draw it. Try this to get an idea:

        using ( var bmp = new Bitmap( 100, 100 ) )
        using ( var g = Graphics.FromImage( bmp ) )
        using ( var ia = new ImageAttributes() )
        {
            float R = 1;
            float G = 0;
            float B = 0;
            ia.SetColorMatrix( new ColorMatrix( new float[][] {
                new float[] {1, 0, 0, R, 0},
                new float[] {0, 1, 0, G, 0},
                new float[] {0, 0, 1, B, 0},
                new float[] {0, 0, 0, 0, 0},
                new float[] {0, 0, 0, 0, 1}} ) );
            g.Clear( Color.White );
            g.FillEllipse( Brushes.Blue, 10, 10, 30, 30 );
            g.FillEllipse( Brushes.Red, 60, 10, 30, 30 );
            g.FillEllipse( Brushes.Green, 10, 60, 30, 30 );
            g.FillEllipse( Brushes.Black, 60, 60, 30, 30 );
            e.Graphics.DrawImage(
                bmp,
                new Rectangle( 0, 0, 100, 100 ),
                0, 0, 100, 100,
                GraphicsUnit.Pixel,
                ia );
        }

Try setting R/G/B to 1 respectively and see how that changes what colors that come out solid/transparent. But, if you should like to alter the alpha channel of the bitmap directly, here's how to do it: Soft edged images in GDI+.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top