This topic is now archived and is closed to further replies.


This topic is 5679 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys! I made a function to load Bitmaps by hand that stores the bitmap as a single array of data where each 3 bytes represent a single pixel. Now, I want to show it on the screen (by GDI calls), but I''m not getting good results... I know how to paint BITMAP RESOURCES, but didn''t figured out how to transform the data I read from the bitmap file, to a HBITMAP instance. I tryied CreateBitmap(), but it didn''t work. So, How Am''I going to do? Fernando

Share this post

Link to post
Share on other sites
Basically it''s something like this:

HBITMAP CreateBitmapFromBits(WORD wWidth, WORD wHeight, LPBYTE lpBits)
// access display DC and create compatible bitmap

HDC hScreen = GetDC(NULL);
HBITMAP hBmp = CreateCompatibleBitmap(hScreen, wWidth, wHeight);

// prepare bitmap info struct

BITMAPINFO bmi = {0};
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
bmi.bmiHeader.biWidth = wWidth;
bmi.bmiHeader.biHeight = wHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_RGB;

// assign bits and header to bitmap

SetDIBits(hScreen, hBmp, 0, wHeight, lpBits, &bmi, DIB_RGB_COLORS);

// release DC

::ReleaseDC(NULL, hScreen);


Two important things need to be mentioned though:
1. Windows Bitmaps are bottom-up, not top-down. So if your bitmap is displayed flipped you should set
bmi.bmiHeader.biHeight = -wHeight;
to turn it upside-down.

2. The scanlines in a HBITMAP are DWORD-aligned (i.e. aligned on a 32-bit boundary), so the code above will only work properly if the width is a multiple of 4.

Share this post

Link to post
Share on other sites
Christian's suggestion is a very good one. However, if you can't pull that one off, there's another method: make a blank HDC and a blank HBITMAP, select the HBITMAP into the HDC, and then use a jillion calls to SetPixel() to put the pixels from the array onto the HDC. Then BitBlt() from the HDC to wherever else you need the image. This method is extremely slow, but once you have the HDC filled you can do whatever you want at (relatively) high speed with BitBlt()s. Here's the code:

HDC hdcImage, hdcWin;
HBITMAP hbmImage;
int i, j;
//somehow obtain a useful DC, perhaps from your window using
//GetDC, like so:
hdcWin = GetDC(hwnd);
hdcImage = CreateCompatibleDC(hdcWin);
hbmImage = CreateCompatibleBitmap(hdcImage, imgWidth, imgHeight);
for(i = 0; i < imgHeight; i++)
for(j = 0; j < imgWidth; j++)
j, i,
RGB(bmpdata[(i*imgWidth+j)*3], bmpdata[(i*imgWidth+j)*3+1], bmpdata[(i*imgWidth+j)*3+2]));

That puts your image on the HDC.

Twilight Dragon
Win32 API Expert

[edited by - TDragon on June 29, 2002 6:57:44 PM]

Share this post

Link to post
Share on other sites
Hi guys, I don't know what is happening. I'm using SetDIBits to show the pictures, but they appear in BLACK & WHITE colors.

Do you know what is wrong? I'll post some code:

BeginPaint(hWnd, &ps);

   hdc = CreateCompatibleDC(ps.hdc);
   bitmap = CreateCompatibleBitmap(hdc, fi.width, fi.height);

   bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
   bi.bmiHeader.biWidth = fi.width;
   bi.bmiHeader.biHeight = fi.height;
   bi.bmiHeader.biPlanes = 1;
   bi.bmiHeader.biBitCount = 24;
   bi.bmiHeader.biCompression = BI_RGB;

   SetDIBits(hdc, bitmap, 0, fi.height,, &bi, DIB_RGB_COLORS);

   bit = SelectObject(hdc, bitmap);

   BitBlt(ps.hdc, 10, 10, fi.width, fi.height, hdc, 0, 0, SRCCOPY);


EndPaint(hWnd, &ps);

where FI is a variable storing the bitmap information.

[edited by - FERNANDO-BRASIL on July 1, 2002 9:08:51 AM]

Share this post

Link to post
Share on other sites