使用C++编辑内存中的位图
Editing bitmap in memory using C++
我有一个二维数据数组,我想将其显示为图像。
计划是这样的 -
使用 CreateCompatibleBitmap
创建位图(这会产生纯黑色位图,我可以毫无问题地显示它)
编辑此位图的像素以匹配我的数据
BitBlt 位图到window
我想我需要一个指向内存中像素数据开始位置的指针。我已经尝试了很多不同的方法来做到这一点,并在谷歌上搜索了 3 天,但仍然无法编辑一个像素。
使用 SetPixel(HDC, x, y, Color)
循环来设置每个像素,但速度非常慢。
我通过锁定位图和编辑位在 C# 中完成了此操作,但我是 C++ 的新手,似乎无法弄清楚如何做类似的事情。
我大部分时间都在尝试使用 memset(p, value, length)
对于 "p",我尝试使用从 CreateCompatibleBitmap
返回的句柄、位图的 DC 和 window 的 DC。我已经尝试了各种值和长度的值。
不过,我不确定这是否正确。
我不必使用位图,这是我唯一知道要做的事情。实际上,如果能找到一种直接更改主 window 的 DC 的方法,那就太棒了。
不过,我确实想避免使用图书馆。我这样做纯粹是为了学习C++。
memset 可用于实际的 RGB 信息数组(但您还需要知道位图的格式,如果像素具有 32 或 24 位)。
从msdn的一些研究来看,你想要得到的似乎是BITMAP结构:
http://msdn.microsoft.com/en-us/library/k1sf4cx2.aspx
这里有可以进行 memset 的 bmBits。
如何从你的函数到达那里?
好吧,CreateCompatibleBitmap returns 一个 HBITMAP 结构,看来您可以使用以下代码从 HBITMAP 获取 BITMAP :
BITMAP bmp;
GetObject(hBmp, sizeof(BITMAP), &bmp);
然而,这似乎为您提供了现有位图信息的副本,它只解决了您的 memset 问题(您现在可以使用 memset 设置位图信息,尽管如此,除了制作bmp 全白或全黑)。
应该有一个函数可以让你将 DC bites 设置为一个位图,所以你应该能够使用新的位图作为参数。
这需要相当多的研究,所以我会 post 为可能正在寻找的其他人确切地说明它是如何完成的。
这会将每个像素都染成红色。
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;
我有一个二维数据数组,我想将其显示为图像。
计划是这样的 -
使用 CreateCompatibleBitmap
创建位图(这会产生纯黑色位图,我可以毫无问题地显示它)
编辑此位图的像素以匹配我的数据
BitBlt 位图到window
我想我需要一个指向内存中像素数据开始位置的指针。我已经尝试了很多不同的方法来做到这一点,并在谷歌上搜索了 3 天,但仍然无法编辑一个像素。
使用 SetPixel(HDC, x, y, Color)
循环来设置每个像素,但速度非常慢。
我通过锁定位图和编辑位在 C# 中完成了此操作,但我是 C++ 的新手,似乎无法弄清楚如何做类似的事情。
我大部分时间都在尝试使用 memset(p, value, length)
对于 "p",我尝试使用从 CreateCompatibleBitmap
返回的句柄、位图的 DC 和 window 的 DC。我已经尝试了各种值和长度的值。
不过,我不确定这是否正确。
我不必使用位图,这是我唯一知道要做的事情。实际上,如果能找到一种直接更改主 window 的 DC 的方法,那就太棒了。 不过,我确实想避免使用图书馆。我这样做纯粹是为了学习C++。
memset 可用于实际的 RGB 信息数组(但您还需要知道位图的格式,如果像素具有 32 或 24 位)。
从msdn的一些研究来看,你想要得到的似乎是BITMAP结构: http://msdn.microsoft.com/en-us/library/k1sf4cx2.aspx
这里有可以进行 memset 的 bmBits。
如何从你的函数到达那里?
好吧,CreateCompatibleBitmap returns 一个 HBITMAP 结构,看来您可以使用以下代码从 HBITMAP 获取 BITMAP :
BITMAP bmp;
GetObject(hBmp, sizeof(BITMAP), &bmp);
然而,这似乎为您提供了现有位图信息的副本,它只解决了您的 memset 问题(您现在可以使用 memset 设置位图信息,尽管如此,除了制作bmp 全白或全黑)。
应该有一个函数可以让你将 DC bites 设置为一个位图,所以你应该能够使用新的位图作为参数。
这需要相当多的研究,所以我会 post 为可能正在寻找的其他人确切地说明它是如何完成的。 这会将每个像素都染成红色。
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;