使用 C++ 在内存中编辑位图
Posted
技术标签:
【中文标题】使用 C++ 在内存中编辑位图【英文标题】:Editing bitmap in memory using C++ 【发布时间】:2015-01-12 03:22:10 【问题描述】:我有一个要显示为图像的二维数据数组。
计划是这样的 -
使用CreateCompatibleBitmap
创建位图(这会生成纯黑色位图,我可以毫无问题地显示它)
编辑此位图的像素以匹配我的数据
BitBlt 位图到窗口
我认为我需要一个指向内存中像素数据开始位置的指针。我已经尝试了许多不同的方法,并在谷歌上搜索了 3 天,但仍然无法编辑单个像素。
使用SetPixel(HDC, x, y, Color)
的循环来设置每个像素工作但非常缓慢。
我已经在 C# 中通过锁定位图和编辑位来实现这一点,但我是 C++ 新手,似乎不知道如何做类似的事情。
我一直在尝试使用memset(p, value, length)
对于“p”,我尝试使用从CreateCompatibleBitmap
返回的句柄、位图的 DC 和窗口的 DC。我已经尝试了各种值和长度的值。
我不确定这是否是正确的使用方法。
我不必使用位图,这只是我知道要做的唯一事情。实际上,找到一种直接更改主窗口 DC 的方法会很棒。 我确实想避免图书馆。我这样做纯粹是为了学习 C++。
【问题讨论】:
您首先准备像素数据,然后使用CreateDIBSection
创建位图。或者完全绕过位图,直接使用SetDIBitsToDevice
从数据缓冲区渲染。
但是,如果您出于某种原因坚持要修改现有位图,SetDIBits
这是非常有用的信息,我将开始着手实施它。我仍然很好奇是否有办法逐像素更改内存中的位图,有点像编写我自己的 SetDIBits 函数。或者这会不会有点太难了?
好吧,如果你的意思是“逐像素”字面意思,那就是SetPixel
在我看来,您主要是在学习低级 C Windows API。可能有用,可能很有趣,但肯定不是 c++。至少不是 21 世纪的 c++
【参考方案1】:
这需要相当多的研究,所以我将准确地发布它是如何为其他可能正在寻找的人完成的。 这会将每个像素都染成红色。
hDC = BeginPaint(hWnd, &Ps);
const int
width = 400,
height = 400,
size = width * height * 3;
byte * data;
data = new byte[size];
for (int i = 0; i < size; i += 3)
data[i] = 0;
data[i + 1] = 0;
data[i + 2] = 255;
BITMAPINFOHEADER bmih;
bmih.biBitCount = 24;
bmih.biClrImportant = 0;
bmih.biClrUsed = 0;
bmih.biCompression = BI_RGB;
bmih.biWidth = width;
bmih.biHeight = height;
bmih.biPlanes = 1;
bmih.biSize = 40;
bmih.biSizeImage = size;
BITMAPINFO bmpi;
bmpi.bmiHeader = bmih;
SetDIBitsToDevice(hDC, 0, 0, width, height, 0, 0, 0, height, data, &bmpi, DIB_RGB_COLORS);
delete[] data;
【讨论】:
为什么要硬编码 40 而不是 sizeof(BITMAPINFOHEADER) ?【参考方案2】:memset 可用于实际的 RGB 信息数组(但您还需要知道位图的格式,如果像素有 32 位或 24 位)。
通过对msdn的一些研究,似乎你想要得到的是BITMAP结构: http://msdn.microsoft.com/en-us/library/k1sf4cx2.aspx
在那里你有你可以memset的bmBits。
如何从你的函数中到达那里?
好吧,CreateCompatibleBitmap 返回一个 HBITMAP 结构,看来您可以使用以下代码从 HBITMAP 获取 BITMAP:
BITMAP bmp;
GetObject(hBmp, sizeof(BITMAP), &bmp);
然而,这似乎得到了现有位图信息的副本,它只解决了你的 memset 问题(你现在可以使用 memset 设置位图信息,即使我没有看到 memeset 除了制作 bmp 之外的任何其他用途白色或黑色)。
应该有一个函数可以让你将 DC 位设置为位图,所以你应该可以使用新的位图作为参数。
【讨论】:
以上是关于使用 C++ 在内存中编辑位图的主要内容,如果未能解决你的问题,请参考以下文章