Click to See Complete Forum and Search --> : [RESOLVED] GDI+ LockBits method


thehumph
February 21st, 2008, 12:17 PM
Hi folks,

I'm working on an important university project, using native unmanaged Win32 C++ in the Visual Studio 2005 Professional IDE.

I have created a class Image to encapsulate and extend functionality from both Bitmap and BitmapData objects in GDI+ (gdiplus.h) for my own purposes. Part of this process has been to create a method Image::lockBits() to transfer the functionality of the Bitmap::LockBits() method. I am having trouble with binding my BitmapData object to the Bitmap object using image->LockBits(). The relevant articles of code are below, starting with my global declarations in the Image object:

Gdiplus::Bitmap * image;
Gdiplus::BitmapData imageData;
int width;
int height;

Then the function Image::lockbits:

int Image::lockBits (int originX, int originY, int areaX, int areaY)
{
Gdiplus::Rect rect (originX, originY, areaX, areaY);

image->LockBits(&rect,
Gdiplus::ImageLockModeRead | Gdiplus::ImageLockModeWrite,
PixelFormat8bppIndexed, imageData);

return 0;
}

As you can see my BitmapData object imageData is in the correct place, but in previous uses of GDI+ I have used &imageData instead, which seems to work. If I try the same practice here, I get the following error message in Visual Studio:

>c:\users\andy\documents\uni\bsc project\code\bscproject\image.cpp(212) : error C2664: 'Gdiplus::Bitmap::LockBits' : cannot convert parameter 4 from 'Gdiplus::BitmapData **__w64 ' to 'Gdiplus::BitmapData *'
> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

Has anyone experienced this or can suggest any lines of further enquiry? This has placed a halt on my integration so any help would be appreciated! I am happy to provide further information about this problem on request.

Cheers,

thehumph

CBasicNet
February 21st, 2008, 09:00 PM
What's wrong with &imageData?

And also, you need to change from PixelFormat8bppIndexed to PixelFormat32bppARGB, unless you want to get 8 bits per pixel index which is very difficult to work with.

thehumph
February 21st, 2008, 10:14 PM
If I use &imageData in my Image object I get the following error:

>c:\users\andy\documents\uni\bsc project\code\bscproject\image.cpp(212) : error C2664: 'Gdiplus::Bitmap::LockBits' : cannot convert parameter 4 from 'Gdiplus::BitmapData **__w64 ' to 'Gdiplus::BitmapData *'
> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

I used 8bpp because my image should be grayscale. Although if I manipulate only one colour channel during thresholding there are some odd results compared to manipulating all three... which makes me believe that ImageJ is lying when I save as 8-bit and the image is actually still in 24-bit (It's JPEG - does that make a difference?)

CBasicNet
February 21st, 2008, 11:04 PM
Can you check imageData is a pointer or object? It seems it is a pointer.

As I said, PixelFormat8bppIndexed is 8 bits per pixel index which is difficult to work with. Unless you want to work with color palettes because what you are getting back are not grey colors but indexes in the palette.

If you manipulate only one colour channel during thresholding there are some odd results compared to manipulating all three, then convert the image to greyscale or average out the color components to make sure the image is really greyscale, then you will not have this problem.