Groups | Blog | Home
all groups > dotnet drawing api > november 2007 >

dotnet drawing api : Combine a bitmap with a mask bitmap


Carlos Alloatti
11/21/2007 12:42:59 AM
I need to combine two 24bpp bitmaps. The mask bitmap only has two
values for its pixels: black or white. The combined resulting bitmap
should be:

BITMAP1: COLOR X + BITMAP2: BLACK = COLOR X
BITMAP1: COLOR X + BITMAP2: WHITE = WHITE

How could I do this?

Carlos Alloatti
11/21/2007 8:25:52 AM
On Nov 21, 1:02 pm, "Michael Phillips, Jr."
[quoted text, click to view]

Michael, thank you for your answer. The problem is that I am using a
ported version of the NET classes in VFP. I tried doing what you
suggest, before reading your post, but that is terribly slow in VFP.

I came up with an alternative, but does not work as I expect.

I want to try to draw the original image to a bitmap, then in the mask
image do a RemapTable of Black to Trasparent, and draw that on top of
the former.

My asumption is that will result in what I want. Now the problem is
that I cant change black to transparent! I do a test:

(Syntax is VFP, but readable)

m.loMask1 = .Bitmap.New(m.lcFileName)
m.loMask2 = .Bitmap.New(m.loMask1.Width, m.loMask1.Height,
0, .Imaging.PixelFormat.Format32bppRGB)

m.loGraphics = .Graphics.FromImage(m.loMask2)
m.loGraphics.Clear(.Color.Transparent)

m.loColorMap = .Imaging.ColorMap.New()
m.loAttributes = .Imaging.ImageAttributes.New()

m.loColorMap.OldColor = .Color.Black
m.loColorMap.NewColor = .Color.Transparent

m.loAttributes.SetRemapTable(m.loColorMap)

m.loGraphics.DrawImage(m.loMask1, m.loRect,
m.loRect, .GraphicsUnit.Pixel, m.loAttributes)

With that code, nothing happens, I just get the same image again, so I
did some tests, using for example:

m.loColorMap.OldColor = .Color.Black
m.loColorMap.NewColor = .Color.Transparent

Gives me what I expect, Black pixels turn to Magenta. Now doing for
example:

m.loColorMap.OldColor = .Color.FromArgb(255,0,0,0)
m.loColorMap.NewColor = .Color.FromArgb(128,255,0,255)

Does not turn Black pixels to ARGB(128,255,0,255) but to
ARGB(255,128,0,128) !!

It seems the Alpha value is premultipled and applied to the RGB
values.

Is that the standard behaviour in .NET or should I be getting
ARGB(128,255,0,255)?

Thank you very much for your time and patience.

Carlos Alloatti
11/21/2007 8:31:06 AM
Sorry in the previous post,

"With that code, nothing happens, I just get the same image again, so
I
did some tests, using for example:

m.loColorMap.OldColor = .Color.Black
m.loColorMap.NewColor = .Color.Transparent

Gives me what I expect, Black pixels turn to Magenta. Now doing for
example:"

Should be:

"With that code, nothing happens, I just get the same image again, so
I
did some tests, using for example:

m.loColorMap.OldColor = .Color.Black
m.loColorMap.NewColor = .Color.MAGENTA

Gives me what I expect, Black pixels turn to Magenta. Now doing for
example:"

Carlos Alloatti
11/21/2007 9:43:11 AM
I discovered "MakeTransparent" ...

So the solution I found to:

BITMAP1: COLOR X + BITMAP2: BLACK = COLOR X
BITMAP1: COLOR X + BITMAP2: WHITE = WHITE

Use MakeTransparent in BITMAP2 to set black to transparent

Create a new BITMAP3

Draw BITMAP1 into BITMAP3

Draw modified BITMAP2 into BITMAP3

So the ten lines of code of the previous post using SetRemapTable,
that did NOT work, was replaced by:

m.loMask1.MakeTransparent(.Color.Black)

Anyway, comments on the SetRemapTable behaviour of the previous post?

PS: Is the a proper group for this postings? seems like there is low
activity here. Any recomendations?

Carlos Alloatti
Michael Phillips, Jr.
11/21/2007 11:02:28 AM
[quoted text, click to view]

1) Create a new destination 24bpp bitmap and use Graphics.DrawImage to copy
the source bitmap to the destination.
2) Use LockBits with read/write access in a loop to cycle through all of the
destination pixels.
And cycle through all of the mask pixels in the same loop.
The mask bitmap should be locked with read access only.
2) Test the mask pixel's color. If black, do nothing to the destination's
pixel.
If the mask color is white, then change the color of the destination
pixel to white.
3) Unlock both bitmaps, save the new destination bitmap and your done!

[quoted text, click to view]

Michael Phillips, Jr.
11/21/2007 1:04:58 PM
[quoted text, click to view]

Perhaps, I misunderstood your post.

I thought that you were working with 24bpp bitmaps.

If so, then there is no alpha component to the color remapping.

For 32bpp alpha channeled bitmaps, the alpha component is premultiplied for
performance
and/or because a particular graphic's operation may require that the alpha
channel be premultiplied to work correctly.

If you wish to promote your 24bpp bitmap to 32bpp ARGB, then you could try
remapping the transparent color with SetColorKey.

This is what I use. It is very convenient to specify a range representing a
min and max key color and remap to a transparent color with one method call.

[quoted text, click to view]

Lockbits is slow for Read/Write access because a temporary buffer is created
and then written back when unlocked.
Performance is predicated on how fast your system Marshals between managed
and unmanaged code.

For Read access only on the mask bitmap, the speed will should be fast as no
temporary buffer is created.

To speed things up, you could try to use GDI ROP with P-Invoke.

Using BitBlt with SRCAND will allow you to punch out your source image with
the AND operation. This is very fast, and you may use a monochrome bitmap
with two colors instead of a 24bpp bitmap with two colors.

If you load and create your color bitmap as a DIB then you have direct
access to the memory. Cycling through and remapping the rest of the pixels
will be very fast.

I have not used VFP so I do not know if P-Invoke is possible.


[quoted text, click to view]

Carlos Alloatti
11/22/2007 3:35:46 PM
MIchael, thank you for your comments.

[quoted text, click to view]

You did not, I am drawing to a 32bppARGB bitmap from two 24bppRGB
bitmaps


[quoted text, click to view]

It is not Lockbits that is slow, is processing the bits in VFP tha is
slow, in fact I use Lockbits to replace the entire pixel data of a
bitmap wtih another set of data, without any further procesing, and
there is no delay.

[quoted text, click to view]

I don't think so, I more or less understand you concepts, but no
knowledge of implementing in VFP, but I managed to solve it and it is
fast.
[quoted text, click to view]
Thanks again,

AddThis Social Bookmark Button