能否直接从GDI+位图中进行BitBlt操作?

6
是否可以使用BitBlt直接从GDI+位图中复制,而不使用GetHBitmap?
由于GetHBitmap会创建整个图像的新副本,并且比BitBlt复制慢,而且给定的HBITMAP必须被处理,因此它很慢。 图像很大。
是否有一种方法可以指向BitBlt以使用原始GDI+图像的像素数据?
编辑:我可以获取指向存储在内存中的GDI+位图像素数据的指针。 我可以创建一个指向GDI+位图像素数据的HBITMAP,以避免多余的复制,并从那里进行BitBlt吗?

1
BitBlt从一个DC复制到另一个DC。要将位图绘制到DC上,您需要将位图选择到源DC中,然后使用BitBlt将其绘制到目标DC上。如果您想对GDI+ Bitmap对象执行此操作,那么应该只需使用Graphics.DrawImage,其中Graphics对象包装了预期的目标DC,为什么还要通过HBitmap呢? - Rob Kennedy
1
我需要 BitBlt 是因为它的光栅操作。DrawImage 无法从一个图像到另一个图像执行 OR 操作。我已经使用 GDI 位图完成了这个操作,但是如何将 GDI+ 位图选择到 hDC 中呢?我真的很想知道是否可能。 - jnm2
啊,s/it's/its - jnm2
1个回答

8
在搜索了几天后,我突然意识到答案一直在我的面前!我正在从指向字节数组的指针创建GDI+位图。然后尝试使用相同的指针创建HBITMAP。但我可以很容易地先创建HBITMAP,然后使用来自它的指针创建GDI+位图。
这个方法非常有效!您可以随意混合使用GDI和GDI+操作。图像同时具有纯GDI和GDI+功能。您可以从完全相同的像素数据中使用BitBlt而不是DrawImage!
以下是代码:
// 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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接