2017-10-20 132 views
0

我試圖修改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

回答

0

我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; 
1

MSDN來自:

biSizeImage

大小,以字節爲單位的圖像。對於BI_RGB位圖,這可能設置爲零。 如果biCompression是BI_JPEG或BI_PNG,biSizeImage分別指示JPEG或PNG圖像緩衝區的大小。

所以我懷疑你創建了一個有效的空數組,因爲位圖通常沒有被壓縮,並在稍後遭受緩衝區溢出。

爲了獲得需要的緩衝區大小,你應該檢查biCompression,然後(假定它是未壓縮BI_RGB)乘以biWidth * biHeight * biBitCount/8