Sign in to follow this  
jackuess

24-bit bitmap only appears in gray scale

Recommended Posts

I have a 24 bit bitmap acquiered from a video capturing device (using the excelent library vidCapture [http://www.codevis.com/vidcapture/index.html]). I want to present this bitmap on the screen and have succeeded in doing so, with CreateBitmap and BitBlt, but it wount appear in colors, only in gray scale. My guess is that it has something to do with the fact that it is a 24 bit bitmap. First I tried setting the BitsPerPixel parameter in CreateBitmap to 24 but that didn't work at all. So I changed to 32 because I know that 24 bit bitmaps are realy stored in 32 bits. And then the picture was displayed, but as I've said: only in gray scale. Here's the code:
if(!CVFAILED(g_vidCap->Grab(CVImage::CVIMAGE_RGB24, imagePtr)))
	{
		HBITMAP Test;
		HDC DC;
		unsigned char *ptr;
		BITMAP bm;
		
		ptr = imagePtr->GetRawDataPtr();
		Test = (HBITMAP)CreateBitmap(240, 240, 1, 32, ptr);
		
		GetObject (Test, sizeof(BITMAP), &bm);
		DC = CreateCompatibleDC(hDC);
		SelectObject(DC, Test);

		BitBlt(hDC, 0, 0, bm.bmWidth, bm.bmHeight, DC, 0, 0, SRCCOPY);
		DeleteObject(Test);
	
		CVImage::ReleaseImage(imagePtr);
	}

[Edited by - jackuess on November 12, 2004 2:54:54 PM]

Share this post


Link to post
Share on other sites
You might want to do a simple test to see if the first few pixels in the image are actually gray (compare the individual components). It could be something going wrong in your usage of the vidCapture library.

Share this post


Link to post
Share on other sites
Quote:
Extrarius wrote:
You might want to do a simple test to see if the first few pixels in the image are actually gray (compare the individual components). It could be something going wrong in your usage of the vidCapture library.



I did a test like that. I compared the first two pixels in ptr with the color values retrieved from imagePtr->GetPixel() (which I know works, because I've acctually printed out the whole picture using only GetPixel and the regular SetPixel function ;-)). So it's doesen't seam to be anything wrong with the vidCapture library. The values in the ptr variable are OK.

Share this post


Link to post
Share on other sites
After some research I realized that I should use CreateDIBitmap instead, since the color depth of the pixel data differs from that of the device.

This is the new code:


if(!CVFAILED(g_vidCap->Grab(CVImage::CVIMAGE_RGB24, imagePtr)))
{
ptr = imagePtr->GetRawDataPtr();

HBITMAP Test;
HDC DC;
BITMAP bm;
BITMAPINFO BitmapInfo;


BitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BitmapInfo.bmiHeader.biWidth = 320;
BitmapInfo.bmiHeader.biHeight = 240;
BitmapInfo.bmiHeader.biPlanes = 1;
BitmapInfo.bmiHeader.biBitCount = 24;
BitmapInfo.bmiHeader.biCompression = BI_RGB;
BitmapInfo.bmiHeader.biSizeImage = 320 * 240 * 3;
BitmapInfo.bmiHeader.biXPelsPerMeter = 0;
BitmapInfo.bmiHeader.biYPelsPerMeter = 0;
BitmapInfo.bmiHeader.biClrUsed = 0;
BitmapInfo.bmiHeader.biClrImportant = 0;

Test = (HBITMAP)CreateDIBitmap(hDC, &BitmapInfo.bmiHeader, CBM_INIT, ptr, &BitmapInfo, DIB_RGB_COLORS);

DC2 = CreateCompatibleDC(hDC);
SelectObject(DC, Test);

BitBlt(hDC, 10, 10, bm.bmWidth, bm.bmHeight, DC, 0, 0, SRCCOPY);
DeleteObject(Test2);

CVImage::ReleaseImage(imagePtr);
}



With this code I get a picutre in full colors. There's still a problem though. When it comes to DI Bitmaps Windows doesn't use the regular color format: RGB. Red and blue switches places: GBR. I've understood that it does so for compatiblity with Presentation Manager of OS/2. So when I render my bitmap it is upside-down and with the wrong colors. I figure that this can't be too hard to solve, but I'm not very good with the low level memory functions of C++ (the best sollution would be to simply reverse the ptr array, wouldn't it?). I've tried functions like _swab and _strrev, but I can't get it to work on my unsigned char.

Share this post


Link to post
Share on other sites
Simply reversing the array will not correct the image orientation. It will be the right way up, but will be flipped left-to-right instead.
You need to swap entire rows (320 * 3 bytes).

Who was the friggin idiot that once decided that they wanted to store bitmaps upsidedown! Someone please go back in time and shoot that person!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this