尝试修改hbitmap数据时出现堆栈错误

时间:2017-10-20 13:37:09

标签: c++ gdi

我尝试修改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,这应该为图像的四分之一设置黑色(最终透明)像素(因为我只是从0到w * x,像素是4个字节长。)

但是有一些数据损坏,所以当该函数退出时我得到一个异常。然后我的代码不正确。

我可以说位图已经很好地加载了,我从GetDIBits获得了良好的位图信息。

由于

2 个答案:

答案 0 :(得分:1)

来自MSDN

  

<强> biSizeImage

     

图像的大小(以字节为单位)。对于BI_RGB位图,这可以设置为零。   如果biCompression是BI_JPEG或BI_PNG,则biSizeImage分别表示JPEG或PNG图像缓冲区的大小。

所以我怀疑你创建了有效的空数组,因为位图通常不会被压缩,以后会受到缓冲区溢出的影响。

要获取需要的缓冲区大小,您应该检查biCompression然后(假设它是未压缩的BI_RGB)乘以biWidth * biHeight * biBitCount / 8

答案 1 :(得分:0)

我接受了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;
相关问题