Is it possible to BitBlt directly from a GDI+ bitmap?
Asked Answered
F

1

6

Is it possible to use BitBlt to copy directly out of a GDI+ bitmap without using GetHBitmap?

GetHBitmap is slow because it makes a new copy of the whole image, in addition to and slower than the BitBlt copy, and the given HBITMAP must be disposed. The image is large.

Is there a way to point BitBlt to use the pixel data of the original GDI+ image?

EDIT: I can get a pointer to where the GDI+ bitmap pixel data is in the memory. Can I create an HBITMAP that points to the GDI+ bitmap pixel data to avoid the extra copy, and BitBlt from that?

Flash answered 3/1, 2011 at 20:34 Comment(3)
BitBlt copies from one DC to another. To draw a bitmap onto a DC, you select the bitmap into the source DC and then BitBlt it onto the destination. If that's what you want to do with a GDI+ Bitmap object, shouldn't you just use Graphics.DrawImage, where the Graphics object wraps the intended target DC? Why go through an HBitmap at all?Photothermic
The reason I need BitBlt is for it's raster operations. DrawImage can't do an OR operation from one image to another. And I've done it with GDI bitmaps, but how can I select a GDI+ bitmap into an hDC? I'd really like to know if it is possible.Flash
Ugh, s/it's/itsFlash
F
8

After searching for days, it suddenly hit me that the answer had been staring me in the face all the time! I was creating a GDI+ bitmap from a pointer to a byte array. Then trying to create an HBITMAP using the same pointer. But I could just as easily create the HBITMAP first and use the pointer from that to create the GDI+ bitmap.

It works like a charm! You can mix GDI and GDI+ operations however you like. The image is both plain GDI and GDI+ at once. Instead of using DrawImage, you can BitBlt from the exact same pixel data!

Here's the code:

// Create the HBITMAP
BITMAPINFO binfo = new BITMAPINFO();
binfo.biSize = (uint)Marshal.SizeOf(typeof(BITMAPINFO));
binfo.biWidth = width;
binfo.biHeight = height;
binfo.biBitCount = (ushort)Image.GetPixelFormatSize(pixelFormat);
binfo.biPlanes = 1;
binfo.biCompression = 0;

hDC = CreateCompatibleDC(IntPtr.Zero);

IntPtr pointer;
hBitmap = CreateDIBSection(hDC, ref binfo, 0, out pointer, IntPtr.Zero, 0);

// Create the GDI+ bitmap using the pointer returned from CreateDIBSection
gdiBitmap = new Bitmap(width, height, width * binfo.biBitCount >> 3, pixelFormat, pointer);
Flash answered 4/1, 2011 at 20:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.