I suspect this is a trivial problem to solve but it's driving me nuts.
I have functioning code that uses LoadBitmapFromBMPFile() which I lifted from Microsoft's web site to load a bitmap and display it so:
Code:
HBITMAP hOldBitmap, hBitmap;
HPALETTE hOldPalette, hPalette;
HDC hDC, hMemDC;
BITMAP bm;
[...]
LoadBitmapFromBMPFile( L"somefile.bmp", &hBitmap, &hPalette );
GetObject( hBitmap, sizeof(BITMAP), &bm );
hMemDC = CreateCompatibleDC( hDC );
hOldBitmap = (HBITMAP)SelectObject( hMemDC, hBitmap );
hOldPalette = SelectPalette( hDC, hPalette, FALSE );
RealizePalette( hDC );
BitBlt( hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY );
No problem.
At a later point, I have a raw image in memory. RGB format, 8 bits per pixel. I want to BitBlt() this onto the display, same as above.
I have functioning code that takes that image in memory, writes it to a file in BMP format, and then calls LoadBitmapFromBMPFile() as above ... but this is silly. I ought to be able to skip the file writing and reading.
LoadBitmapFromBMPFile() starts off so:
Code:
BOOL LoadBitmapFromBMPFile( LPTSTR szFileName, HBITMAP *phBitmap,
HPALETTE *phPalette )
{
BITMAP bm;
*phBitmap = NULL;
*phPalette = NULL;
// Use LoadImage() to get the image loaded into a DIBSection
*phBitmap = (HBITMAP)LoadImage( NULL, szFileName, IMAGE_BITMAP, 0, 0,
LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
Surely there's some analogue to LoadImage() that, instead of taking a filename as a parameter, can accept a pointer to the already-in-memory RGB image data?
If there is, I haven't found it.
Google has suggested I use CreateDIBSection(). This represents my non-successful attempt:
Code:
unsigned char *display_image_data; // image data in 8 bpp RGB format
[...]
BITMAPINFO pbmi;
pbmi.bmiheader.biSize = sizeof(BITMAPINFO);
pbmi.bmiheader.biWidth = DISPLAY_X; // img width in pixels
pbmi.bmiheader.biHeight = DISPLAY_Y; // img height in pixels
pbmi.bmiheader.biPlanes = 1;
pbmi.bmiheader.biBitCount = 24; // also tried 8 here
pbmi.bmiheader.biCompression = BI_RGB;
pbmi.bmiheader.biSizeImage = 0; // docs say 0 if BI_RGB is used
pbmi.bmiheader.biXPelPerMeter = 0; // no idea what to do with this
pbmi.bmiheader.biYPelPerMeter = 0; // or this
pbmi.bmiheader.biClrUsed = 0;
pbmi.bmiheader.biClrImportant = 0;
// pbmi.bmiColors shouldn't need for RGB
hBitmap = CreateDIBSection( hDC, &pbmi, DIB_RGB_COLORS, (void **)display_image_data, NULL, 0 );
GetObject( hBitmap, sizeof(BITMAP), &bm );
hMemDC = CreateCompatibleDC( hDC );
hOldBitmap = (HBITMAP)SelectObject( hMemDC, hBitmap );
hOldPalette = SelectPalette( hDC, hPalette, FALSE );
RealizePalette( hDC );
BitBlt( hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY );
And what I get is a big black rectangle painted to the screen.
I would appreciate some tips here ... thank you.