HBITMAP to .net Bitmap through PInvoke

0 down vote favorite


i am trying to use unmanaged code from managed code

i would like to provide the following function from the unmanaged code

extern "C" __declspec( dllexport) HBITMAP * DetectDocumentPatter(HBITMAP* b);
for now the implementation of the code just return the same parameter b

i am trying to access it from .net side

1
2
3
4
5
6
        Bitmap b = new Bitmap(@"C:\Projects\samples\9b.jpg");
        Rectangle rect = new Rectangle(0, 0, b.Width, b.Height);
        BitmapData bmpData = b.LockBits(rect, ImageLockMode.ReadWrite, b.PixelFormat);
       IntPtr p = wrapper.DetectDocumentPatter(bmpData.Scan0);
        Bitmap c = Bitmap.FromHbitmap(p);
        c.Save(@"C:\Projects\samples\unmanagedBitmap.jpg");


but the 5th line code through a generic error occured in GDI+

any idea how can i marshal HBITMAP to .net Bitmap ! i've searched here but the content is really misleading
An HBITMAP is a bitmap header (H-BITMAP, HEADER-BITMAP). Scan0, on the other hand, is the address of the first row of data, which is NOT the bitmap header. Therefore your C# code is incorrect.

UPDATE: The question kept ringing a bell in the back of my head so I checked. HBITMAP is a handle to a bitmap object, so the above doesn't apply entirely.

It is true, though that Scan0 is not the equivalent of a bitmap handle, and this is why you get an error.
Last edited on
How about the GetHbitmap() method of Bitmap?

Bitmap.GetHbitmap Method
http://msdn.microsoft.com/en-us/library/1dz311e4.aspx

i.e. (untested)

1
2
3
4
5
6
        Bitmap b = new Bitmap(@"C:\Projects\samples\9b.jpg");
        IntPtr p1 = b.GetHbitmap();
        IntPtr p2 = wrapper.DetectDocumentPatter(p1);
        Bitmap c = Bitmap.FromHbitmap(p2);
        c.Save(@"C:\Projects\samples\unmanagedBitmap.jpg");
        // TODO : calls to GDI DeleteObject  


Andy

PS Belatedly noticed that your imported function DetectDocumentPatter is working with HBITMAP*s rather than the usual HBITMAP. Any reason for that? Usually you only use a HBITMAP* for an out param.

MSDN states that GetHbitmap() returns an HBITMAP and FromHbitmap takes an HBITMAP, not HBITMAP*. So you should adjust DetectDocumentPatter if possible. e.g.

1
2
3
4
5
6
7
8
9
10
11
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

private void DemonstrateGetHbitmap()
{
    Bitmap bm = new Bitmap("Picture.jpg");
    IntPtr hBitmap = bm.GetHbitmap();

    // Do something with hBitmap.
    DeleteObject(hBitmap);
}


DeleteObject definitely takes a handle!
Last edited on
Topic archived. No new replies allowed.