Sign in to follow this  
Followers 0
monoceres

GetDIBits

8 posts in this topic

Hi!

Recently I have done some pixel effects with the use of the GetPixel and SetPixel functions, but I have found out that it's way to slow. So I tried to use GetDIBits instead but it's so d*mn hard to use.

Here's my current effort:

#include <windows.h>
void _BitmapTest(HBITMAP bitmap)
{
    int extramem=2 * sizeof(RGBQUAD); // Extra memory for 32 bit bitmaps or something
    BYTE *pByte=NULL;
    HDC dc=GetDC(NULL);
    BITMAPINFO info={0};
    info.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
    GetDIBits(dc,bitmap,0,0,NULL,&info,DIB_RGB_COLORS);
    pByte= new BYTE[sizeof(BITMAPINFO)+extramem]; // I have no idea what this do
   
// A lot of code should be here...

    ReleaseDC(NULL,dc);
    delete[] pByte;
}

All I want is to get and set the colors of the pixels in the bitmap but I just don't get it.

Any help is appreciated :)


Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

GetDIBits copies the bitmap into a buffer. Since it doesn't return a pointer to the buffer, it is literally copying the entire bitmap to your buffer. Why would you need this function to get/set a pixel's color? I'm not sure if there is a LockBits function in C++, but you need something similar to that. It gives you a pointer to the buffer rather than copying the buffer.

edit

GDI+ has a Bitmap class that has a LockBits method.

http://msdn.microsoft.com/en-us/library/ms536298(VS.85).aspx

Edited by cppman

Share this post


Link to post
Share on other sites

if you want the GetDCBits from a loaded bitmap you have to call it twice

first call you must have the pvBits set to 0

it copies the bitmapinfo to the BITMAPINFOHEADER struct

allocate some bytes with GlobalAlloc

then call GetDCBits again , set pvBits with the pointer returned from GlobalAlloc

then it copies the bitmapbits

sorry can't give you an example , i don't code in C

Share this post


Link to post
Share on other sites

I'm going with cppman's suggestion because I got the performance boost I wanted.

From seconds to milliseconds :)


Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites

I'm going with cppman's suggestion because I got the performance boost I wanted.

From seconds to milliseconds :)

If you mean by cppman's suggestion you mean the LockBits method.

There is _GDIPlus_BitmapLockBits() in help, and a forum search on that functions will help.

Share this post


Link to post
Share on other sites

If you mean by cppman's suggestion you mean the LockBits method.

There is _GDIPlus_BitmapLockBits() in help, and a forum search on that functions will help.

I already implemented it in c++ :)


Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

I already implemented it in c++ :)

Correction, I thought I implemented it.

Running the code is a lot like lottery, sometimes it works as expected, sometimes it draws 4/5 of the image and sometimes it crashes :P

My code look like this:

// Redraws a HBITMAP into a graphics object.
// Just a test
extern "C" __declspec(dllexport) int _BitmapGreyScale(HBITMAP &hbitmap, Graphics &graphics)
{
    Bitmap *bitmap= new Bitmap(hbitmap,0);
    Bitmap *canvas= new Bitmap(hbitmap,0);
    int status;
//  BYTE red,green,blue, grey;
    int width=bitmap->GetWidth();
    int height=bitmap->GetHeight();
    Rect rect(0,0,width,height);

    // Lock first bitmap
    BitmapData *bdata= new BitmapData;
    bitmap->LockBits(&rect,ImageLockModeRead,PixelFormat32bppARGB,bdata); // So stupid that you cannot or Write and Read values...
    UINT * pixels=(UINT*)bdata->Scan0;
    
    // Lock second bitmap
    BitmapData *writedata= new BitmapData;
    canvas->LockBits(&rect,ImageLockModeWrite,PixelFormat32bppARGB,writedata);
    UINT *writepixels=(UINT*)writedata->Scan0;

    
    // Loop through the pixel data
    for (UINT x=0;x<(UINT)width;x++){
        for (UINT y=0;y<(UINT)height;y++){
        writepixels[x * writedata->Stride / 4 + y]=pixels[x * bdata->Stride / 4 + y];

        }
        
    }

    // Unlock the bitmaps again
    canvas->UnlockBits(writedata);
    bitmap->UnlockBits(bdata);


    status=graphics.DrawImage(canvas,rect);
    // Clean up
    delete canvas;
    delete bitmap;
    delete bdata;
    delete writedata;
    return status;
}

What am I doing wrong?

Edited by monoceres

Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites

Correction, I thought I implemented it.

Running the code is a lot like lottery, sometimes it works as expected, sometimes it draws 4/5 of the image and sometimes it crashes :)

I've got no clue, actually. I only know the concept behind LockBits from playing with Direct3D. I never work with GDI (or GDI+) in C++.

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  
Followers 0