-
November 19th, 2010, 07:41 AM
#1
Create compatible bitmap
Hi,
I can't seem to properly create a compatible bitmap in my MFC application. I'm trying to StretchBlt a byte buffer (with 8-bit greyscale pixel information) to a DC, but the only way to get it done is by taking a rather unconventional detour. Here's what I do:
Code:
HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, "bitmap.bmp", IMAGE_BITMAP,
0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
CBitmap cBmp;
cBmp.Attach(hBmp);
cBmp.SetBitmapBits(m_width*m_height, datap);
CDC dcMem;
dcMem.CreateCompatibleDC(dc);
HBITMAP BitmapOld = (HBITMAP)SelectObject(dcMem, cBmp);
dc->StretchBlt(xOffset, yOffset, m_width*rectSizeX, m_height*rectSizeY, &dcMem, 0, 0, m_width, m_height, SRCCOPY);
dcMem.SelectObject(BitmapOld);
dcMem.DeleteDC();
The file bitmap.bmp contains an uncompressed 8-bit greyscale image with exactly the same dimension of m_width*m_height. So far only by loading this one file first, attaching it to CBitmap cBmp and then calling SetBitmapBits with the pointer to my own byte buffer (datap), thus overwriting the bitmap information from the file, I can create a compatible bitmap out of my byte buffer that I can blit into the window. If I go like this
Code:
BITMAPINFO *lpInfo = new BITMAPINFO;
lpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpInfo->bmiHeader.biWidth = m_width;
lpInfo->bmiHeader.biHeight = m_height;
lpInfo->bmiHeader.biPlanes = 1;
lpInfo->bmiHeader.biBitCount = 8;
lpInfo->bmiHeader.biCompression = BI_RGB;
lpInfo->bmiHeader.biSizeImage = m_width*m_height;
lpInfo->bmiHeader.biClrUsed = 0;
HBITMAP hBmp = (HBITMAP)::CreateDIBSection(0, lpInfo, DIB_RGB_COLORS, 0, 0, 0x0);
... and then do the rest mentioned above (Attach(), CreateCompatibleDC(), SelectObject(), StretchBlt() etc.), I see only a greenish version of the image I want to blit (but in right aspect ratio, stride, dimension etc.), and it keeps appearing and disappearing with a blurry spot all the time.
What am I doing wrong?
Mac
-
November 19th, 2010, 10:22 AM
#2
Re: Create compatible bitmap
You are loading a DIB (device independent bitmap) then trying to blit it to a specific device (not independent). You need to first convert your DIB to a device dependent bitmap (DDB) that is compatible with the device you intend to use (your display in this case). You do this with the un-aptly named CreateDIBBitmap() using a DC compatible with your display. See:
http://www.codeguru.com/cpp/g-m/bitm...icle.php/c1681
-
November 22nd, 2010, 03:52 AM
#3
Re: Create compatible bitmap
Thanks for your response.
Uhm, well ... LOADING the bitmap (file) and then overwriting the file's data with my byte buffer very much DID work the way I described. But this is said detour I can't take in the final code. I tried using CreateDIBBitmap like you said.
Code:
BITMAPINFOHEADER bmih;
bmih.biSize = sizeof (BITMAPINFOHEADER);
bmih.biWidth = m_width;
bmih.biHeight = m_height;
bmih.biPlanes = 1;
bmih.biBitCount = 8;
bmih.biCompression = BI_RGB;
bmih.biSizeImage = m_width*m_height;
if (0 == m_pBitmapInfo)
{
m_pBitmapInfo = (BITMAPINFO *) (new BYTE[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)]);
}
m_pBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_pBitmapInfo->bmiHeader.biWidth = m_width;
m_pBitmapInfo->bmiHeader.biHeight = m_height;
m_pBitmapInfo->bmiHeader.biPlanes = 1;
m_pBitmapInfo->bmiHeader.biBitCount = 8;
m_pBitmapInfo->bmiHeader.biCompression = BI_RGB;
m_pBitmapInfo->bmiHeader.biSizeImage = m_width*m_height;
m_pBitmapInfo->bmiHeader.biClrUsed = 0;
if (0 != m_pBitmapInfo)
{
for (int n=0; n < 256; n++)
{
m_pBitmapInfo->bmiColors[n].rgbBlue=datap[n];
m_pBitmapInfo->bmiColors[n].rgbGreen=datap[n];
m_pBitmapInfo->bmiColors[n].rgbRed=datap[n];
m_pBitmapInfo->bmiColors[n].rgbReserved=0;
}
}
CDC dcMem_display;
dcMem_display.CreateCompatibleDC(dc);
HDC hdc = dcMem_display;
HBITMAP hBmp = (HBITMAP)::CreateDIBitmap(hdc, &bmih, CBM_INIT, datap, m_pBitmapInfo, DIB_RGB_COLORS);
HBITMAP BitmapOld = (HBITMAP)SelectObject(dcMem_display, hBmp);
dc->StretchBlt(xOffset, yOffset, m_width*rectSizeX, m_height*rectSizeY, &dcMem_display, 0, 0, m_width, m_height, SRCCOPY);
dcMem_display.SelectObject(BitmapOld);
dcMem_display.DeleteDC();
But all I get with this, is a solid black rectangle drawn into my window.
Mac
-
November 22nd, 2010, 09:33 AM
#4
Re: Create compatible bitmap
In this case, since you mentioned it's an 8-bit BMP, it appears that you are corrupting your bitmap by loading the pixel information into the color table area. An 8-bit BMP has a table of 256 DWORDS representing the colormap for this bitmap immediately following the header.
-
November 23rd, 2010, 07:40 AM
#5
Re: Create compatible bitmap
I got it!
Went back to CreateDIBSection() from my original post, but initialized bmiColors like this:
Code:
for (int n=0; n < 256; n++)
{
m_pBitmapInfo->bmiColors[n].rgbBlue=n;
m_pBitmapInfo->bmiColors[n].rgbGreen=n;
m_pBitmapInfo->bmiColors[n].rgbRed=n;
m_pBitmapInfo->bmiColors[n].rgbReserved=0;
}
Thanks for the advice!
Mac
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|