2017-08-29 110 views
1

我試圖按照本文中的指示將像素數組轉換爲HBITMAPHow to convert an Array of pixels to HBITMAP將位數組轉換爲HBITMAP後的空指針

基本上,數組轉換爲HBITMAP,然後通過複製到剪貼板進行驗證。但是,如果從其成員訪問BITMAP構造的位值,則返回NULL

我可能在這裏缺少一些東西。如果成功創建了HBITMAP,爲什麼我們仍然會得到指向其位值的NULL

uint8 width = 160; 
uint8 height = 120; 

uint8* pixels = new uint8[160 * 120 * 4]; 
for (int i = 0; i < 160 * 120 * 4; i++){ 
    pixels[i] = (i % 4 == 1) * 255; // testing pixels 
} 

BITMAPINFOHEADER bmih; 
bmih.biSize = sizeof(BITMAPINFOHEADER); 
bmih.biWidth = width; 
bmih.biHeight = -1 * height; 
bmih.biPlanes = 1; 
bmih.biBitCount = 32; 
bmih.biCompression = BI_RGB; 
bmih.biSizeImage = 0; 
bmih.biXPelsPerMeter = 10; 
bmih.biYPelsPerMeter = 10; 
bmih.biClrUsed = 0; 
bmih.biClrImportant = 0; 

BITMAPINFO dbmi; 
ZeroMemory(&dbmi, sizeof(dbmi)); 
dbmi.bmiHeader = bmih; 
dbmi.bmiColors->rgbBlue = 0; 
dbmi.bmiColors->rgbGreen = 0; 
dbmi.bmiColors->rgbRed = 0; 
dbmi.bmiColors->rgbReserved = 0; 

HDC hdc = ::GetDC(NULL); 

HBITMAP hbmp = CreateDIBitmap(hdc, &bmih, CBM_INIT, pixels, &dbmi, DIB_RGB_COLORS); 
if (hbmp == NULL) { 
    ::MessageBox(NULL, L"Could not load the desired image", L"Error", MB_OK); 
    return NULL; 
} 

::ReleaseDC(NULL, hdc); 

// a little test if everything is OK 
OpenClipboard(NULL); 
EmptyClipboard(); 
SetClipboardData(CF_BITMAP, hbmp); // I can verify the image by pasting 
CloseClipboard(); 

// verify the bitmap 
BITMAP bitmap; 
::GetObject(hbmp, sizeof(BITMAP), &bitmap); 
uint8* lpbits = (uint8*)bitmap.bmBits; 

assert(lpbits != NULL); // Why this assertion failed?? 

// cleanup 
// DeleteObject(hbmp); 
+0

調用GetLastError來查看調用失敗的原因 - 至少你會得到一個線索 – pm100

+0

@ pm100:大多數GDI函數不會使用GetLastError()來進行錯誤報告,對於使用的GDI函數在這個例子中(只有剪貼板功能)。 –

+0

@RemyLebeau不夠公平。所以沒辦法獲得除了'沒有工作'以外的任何東西。但是,如果某些基礎事件失敗(文件錯誤),那麼GetLastError將返回一些內容(雖然它可能是一條紅色鯡魚)。 – pm100

回答

7

答案是在GetObject() documentation

如果hgdiobj是一個處理一個位圖通過調用CreateDIBSection創建,並指定緩衝區足夠大,GetObject函數返回一個DIBSECTION結構。另外,DIBSECTION中包含的BITMAP結構的bmBits成員將包含指向位圖位值的指針。

如果hgdiobj是一個手柄通過任何其他手段,GetObject只返回寬度,高度和顏色格式位圖的信息創建的位圖。您可以通過調用GetDIBits()GetBitmapBits()函數來獲取位圖的位值。

這意味着查詢DIB位圖用於DIBSECTION結構,它包含一個BITMAP除其他事項外時bmBits僅填充。

您正在查詢一個BITMAP結構的DDB位圖,因此bmBits不會被填充,並且您必須單獨檢索像素位。