Thread: RE: [GD-Windows] In memory bitmap to HBITMAP
Brought to you by:
vexxed72
From: Andrew G. <And...@ho...> - 2001-12-07 09:57:43
|
I've had this before, I can't remember what caused it but it turned out to be a "duh" error on my part. Code Guru (www.codeguru) is a great site for all sorts of GDI programming trickery. It's MFC based but the techniques are sound and it's not a great deal of pain to implment any of the samples in Win32. In this case http://www.codeguru.com/bitmap/bitmap_from_bmp.shtml. On another note, have you thought about using LoadImage() instead rather than doing it manually? Andrew Grant Hothouse Creations > -----Original Message----- > From: Brian Hook [mailto:bri...@py...] > Sent: 07 December 2001 02:04 > To: gam...@li... > Subject: [GD-Windows] In memory bitmap to HBITMAP > > > I'm struggling with something fairly basic -- I want to load a BMP out > of a compressed file, convert to an HBITMAP, then blit it into a DDraw > surface. I know how to do the first and last part, but the middle is > causing problems. Even worse, I'm not getting any errors. > > Loading the bitmap doesn't seem to be a problem. I load it > up and parse > and find the BITMAPFILEHEADER and BITMAPINFOHEADER no probs. I also > locate the raw bits no problem (and inspect with the debugger to make > sure I'm getting what I think I'm getting -- in this case, solid > magenta). Looks fine. > > The next step is to create a DC compatible with the desktop: > > HDC hDC = CreateCompatibleDC( NULL ); > > I then create a HBITMAP compatible with DC, and using the > bits I pulled: > > HBITMAP hbm; > > hbm = CreateDIBitmap( hDC, lpBMIH, CBM_INIT, lpBits, lpBMIH, > DIB_RGB_COLORS ); > > lpBMIH are simply pointers to the appropriate BITMAPINFOHEADER. They > have correct values in them. The bitmap is returned successfully. > > To verify things, I grab the bits out of the Bitmap to make sure > everything is cool: > > GetDIBits( hDC, hbm, 0, iHeight, tempbuffer, &bmi, DIB_RGB_COLORS ); > > It returns the correct number of scan lines, but tempbuffer is filled > with black. This means either the CreateDIBitmap() filled in > the bitmap > with black, or the GetDIBits() failed somehow. I can't > figure out which > is the real culprit, but the bitmap is pretty much a black square. > > Any suggestions on how to hunt this down? > > > This email is covered by the following disclaimer, please read before accepting this email. http://www.hothouse.org/disclaimer/ |
From: Andrew G. <And...@ho...> - 2001-12-07 10:40:47
|
Ahh, remembered what the problem was :) CreateCompatibleDC creates a memory DC. By default memory DC's have a 1x1 monochrome surface so when you call CreateDIBitmap you are creating a bitmap which is the same type as that DC, e.g monochrome. Try passing in the DC of your window instead to CreateDIBitmap. To explain further; (stuff you may/may not know) In Windows DCs are your interface for drawing to the object they contain. Screens, Bitmaps and so on. When you call CreateCompatibleDC you are returned a compatible but empty DC (well, 1x1 b/w) that you can then use to draw to. Compatible doesn't mean format-wise (after all you can BitBlt between DCs of different colour depths), it means compatible in some device way, in this case compatible with the screen. However until you place something into that DC then you are using the default 1x1 monochrome surface. For instance if you wanted to draw text to a HBITMAP using GDI you put that hbmp into the DC first so you are using that. Something like... // create a dc HDC hdc = CreateCompatibleDC(); // select the bitmap into the dc HGDIOBJ hOld = SelectObject(hdc, hbmp); // draw your text DrawText(hdc, "blah blah", ...); // remove the hbmp from the dc SelectObject(hdc, hOld); // delete the dc DeleteDC(hdc); Another example. To solve your problem you could do HDC hdc = CreateCompatibleDC(); // create a memory DC HBITMAP = CreateBitmapIndirect(); // creates an empty bitmap of the specified dimensions and depth // select the new bmp into the DC HGDIOBJ hOld = SelectObject(hdc, hbmp); CreateDIBitmap(hdc, ...); Now at this point you have loaded your new bitmap with the same color depth as the bitmap you created with CreateBitmapIndirect(), because that was format of the bitmap in the DC you used with CreateDIBitmap, not the default 1x1 monochrome one. Of course this isn't always good method because you are allocating extra resources with CreateBitmapIndirect, however this technique is useful for the case where the users desktop is running in 16-bit color and you want to work with 24-bit images. It's good to think of a DC as an interface you use to draw on something. In the case of WM_PAINT that 'something' is the screen, in the case of memory DCs it is the bitmap you place in them with SelectObject. Hope this helps somewhat. Andrew Grant Hothouse Creations > -----Original Message----- > From: Andrew Grant [mailto:And...@ho...] > Sent: 07 December 2001 09:57 > To: gam...@li... > Subject: RE: [GD-Windows] In memory bitmap to HBITMAP > > > I've had this before, I can't remember what caused it but it > turned out to > be a "duh" error on my part. Code Guru (www.codeguru) is a > great site for > all sorts of GDI programming trickery. It's MFC based but the > techniques are > sound and it's not a great deal of pain to implment any of > the samples in > Win32. In this case > http://www.codeguru.com/bitmap/bitmap_from_bmp.shtml. > > On another note, have you thought about using LoadImage() > instead rather > than doing it manually? > > Andrew Grant > Hothouse Creations > > > > > -----Original Message----- > > From: Brian Hook [mailto:bri...@py...] > > Sent: 07 December 2001 02:04 > > To: gam...@li... > > Subject: [GD-Windows] In memory bitmap to HBITMAP > > > > > > I'm struggling with something fairly basic -- I want to > load a BMP out > > of a compressed file, convert to an HBITMAP, then blit it > into a DDraw > > surface. I know how to do the first and last part, but the > middle is > > causing problems. Even worse, I'm not getting any errors. > > > > Loading the bitmap doesn't seem to be a problem. I load it > > up and parse > > and find the BITMAPFILEHEADER and BITMAPINFOHEADER no probs. I also > > locate the raw bits no problem (and inspect with the > debugger to make > > sure I'm getting what I think I'm getting -- in this case, solid > > magenta). Looks fine. > > > > The next step is to create a DC compatible with the desktop: > > > > HDC hDC = CreateCompatibleDC( NULL ); > > > > I then create a HBITMAP compatible with DC, and using the > > bits I pulled: > > > > HBITMAP hbm; > > > > hbm = CreateDIBitmap( hDC, lpBMIH, CBM_INIT, lpBits, lpBMIH, > > DIB_RGB_COLORS ); > > > > lpBMIH are simply pointers to the appropriate > BITMAPINFOHEADER. They > > have correct values in them. The bitmap is returned successfully. > > > > To verify things, I grab the bits out of the Bitmap to make sure > > everything is cool: > > > > GetDIBits( hDC, hbm, 0, iHeight, tempbuffer, &bmi, DIB_RGB_COLORS ); > > > > It returns the correct number of scan lines, but tempbuffer > is filled > > with black. This means either the CreateDIBitmap() filled in > > the bitmap > > with black, or the GetDIBits() failed somehow. I can't > > figure out which > > is the real culprit, but the bitmap is pretty much a black square. > > > > Any suggestions on how to hunt this down? > > > > > > > > > This email is covered by the following disclaimer, please read before > accepting this email. http://www.hothouse.org/disclaimer/ > > _______________________________________________ > Gamedevlists-windows mailing list > Gam...@li... > https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows > This email is covered by the following disclaimer, please read before accepting this email. http://www.hothouse.org/disclaimer/ |
From: Brian H. <bri...@py...> - 2001-12-07 16:05:57
|
At 10:40 AM 12/7/2001 +0000, Andrew Grant wrote: >CreateCompatibleDC creates a memory DC. By default memory DC's have a 1x1 >monochrome surface so when you call CreateDIBitmap you are creating a bitmap >which is the same type as that DC, e.g monochrome. Try passing in the DC of >your window instead to CreateDIBitmap. Someone else mentioned this to me off-list, and I felt stupid because the help says this. But I don't feel THAT stupid because, well, look at the name of the function and I was passing in "NULL", which means (to me) "Create a DC compatible with the screen". And I'm not running in monochrome, thank you =) But as you say, DC compatibility doesn't mean color depth compatibility, it means "device characteristic" compatibility. So, yeah, I guess it was a stupid newbie error =) I'll give the various suggestions a shot today, thanks! Brian |
From: Andrew G. <And...@ho...> - 2001-12-07 10:51:18
|
To avoid confusion, I should also mention that Jon Watte's example works regardless of what is in the memory DC because he is using CreateDIBSection, not CreateDIBitmap. CreateDIBSection = device independent bitmap CreateDIBitmap = device dependent bitmap. (Why it's not CreateDDBitmap or something sensible I don't know). Device dependent bitmaps give better GDI performance because they are in some device-friendly format. Andrew Grant Hothouse Creations > -----Original Message----- > From: Andrew Grant [mailto:And...@ho...] > Sent: 07 December 2001 10:41 > To: gam...@li... > Subject: RE: [GD-Windows] In memory bitmap to HBITMAP > > > Ahh, remembered what the problem was :) > > CreateCompatibleDC creates a memory DC. By default memory > DC's have a 1x1 > monochrome surface so when you call CreateDIBitmap you are > creating a bitmap > which is the same type as that DC, e.g monochrome. Try > passing in the DC of > your window instead to CreateDIBitmap. > > > To explain further; (stuff you may/may not know) > > In Windows DCs are your interface for drawing to the object > they contain. > Screens, Bitmaps and so on. When you call CreateCompatibleDC you are > returned a compatible but empty DC (well, 1x1 b/w) that you > can then use to > draw to. Compatible doesn't mean format-wise (after all you can BitBlt > between DCs of different colour depths), it means compatible > in some device > way, in this case compatible with the screen. However until you place > something into that DC then you are using the default 1x1 monochrome > surface. > > For instance if you wanted to draw text to a HBITMAP using > GDI you put that > hbmp into the DC first so you are using that. Something like... > > // create a dc > HDC hdc = CreateCompatibleDC(); > > // select the bitmap into the dc > HGDIOBJ hOld = SelectObject(hdc, hbmp); > > // draw your text > DrawText(hdc, "blah blah", ...); > > // remove the hbmp from the dc > SelectObject(hdc, hOld); > > // delete the dc > DeleteDC(hdc); > > > > Another example. To solve your problem you could do > > HDC hdc = CreateCompatibleDC(); // > create a memory DC > > HBITMAP = CreateBitmapIndirect(); // > creates an empty > bitmap of the specified dimensions and depth > > // select the new bmp into the DC > HGDIOBJ hOld = SelectObject(hdc, hbmp); > > CreateDIBitmap(hdc, ...); > > Now at this point you have loaded your new bitmap with the > same color depth > as the bitmap you created with CreateBitmapIndirect(), > because that was > format of the bitmap in the DC you used with CreateDIBitmap, > not the default > 1x1 monochrome one. Of course this isn't always good method > because you are > allocating extra resources with CreateBitmapIndirect, however > this technique > is useful for the case where the users desktop is running in > 16-bit color > and you want to work with 24-bit images. > > It's good to think of a DC as an interface you use to draw on > something. In > the case of WM_PAINT that 'something' is the screen, in the > case of memory > DCs it is the bitmap you place in them with SelectObject. > > > Hope this helps somewhat. > > > Andrew Grant > Hothouse Creations > > > > > -----Original Message----- > > From: Andrew Grant [mailto:And...@ho...] > > Sent: 07 December 2001 09:57 > > To: gam...@li... > > Subject: RE: [GD-Windows] In memory bitmap to HBITMAP > > > > > > I've had this before, I can't remember what caused it but it > > turned out to > > be a "duh" error on my part. Code Guru (www.codeguru) is a > > great site for > > all sorts of GDI programming trickery. It's MFC based but the > > techniques are > > sound and it's not a great deal of pain to implment any of > > the samples in > > Win32. In this case > > http://www.codeguru.com/bitmap/bitmap_from_bmp.shtml. > > > > On another note, have you thought about using LoadImage() > > instead rather > > than doing it manually? > > > > Andrew Grant > > Hothouse Creations > > > > > > > > > -----Original Message----- > > > From: Brian Hook [mailto:bri...@py...] > > > Sent: 07 December 2001 02:04 > > > To: gam...@li... > > > Subject: [GD-Windows] In memory bitmap to HBITMAP > > > > > > > > > I'm struggling with something fairly basic -- I want to > > load a BMP out > > > of a compressed file, convert to an HBITMAP, then blit it > > into a DDraw > > > surface. I know how to do the first and last part, but the > > middle is > > > causing problems. Even worse, I'm not getting any errors. > > > > > > Loading the bitmap doesn't seem to be a problem. I load it > > > up and parse > > > and find the BITMAPFILEHEADER and BITMAPINFOHEADER no > probs. I also > > > locate the raw bits no problem (and inspect with the > > debugger to make > > > sure I'm getting what I think I'm getting -- in this case, solid > > > magenta). Looks fine. > > > > > > The next step is to create a DC compatible with the desktop: > > > > > > HDC hDC = CreateCompatibleDC( NULL ); > > > > > > I then create a HBITMAP compatible with DC, and using the > > > bits I pulled: > > > > > > HBITMAP hbm; > > > > > > hbm = CreateDIBitmap( hDC, lpBMIH, CBM_INIT, lpBits, lpBMIH, > > > DIB_RGB_COLORS ); > > > > > > lpBMIH are simply pointers to the appropriate > > BITMAPINFOHEADER. They > > > have correct values in them. The bitmap is returned successfully. > > > > > > To verify things, I grab the bits out of the Bitmap to make sure > > > everything is cool: > > > > > > GetDIBits( hDC, hbm, 0, iHeight, tempbuffer, &bmi, > DIB_RGB_COLORS ); > > > > > > It returns the correct number of scan lines, but tempbuffer > > is filled > > > with black. This means either the CreateDIBitmap() filled in > > > the bitmap > > > with black, or the GetDIBits() failed somehow. I can't > > > figure out which > > > is the real culprit, but the bitmap is pretty much a black square. > > > > > > Any suggestions on how to hunt this down? > > > > > > > > > > > > > > > This email is covered by the following disclaimer, please > read before > > accepting this email. http://www.hothouse.org/disclaimer/ > > > > _______________________________________________ > > Gamedevlists-windows mailing list > > Gam...@li... > > https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows > > > > > This email is covered by the following disclaimer, please read before > accepting this email. http://www.hothouse.org/disclaimer/ > > _______________________________________________ > Gamedevlists-windows mailing list > Gam...@li... > https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows > This email is covered by the following disclaimer, please read before accepting this email. http://www.hothouse.org/disclaimer/ |