HighTechTalks DotNet Forums  

Combine a bitmap with a mask bitmap

Dotnet Framework (Drawing) microsoft.public.dotnet.framework.drawing


Discuss Combine a bitmap with a mask bitmap in the Dotnet Framework (Drawing) forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old   
Carlos Alloatti
 
Posts: n/a

Default Combine a bitmap with a mask bitmap - 11-21-2007 , 02:42 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

Reply With Quote
  #2  
Old   
Michael Phillips, Jr.
 
Posts: n/a

Default Re: Combine a bitmap with a mask bitmap - 11-21-2007 , 10:02 AM






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

How could I do this?
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!

"Carlos Alloatti" <calloatti (AT) gmail (DOT) com> wrote

Quote:
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



Reply With Quote
  #3  
Old   
Carlos Alloatti
 
Posts: n/a

Default Re: Combine a bitmap with a mask bitmap - 11-21-2007 , 10:25 AM



On Nov 21, 1:02 pm, "Michael Phillips, Jr."
<mphillip... (AT) nospam (DOT) jun0.c0m> wrote:
Quote:
BITMAP1: COLOR X + BITMAP2: BLACK = COLOR X
BITMAP1: COLOR X + BITMAP2: WHITE = WHITE

How could I do this?

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!

"Carlos Alloatti" <calloa... (AT) gmail (DOT) com> wrote in message

news:8321fbdf-295a-4f7b-8a65-3eedac462248 (AT) w34g2000hsg (DOT) googlegroups.com...

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
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


Reply With Quote
  #4  
Old   
Carlos Alloatti
 
Posts: n/a

Default Re: Combine a bitmap with a mask bitmap - 11-21-2007 , 10:31 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

Reply With Quote
  #5  
Old   
Carlos Alloatti
 
Posts: n/a

Default Re: Combine a bitmap with a mask bitmap - 11-21-2007 , 11:43 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


Reply With Quote
  #6  
Old   
Michael Phillips, Jr.
 
Posts: n/a

Default Re: Combine a bitmap with a mask bitmap - 11-21-2007 , 12:04 PM



Quote:
"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:"
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.

Quote:
... I tried doing what you
suggest, before reading your post, but that is terribly slow in VFP.
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.


"Carlos Alloatti" <calloatti (AT) gmail (DOT) com> wrote

Quote:
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



Reply With Quote
  #7  
Old   
Carlos Alloatti
 
Posts: n/a

Default Re: Combine a bitmap with a mask bitmap - 11-22-2007 , 05:35 PM



MIchael, thank you for your comments.

Quote:
Perhaps, I misunderstood your post.

I thought that you were working with 24bpp bitmaps.

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


Quote:
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.

... I tried doing what you
suggest, before reading your post, but that is terribly slow in VFP.

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.
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.

Quote:
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.
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.
Quote:
Thanks again,

Carlos Alloatti


Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.