如何将System.Drawing.Bitmap覆盖到现有的GDI位图上?

时间:2010-04-14 01:36:19

标签: c# .net gdi+ gdi

如果我有.Net Bitmap,我可以通过调用Bitmap的{​​{1}}方法从中创建一个GDI位图。

GetHbitmap()

这很好用,但每次调用Bitmap bmp = new Bitmap(100, 100); IntPtr gdiBmp = bmp.GetHbitmap(); 时,Windows都必须分配返回的GetHbitmap引用的新内存。

我想做的 - 如果可能的话 - 写一个函数(我知道这里需要PInvoke),它还生成一个IntPtr的GDI位图副本,但是会覆盖现有的一块内存已经从Bitmap返回的IntPtr引用,而不是分配新内存。所以它看起来像这样(如果它是GetHbitmap的扩展方法):

Bitmap

我该怎么做?我假设我需要知道GDI位图的结构,可能我可以使用// 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 LockBits,但我不确定如何。

赏金猎人的线索:

BitmapData有一个方法Bitmap,它将位图锁定在内存中并返回一个LockBits对象。 BitmapData对象具有BitmapData属性,该属性是Scan0指向锁定位图的像素数据的开头(即指向位图的header又是位图本身的开头。)

我很确定解决方案看起来像这样:

IntPtr

解决方案不必是通用的 - 它只需要使用像素格式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); (默认的GDI +格式)的位图。

3 个答案:

答案 0 :(得分:3)

我认为您回答了自己的问题:使用LockBits。

请参阅 http://msdn.microsoft.com/en-us/library/ms229672.aspxhttp://www.bobpowell.net/lockingbits.htm

我使用这种方法在.NET(1.1!)程序中快速绘制分形,我正在写这篇文章以获得乐趣。在我尝试的所有方法中,这是迄今为止最快的方法。

答案 1 :(得分:2)

你不应该假设HANDLE或HBITMAP是指向任何东西的指针。它可以实现为句柄表的索引,哈希表的键等等。

但是,如果调用GDI GetObject函数,则结果BITMAP structure包含指向实数位的指针。

不确定它是否会如此快(我认为在源和目标的像素格式相同的情况下),但SetDIBits应该完全符合您的要求(替换现有HBITMAP中的数据) )。

答案 2 :(得分:2)

使用Graphics.FromHdc从IntPtr创建图形,并使用Graphics.DrawImage将Bitmap粘贴到其中。

相关问题