Can't create an 4bpp Bitmap (A generic error occurred in GDI+.)

N

news.microsoft.com

Hi guys,



This text looks long and complicate but it is not, and I really really need
some help here.



For the last 24hs I'm trying to resolve this issue (last night I dreamed
about it) and I can't see what is the problem.



I have to 2 Bitmaps coming from an Icon. One is the image itself or XORBmp
and one is the Mask or ANDBmp, I just want to produce a third image
combining both, but the result image MUST be the same format as the original
XORBmp. (if source is 4bpp then destination must be 4bpp)



The following code works, but the result always is a 32bpp image. (Same as
my DISPLAY color depth)



IntPtr hDCScreen = GetDC(IntPtr.Zero);



Bitmap XORBmp = srcBitmap; //<= 1, 4, 8, 24 bpp usually is 4bpp

IntPtr hBitmapXORBmp = XORBmp.GetHbitmap();

IntPtr hDCScreenXORBmp = CreateCompatibleDC(hDCScreen);

SelectObject(hDCScreenXORBmp, hBitmapXORBmp);



int format1 = GetDeviceCaps(hDCScreenXORBmp, GetDeviceCapsFlag.BITSPIXEL);
// Gives that the HDC is 32 bpp



Bitmap ANDBmp = mskBitmap; // <= 1bpp B&W Image or Mask

IntPtr hBitmapANDBmp = ANDBmp.GetHbitmap();

IntPtr hDCScreenANDBmp = CreateCompatibleDC(hDCScreen);

SelectObject(hDCScreenANDBmp, hBitmapANDBmp);



IntPtr hDCScreenOUTBmp = CreateCompatibleDC(hDCScreen);

//IntPtr hBitmapOUTBmp = CreateBitmap(XORBmp.Width, XORBmp.Height, 1,
BitsFromPixelFormat(XORBmp.PixelFormat), IntPtr.Zero);

IntPtr hBitmapOUTBmp = CreateCompatibleBitmap(hDCScreenOUTBmp,
XORBmp.Width, XORBmp.Height); // Creates a 32bpp becuase of
hDCScreenOUTBmp... not good

SelectObject(hDCScreenOUTBmp, hBitmapOUTBmp);



int format2 = GetDeviceCaps(hDCScreenOUTBmp, GetDeviceCapsFlag.BITSPIXEL);
// Gives again that the HDC is 32 bpp



bool r1 = BitBlt(hDCScreenOUTBmp, 0, 0, XORBmp.Width, XORBmp.Height,
IntPtr.Zero, 0, 0, PatBltTypes.WHITENESS);

bool r2 = BitBlt(hDCScreenOUTBmp, 0, 0, XORBmp.Width, XORBmp.Height,
hDCScreenANDBmp, 0, 0, PatBltTypes.SRCAND);

bool r3 = BitBlt(hDCScreenOUTBmp, 0, 0, XORBmp.Width, XORBmp.Height,
hDCScreenXORBmp, 0, 0, PatBltTypes.SRCPAINT);



Bitmap OutputBmp = Bitmap.FromHbitmap(hBitmapOUTBmp);

....

....



It is because the following line is creating the output image as 32bpp
(32bpp because is using the HDC created from my DISPLAY).



IntPtr hBitmapOUTBmp = CreateCompatibleBitmap(hDCScreenOUTBmp,
XORBmp.Width, XORBmp.Height);



So. If I replace that line by:



IntPtr hBitmapOUTBmp = CreateBitmap(XORBmp.Width, XORBmp.Height, 1,
BitsFromPixelFormat(XORBmp.PixelFormat), IntPtr.Zero);



I got what I want.. (BitsFromPixelFormat the only thing it does is return
the number of bits from the PixelFormat enum)



But now the following line crash



Bitmap OutputBmp = Bitmap.FromHbitmap(hBitmapOUTBmp);



Keeps giving "A generic error occurred in GDI+.".



QUESTION 1: So, why it fails, or how can I create the output .net Bitmap
with the same format as the incoming bitmap.



Please if you know what is wrong let me know, this is killing me.








What I suspect is that the next:



The MSDN help tell very clear this:



(CreateBitmap)

"After a bitmap is created, it can be selected into a device context by
calling the SelectObject function. HOWEVER, the bitmap can only be selected
into a device context if the bitmap and the DC have the same format.



QUESTION 2: Now how I'm supposed to create a Memory DC with the same format
as the output bitmap?????

My incoming bitmap is 4bpp and I have NO WAY to create a Memory DC other
than use the function CreateCompatibleDC(HDC.) where I have to put the
DISPLAY HDC. so the result HDC ALWAYS will be the same as the DISPLAY 16 or
32 bpp and not the format as the incoming bitmap "4bpp".



I tried to find the Whole internet how to create a Memory DC other than the
same as the DISPLAY color depth.. but no luck and no a single line how it
could be done.



If you think to use CreateDC.. I'm pretty sure that is not the way because
in the whole Google I can't find a single example how to use CreateDC with a
different DEVMode. So I'm assuming that not the right path at all.





Thanks,

Gustavo.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top