Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

unable to read bitmap data from hBitmap

I am using the bitmapdata function in gdiplus to quickly get the pixel color info from a bitmap. It works when I load a bitmap from a file but it doesnt work when I use fromHbitmap where hBitmap contains a screencapture. when I use fromHbitmap, the resulting data is blank.

here is my code

#include
#include
#include
using namespace Gdiplus;



INT main()
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);



HDC hDDC = GetDC( GetDesktopWindow() );


HBITMAP hBitmap = CreateCompatibleBitmap(hDDC, 500, 500);



HPALETTE hPalette = (HPALETTE)GetCurrentObject(hDDC, OBJ_PAL);

Bitmap* bitmap = Bitmap::FromHBITMAP (hBitmap,hPalette); // when I change this line to Bitmap* bitmap = new Bitmap(L"D:my_picture.jpg"); it works

BitmapData* bitmapData = new BitmapData;
Rect rect(0, 0, 100, 100);

// Lock a 100x100 rectangular portion of the bitmap for reading.
bitmap->LockBits(
&rect,
ImageLockModeRead,
PixelFormat32bppARGB,
bitmapData);

printf("The stride is %d.

", bitmapData->Stride);

// Display the hexadecimal value of each pixel in the 100x100 rectangle.
UINT* pixels = (UINT*)bitmapData->Scan0;

for(UINT row = 0; row < 100; ++row)
{
for(UINT col = 0; col < 100; ++col)
{
printf("%x
", pixels[row * bitmapData->Stride / 4 + col]);
}
printf("- - - - - - - - - -
");
}

bitmap->UnlockBits(bitmapData);
delete bitmapData;
delete bitmap;
DeleteObject(hBitmap);
GdiplusShutdown(gdiplusToken);
return 0;
}

Comments

  • richfellrichfell Member Posts: 17
    I believe the root of your issue is that you are not creating a screen capture with these lines:

    HDC hDDC = GetDC( GetDesktopWindow() );
    HBITMAP hBitmap = CreateCompatibleBitmap(hDDC, 500, 500);

    What you are doing is creating a new "empty" bitmap which is compatible with the color settings of the desktop's Device Context.

    In order to get a screen capture you would have to get the desktop window to paint itself into your compatible bitmap by setting up a DeviceContext with your new bitmap and sending a WM_PAINT message to the desktop window supplying your bitmap's DeviceContext handle as the wParam.

    Something like:

    // get desktop window handle
    HWND hWndDesktop = GetDesktopWindow();

    // get the window rectangle
    RECT desktopRect;
    GetWindowRect(hWndDesktop, &desktopRect);

    // calculate width/height of the desktop window
    int dtWidth = desktopRect.right - desktopRect.left;
    int dtHeight = desktopRect.bottom - desktopRect.top;

    // create a compatible DC and bitmap
    HDC hDDC = CreateCompatibleDC(GetDC(hWndDesktop));
    BITMAP hBitmap = CreateCompatibleBitmap(hDDC, dtWidth, dtHeight);

    // select the bitmap into the compatible DC
    SelectObject(hDDC, hBitmap);

    // have the desktop paint itself into our bitmap
    SendMessage(hWndDesktop, WM_PAINT, (WPARAM)hDDC, 0);



  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [color=Blue]All correct, just instead of sending WM_PAINT use BitBlt() from desktop DC to memory DC.[/color]
  • heckubissheckubiss Member Posts: 2
    I used bitblt to copy the hDC into the hDDC but the pixel data is still blank

    #include
    #include
    #include
    using namespace Gdiplus;


    INT main()
    {
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    HWND hWndDesktop = GetDesktopWindow();
    HDC hDC;
    hDC=GetDC(hWndDesktop);
    // get the window rectangle
    RECT desktopRect;
    GetWindowRect(hWndDesktop, &desktopRect);

    // calculate width/height of the desktop window
    int dtWidth = desktopRect.right - desktopRect.left;
    int dtHeight = desktopRect.bottom - desktopRect.top;


    HDC hDDC = CreateCompatibleDC(hDC);
    HBITMAP hBitmap = CreateCompatibleBitmap(hDDC, dtWidth, dtHeight);
    SelectObject(hDDC, hBitmap);

    BitBlt(hDDC, 0, 0, dtWidth, dtHeight,hDC, 0, 0, SRCCOPY);

    HPALETTE hPalette = (HPALETTE)GetCurrentObject(hDDC, OBJ_PAL);
    Bitmap* bitmap = Bitmap::FromHBITMAP (hBitmap,hPalette);


    BitmapData* bitmapData = new BitmapData;
    Rect rect(0, 0, 100, 100);

    // Lock a 100x100 rectangular portion of the bitmap for reading.
    bitmap->LockBits(
    &rect,
    ImageLockModeRead,
    PixelFormat32bppARGB,
    bitmapData);

    printf("The stride is %d.

    ", bitmapData->Stride);

    // Display the hexadecimal value of each pixel in the 100x100 rectangle.
    UINT* pixels = (UINT*)bitmapData->Scan0;

    for(UINT row = 0; row < 100; ++row)
    {
    for(UINT col = 0; col < 100; ++col)
    {
    printf("%x
    ", pixels[row * bitmapData->Stride / 4 + col]);
    }
    printf("- - - - - - - - - -
    ");
    }

    bitmap->UnlockBits(bitmapData);
    delete bitmapData;
    delete bitmap;
    DeleteObject(hBitmap);
    GdiplusShutdown(gdiplusToken);




    printf("hello world");
    return 0;

    }
  • AsmGuru62AsmGuru62 Member Posts: 6,519
    : I used bitblt to copy the hDC into the hDDC but the pixel data is
    : still blank
    :
    : #include
    : #include
    : #include
    : using namespace Gdiplus;
    :
    :
    : INT main()
    : {
    : GdiplusStartupInput gdiplusStartupInput;
    : ULONG_PTR gdiplusToken;
    : GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    :
    : HWND hWndDesktop = GetDesktopWindow();
    : HDC hDC;
    : hDC=GetDC(hWndDesktop);
    : // get the window rectangle
    : RECT desktopRect;
    : GetWindowRect(hWndDesktop, &desktopRect);
    :
    : // calculate width/height of the desktop window
    : int dtWidth = desktopRect.right - desktopRect.left;
    : int dtHeight = desktopRect.bottom - desktopRect.top;
    :
    :
    : HDC hDDC = CreateCompatibleDC(hDC);
    : HBITMAP hBitmap = CreateCompatibleBitmap(hDDC, dtWidth,
    : dtHeight);
    : SelectObject(hDDC, hBitmap);
    :
    : BitBlt(hDDC, 0, 0, dtWidth, dtHeight,hDC, 0, 0, SRCCOPY);

    [color=Red]COLORREF rgb1 = GetPixel (hDDC, 22, 34);
    COLORREF rgb2 = GetPixel (hDDC, 78, 12);
    COLORREF rgb3 = GetPixel (hDDC, 74, 45);
    //
    // Take a few ^^^ pixels from memory DC and check
    // if they return real color values. If they are, then
    // code below is not doing its work, but the pixels are
    // retrieved and inside hDDC.
    [/color]
    :
    : HPALETTE hPalette = (HPALETTE)GetCurrentObject(hDDC, OBJ_PAL);
    : Bitmap* bitmap = Bitmap::FromHBITMAP (hBitmap,hPalette);
    :
    :
    : BitmapData* bitmapData = new BitmapData;
    : Rect rect(0, 0, 100, 100);
    :
    : // Lock a 100x100 rectangular portion of the bitmap for reading.
    : bitmap->LockBits(
    : &rect,
    : ImageLockModeRead,
    : PixelFormat32bppARGB,
    : bitmapData);
    :
    : printf("The stride is %d.

    ", bitmapData->Stride);
    :
    : // Display the hexadecimal value of each pixel in the 100x100
    : rectangle.
    : UINT* pixels = (UINT*)bitmapData->Scan0;
    :
    : for(UINT row = 0; row < 100; ++row)
    : {
    : for(UINT col = 0; col < 100; ++col)
    : {
    : printf("%x
    ", pixels[row * bitmapData->Stride / 4 + col]);
    : }
    : printf("- - - - - - - - - -
    ");
    : }
    :
    : bitmap->UnlockBits(bitmapData);
    : delete bitmapData;
    : delete bitmap;
    : DeleteObject(hBitmap);
    : GdiplusShutdown(gdiplusToken);
    :
    :
    :
    :
    : printf("hello world");
    : return 0;
    :
    : }
Sign In or Register to comment.