【问题标题】:How to wrap an existing memory buffer as a DC in native win32?如何在本机 win32 中将现有内存缓冲区包装为 DC?
【发布时间】:2012-01-01 02:44:21
【问题描述】:

我在内存中有一个由 32 位 ARGB 值数组定义的图像。我想得到一个 DC 来绘制它,然后将结果放在同一个数组中。图像永远不会通过 blitting 显示在屏幕上。

如果不复制图像数据,这可能吗?

当我查看 msdn 的 CreateDC() 页面时,它需要一个驱动程序名称和一个设备。但直流不必与任何设备兼容。此外,如果显示器以 16 位或 32 位色深运行,我不希望结果有所不同。我想我需要一个与我的内存布局兼容的 DC,而不是与某些设备兼容的 DC。我该怎么做?

谢谢 马克

【问题讨论】:

  • <gdiplus.h> 很好地涵盖了这一点。使用 Bitmap(int, int, int, PixelFormat, BYTE*) 构造函数创建位图。使用从 Graphics::FromImage() 获得的 Graphics 对象进行绘制。

标签: image winapi memory draw gdi


【解决方案1】:

CreateDIBSection 让您指定位图的内存存储位置。但是,它需要位于内存映射部分中。

【讨论】:

  • 什么是内存映射部分?另外,根据我对 David 的回答,CreateDIBSection 可以用于获取现有内存缓冲区的 HBITMAP 句柄,还是将数据复制到新的内存位置?
  • CreateFileMapping 创建内存映射部分。您可以将该部分传递给 CreateDIBSection,它将使用该内存(通过引用,而不是副本)。
  • 谢谢。我在其他地方遇到过类似的建议,但我发现 CreateFileMapping 文档很难理解 - 它似乎需要一个文件名,但数据在内存中,而不是在文件中。没有文件如何使用函数?
  • 就像文档中所说的那样,如果您想要无文件映射,请传递 INVALID_FILE_HANDLE
【解决方案2】:

您需要创建一个位图和select that bitmap into your DC。位图是使用您的内存缓冲区创建的。

使用CreateBitmap(与设备相关)或CreateDIBitmap(与设备无关;这是我的建议,尤其是因为您不希望它受到显示颜色深度的影响——这意味着它应该是设备无关。)两者都有指向现有内存缓冲区的参数。例如,对于CreateDIBitmap,您需要传递CBM_INIT 标志,然后将指向缓冲区的指针作为lpbInit 参数传递。您还需要传入描述位图格式的BITMAPINFO 结构。

CreateBitmap 可以让您以稍微简单的方式做同样的事情,但位图(依赖于设备)使用起来不太灵活。

(顺便说一句,您可能希望在 CreateDC 上使用 CreateCompatibleDC - 取决于,但它通常是您所追求的。)

有关使用 DC 和位图的更多信息,请阅读 this article 之类的内容。 (根据您的问题,我不确定您对它们或一般 GDI 编程的熟悉程度。)

【讨论】:

  • 如果我理解正确,CreateDIBitmap 会将位图数据从您的内存缓冲区复制到新分配的内存中,并将 HBITMAP 句柄返回给副本。我和 OP 一样,正在寻找一种方法来获得直接绘制到现有内存缓冲区而不是其副本的 DC。有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-08
  • 2015-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-22
相关资源
最近更新 更多