如果我有 .Net Bitmap,我可以通过调用 Bitmap 的 GetHbitmap() 方法从中创建 GDI 位图.
Bitmap bmp = new Bitmap(100, 100);
IntPtr gdiBmp = bmp.GetHbitmap();
这工作正常,但每次调用 GetHbitmap 时,Windows 都必须分配返回的 IntPtr 引用的新内存。
如果可能的话,我想做的是编写一个函数(我知道这里需要 PInvoke),该函数还生成 Bitmap 的 GDI 位图副本,但会覆盖现有的从 GetHbitmap 返回的 IntPtr 已经引用的内存块,而不是分配新内存。所以它看起来像这样(如果它是 Bitmap 的扩展方法):
// desired method signature:
void OverwriteHbitmap(IntPtr gdi)
{
}
// ex:
Bitmap bmp1 = new Bitmap(100, 100);
IntPtr gdi1 = bmp1.GetHbitmap();
Bitmap bmp2 = new Bitmap(100, 100);
bmp2.OverwriteHbitmap(gdi1); // gdi1 is still pointing to the same block
// of memory, which now contains the pixel data from bmp2
我该怎么做?我假设我需要知道 GDI 位图的结构,也许我可以为此使用 LockBits 和 BitmapData,但我不确定具体如何使用。
赏金猎人的线索:
Bitmap 有一个方法 LockBits 将位图锁定在内存中并返回一个 BitmapData 对象。 BitmapData 对象有一个 Scan0 属性,它是一个 IntPtr 指向锁定位图像素数据的开始(即它不' t 指向位图的 header ,也就是位图本身的开始)。
我很确定解决方案看起来像这样:
Bitmap bmp1 = new Bitmap(100, 100);
IntPtr gdi1 = bmp1.GetHbitmap(); // now we have a pointer to a
// 100x100 GDI bitmap
Bitmap bmp2 = new Bitmap(100, 100);
BitmapData data = bmp2.LockBits();
IntPtr gdi1Data = gdi1 + 68; // magic number = whatever the size
// of a GDI bitmap header is
CopyMemory(data.Scan0, gdi1Data, 40000);
解决方案不必是通用的 - 它只需要适用于像素格式 Format32bppArgb(默认 GDI+ 格式)的位图。
请您参考如下方法:
我想您已经回答了您自己的问题:使用 LockBits。
见 How to: Use LockBits 和 Bob Powell - Locking Bits .
我使用这种方法在我编写的 .NET(1.1!)程序中快速绘制分形是为了好玩。在我试验过的所有方法中,这是迄今为止最快的。
