views:

957

answers:

2

Is it possible to draw a transperancy mask of an image (that is, paint all visible pixels with a constant color) using Graphics::DrawImage? I am not looking for manually scanning the image pixel-by-pixel and creating a seperate mask image, I wonder if it's possible to draw one directly from the original image.

My guessing is that it should be done with certain manipulations to ImageAttributes, if possible at all.

The color of the mask is arbitrary and should be accurate, and it would be a plus if there can be a threshold value for the transparency.

A: 

Do you mean that you want to transform every existing color in the bitmap into one uniform color, while fully honoring the alpha/transparency information present in the image?

If so, just use the following colormatrix:

imageAttributes.SetColorMatrix( new ColorMatrix( new float[][] {
 new float[] {0, 0, 0, 0, 0},
 new float[] {0, 0, 0, 0, 0},
 new float[] {0, 0, 0, 0, 0},
 new float[] {0, 0, 0, 1, 0},
 new float[] {r, g, b, 0, 1}} ) );

where r, g, b are between 0 and 1, like so:

float r = DesiredColor.R / 255f;
float g = DesiredColor.G / 255f;
float B = DesiredColor.B / 255f;

I don't understand what you mean by "it would be a plus if there can be a threshold value for the transparency", though... so maybe this isn't the answer you were looking for?

danbystrom
That's not quite it. The transformation needs to honor the source alpha only in terms of visible/invisible (not by maintaining it). Therefore, a threshold value indicates the visiblity limit (i.e alpha>=20 ? visible : invisible). All visible pixels should be painted using a uniform color, and all invisible ones should not be painted at all. The uniform color should be ARGB (and not only RGB), and should be accurate (I am not sure how well can floats hold 1/255's)
sold
Ah, I thought I missed something! Well, I'd definately create a new image by scanning pixel-by-pixel. At least it would be much faster than an ImageAttribute solution.
danbystrom
A: 

I have to draw an image with a per pixel alpha mask and found the best way was to just draw the base RGB image then draw the opaque parts of the alpha mask over the top. You need to map each alpha level to an alpha level + colour to get the image to honour every detail in the alpha mask. The code I've got has the alpha mask as a seperate 8bit image but the draw code looks like this:

g.DrawImage(&picture, r.left, r.top, r.Width(), r.Height()); // base image   

if ( AlphaBuf != NULL ) // do we have and alpha mask?
{
Gdiplus::Bitmap mask(Width, Height, Width(), PixelFormat8bppIndexed, AlphaBuf);
picture.GetPalette( palette, picture.GetPaletteSize() );
    // invert - only shows the transparent  
palette->Entries[0] = DLIMAKEARGB(255, 0, 0, 200); // 0 = fully transparent
palette->Entries[255] = DLIMAKEARGB(0, 0, 0, 0); // 255 = fully opaque 

mask.SetPalette(palette);
g.DrawImage(&mask, r.left, r.top, r.Width(), r.Height()); // draw the mask 
}

My alpha masks are only full transparent or full opaque but I would think that setting the other alpha values in the pallette would let you follow a more graduated mask.

palette->Entries[1] = DLIMAKEARGB(254, 0, 0, 200);
palette->Entries[2] = DLIMAKEARGB(253, 0, 0, 200);
etc..

Hope this helps (or at least makes sense :-p )

Dave Lindsay