尝试修改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得到了很好的位图信息。

由于

+0

怎么样,发表** **完整,但小例子。加上数据文件(图像)。 –

+0

为了避免内存泄漏和进入更好的习惯,对临时动态分配的像素缓冲区使用'std :: vector'。 –

+0

发生了什么类型的异常? – nate

我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