尝试修改hbitmap数据时出现堆栈错误
问题描述:
我试图修改hbitmap以在渲染它之前添加透明像素(但这不是问题),并且在使用一些Google搜索之后,我无法让我的代码正常工作。 这就是我想:尝试修改hbitmap数据时出现堆栈错误
HBITMAP hBitmap = NULL, hBitmapOld = NULL;
HDC hMemDC = NULL;
BLENDFUNCTION bf;
hMemDC = CreateCompatibleDC(hdc);
hBitmapOld = (HBITMAP)SelectObject(hMemDC, bitmap);
BITMAPINFO MyBMInfo = { 0 };
MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);
if (0 == GetDIBits(hMemDC, bitmap, 0, height, NULL, &MyBMInfo, DIB_RGB_COLORS))
return;
// create the pixel buffer
BYTE* lpPixels = new BYTE[MyBMInfo.bmiHeader.biSizeImage];
if (0 == GetDIBits(hMemDC, bitmap, 0, height, lpPixels, &MyBMInfo, DIB_RGB_COLORS))
return;
for (int i = 0; i < width*height; i++)//i know there's 4 bytes per pixel, it's just to try
lpPixels[i] = 0;
if (0 == SetDIBits(hMemDC, bitmap, 0, height, lpPixels, &MyBMInfo, DIB_RGB_COLORS))
return;
delete[] lpPixels;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 255; //transparency value between 0-255
bf.AlphaFormat = 0;
AlphaBlend(hdc, xabs, yabs, width, height, hMemDC, 0, 0, width, height, bf);
SelectObject(hMemDC, hBitmapOld);
DeleteDC(hMemDC);
DeleteObject(hBitmap);
Actualy我只是试图将像素设置为0,这应该图像的四分之一设置黑色(eventualy透明)像素(因为我只是去从0到w * x,像素长度为4个字节)。
但有一些数据损坏,所以当该函数退出时,我得到一个异常。然后我的代码是不正确的。
我可以说位图装载得很好,我从GetDIBits
得到了很好的位图信息。
由于
答
我folowwed VTT的意见,但它仍然没有奏效,看来这个问题是从哪里来的这是不正确的使用BITMAPINFO
,所以我也跟着一路微软并here和它的作品:
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = width;
bi.biHeight = height;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
if (0 == GetDIBits(hMemDC, bitmap, 0, height, NULL, (BITMAPINFO*)&bi, DIB_RGB_COLORS))
return;
// create the pixel buffer
BYTE* lpPixels = new BYTE[bi.biWidth * bi.biHeight * bi.biBitCount/8];
if (0 == GetDIBits(hMemDC, bitmap, 0, height, lpPixels, (BITMAPINFO*)&bi, DIB_RGB_COLORS))
return;
for (int i = 0; i < width*height; i++)//i know there's 4 bytes per pixel, it's just to try
lpPixels[i] = 0;
if (0 == SetDIBits(hMemDC, bitmap, 0, height, lpPixels, (BITMAPINFO*)&bi, DIB_RGB_COLORS))
return;
答
MSDN来自:
biSizeImage
大小,以字节为单位的图像。对于BI_RGB位图,这可能设置为零。 如果biCompression是BI_JPEG或BI_PNG,biSizeImage分别指示JPEG或PNG图像缓冲区的大小。
所以我怀疑你创建了一个有效的空数组,因为位图通常没有被压缩,并在稍后遭受缓冲区溢出。
为了获得需要的缓冲区大小,你应该检查biCompression
,然后(假定它是未压缩BI_RGB
)乘以biWidth * biHeight * biBitCount/8
怎么样,发表** **完整,但小例子。加上数据文件(图像)。 –
为了避免内存泄漏和进入更好的习惯,对临时动态分配的像素缓冲区使用'std :: vector'。 –
发生了什么类型的异常? – nate