Sign in to follow this  
Vortez

GDI Bitmap color conversion

Recommended Posts

Vortez    2714
Hi, i need a little help with some code in my project, i've been using this code below to generate a screenshot, store it into some buffer, then converting it to 24 bits using my own conversion routine.

[code]
HWND hDesktopWnd = GetDesktopWindow();
HDC hdc = GetDC(hDesktopWnd);

SShot s;
s.x = 0;
s.y = 0;
s.w = GetSystemMetrics(SM_CXSCREEN);
s.h = GetSystemMetrics(SM_CYSCREEN);

s.hdc = CreateCompatibleDC(hdc);
s.hbmp = CreateCompatibleBitmap(hdc,s.w,s.h);
s.ex_hbmp = (HBITMAP)SelectObject(s.hdc, s.hbmp);

BitBlt(s.hdc,0,0,s.w,s.h,hdc,s.x,s.y,SRCCOPY);
//StretchBlt(s.hdc,0,0,s.w,s.h,hdc,0,s.h,s.w,-s.h,SRCCOPY);

ReleaseDC(hDesktopWnd,hdc);

/////////////////////////////////////////////////////////////////////////////////////////

// Allocate buffers
DWORD NumPixels = s.w * s.h;
Buffers.ScreenShot.Allocate(NumPixels * 4);
Buffers.Converted.Allocate(NumPixels * 3);

// Fill the ScreenShot buffer
GetBitmapBits(s.hbmp, Buffers.ScreenShot.GetBufferSize(), Buffers.ScreenShot.GetBuffer());

// Convert it to 24 bits in another buffer
DWORD Ret = ConvertTo24bits(Buffers.Converted.GetBuffer(), Buffers.ScreenShot.GetBuffer(), Buffers.ScreenShot.GetBufferSize());

/////////////////////////////////////////////////////////////////////////////////////////

// Release the bitmap handles
if(SelectObject(s.hdc, s.hbmp)){
DeleteObject(s.hbmp);
DeleteDC(s.hdc);
}
[/code]

The problem is, if the screen resolution use another color format than 32 bits, this code won't work.
So, i would like to know how can i convert the image to 24 bits from any pixel format the desktop is currently using.

Thx.

Share this post


Link to post
Share on other sites
Endurion    5408
The simplest solution would be to create another bitmap in memory, this time with 24 bits. Then you select each into their own HDC and BitBlt the graphic from one to the other. Let Windows take care of the conversion.

Share this post


Link to post
Share on other sites
Vortez    2714
After some experimentation and some explanation about GetDIBits, all i had to do was to replace the GetBitmapBits call by this, getting rid of my own format routine at the same time:

[code]
LPBITMAPINFO lpbi = (LPBITMAPINFO)(new char[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)]);
ZeroMemory(lpbi, sizeof(BITMAPINFO));
int x = sizeof(BITMAPINFOHEADER);
int y = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

SelectObject(s.hdc, s.ex_hbmp);

GetDIBits(s.hdc, s.hbmp, 0, s.h, NULL, lpbi, DIB_RGB_COLORS);
lpbi->bmiHeader.biBitCount = 16;
lpbi->bmiHeader.biSizeImage = (s.w * s.h) * (lpbi->bmiHeader.biBitCount / 8);
lpbi->bmiHeader.biCompression = BI_RGB;

LPVOID lpvBits = new char[lpbi->bmiHeader.biSizeImage];
ZeroMemory(lpvBits, lpbi->bmiHeader.biSizeImage);

GetDIBits(s.hdc, s.hbmp, 0, s.h, lpvBits, lpbi, DIB_RGB_COLORS);
SelectObject(s.hdc, s.hbmp);

SAFE_DELETE_ARRAY(lpvBits);
SAFE_DELETE_ARRAY(lpbi);
[/code]

Just posting in case this can help someone else...

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