Jump to content
Sign in to follow this  
monoceres

GetDIBits

Recommended Posts

monoceres

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
cppman

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
jpam

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
monoceres

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
Malkey

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
monoceres

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
monoceres

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
cppman

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  

×