Creating a GDI+ Bitmap from an 8-bit Bitmap

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Hello,
I am trying to capture a portion of the screen, and then display that using
GDI+. My current approach for doing this is to create a bitmap using
CreateCompatibleBitmap(), select that into a memory DC, and call BitBlt() to
copy the contents of the screen DC into my memory DC. I then pass the HBITMAP
for the to the GDI+ Bitmap constructor.

This works very well when the display is set to use either 16-bit or 32-bit
color. However, if the display is set to 8-bit color, then the colors in the
captured bitmap aren't displayed correctly. At first, I thought that this was
because I wasn't passing an HPALETTE to the GDI+ Bitmap, however when I
capture the current palette and pass that as well, there is no change in the
displayed image.

I am sure that I am capturing the palette correctly, because if I draw the
HBITMAP to the screen using the HPALETTE and normal GDI calls, the image is
displayed correctly.

I'm really not sure what else I have to do in order to get GDI+ to use the
palette information for the bitmap. Do you have any ideas as to what I am
doing wrong?

Here's the code that I am using to capture the screen:
HDC hDCScreen = GetDC(NULL);
SIZE szScreen = {
GetDeviceCaps(hDCScreen, HORZRES),
GetDeviceCaps(hDCScreen, VERTRES)
};

HDC hDCBuffer = CreateCompatibleDC(hDCScreen);

UINT bitDepth = GetDeviceCaps(hDCScreen, BITSPIXEL);
HPALETTE hPalOld = NULL;

LOGPALETTE* pPalette = NULL;
UINT nColors = 0;
if(bitDepth <= 8)
{
nColors = GetSystemPaletteEntries(hDCScreen, 0, 0, NULL);
pPalette =
(LOGPALETTE*)malloc(sizeof(LOGPALETTE)+(nColors-1)*sizeof(PALETTEENTRY));
pPalette->palVersion = 0x300;
pPalette->palNumEntries = (WORD)nColors;
GetSystemPaletteEntries(hDCScreen, 0, nColors, pPalette->palPalEntry);
m_hPalScreen = CreatePalette(pPalette);
hPalOld = (HPALETTE)SelectObject(hDCBuffer, m_hPalScreen);
RealizePalette(hDCBuffer);
free(pPalette);
}

m_hBmpScreen = CreateCompatibleBitmap(hDCScreen, szScreen.cx, szScreen.cy);

HBITMAP hBmpOld = (HBITMAP)SelectObject(hDCBuffer, m_hBmpScreen);
BitBlt(hDCBuffer, 0, 0, szScreen.cx, szScreen.cy, hDCScreen, 0, 0, SRCCOPY);

if(NULL != m_hPalScreen)
{
SelectObject(hDCBuffer, hPalOld);
}

m_pImage = Bitmap::FromHBITMAP(m_hBmpScreen, m_hPalScreen);

SelectObject(hDCBuffer, hBmpOld);
DeleteDC(hDCBuffer);

ReleaseDC(NULL, hDCScreen);

Thanks,
Andy
.



Relevant Pages

  • Re: Creating a GDI+ Bitmap from an 8-bit Bitmap
    ... You could also try calling UnrealizeObject before creating your gdi+ bitmap. ... This will force the system to completely remap the logical palette to the ... I am trying to capture a portion of the screen, and then display that ...
    (microsoft.public.win32.programmer.gdi)
  • Re: Bitmaps displayed in CScrollView are chopped when scrolled
    ... Basically, use GDI+ for decoding, and then GDI for image display. ... I cannot successfully convert a GDI++ bitmap back to a DIB. ...
    (microsoft.public.win32.programmer.gdi)
  • Improving Image Display Performance
    ... I capture from a camera embedded in a Pocket PC. ... create a Bitmap object, and display it in a PictureBox. ... I get around 15 frames per seconds in 160x120, ...
    (microsoft.public.dotnet.framework.compactframework)
  • Re: Creating a GDI+ Bitmap from an 8-bit Bitmap
    ... You should use SelectPalette to bring the palette into the device context ... hDCBuffer) before you create the gdi+ bitmap. ... I am trying to capture a portion of the screen, and then display that ...
    (microsoft.public.win32.programmer.gdi)
  • Re: Capturing Windows Media Player image
    ... The GDI+ FAQ has an article on how to capture a control, ... screen to a Bitmap. ... The technique uses interop and the GDI BitBlt API. ... Answer those GDI+ questions with the GDI+ FAQ ...
    (microsoft.public.dotnet.framework.drawing)