2017-08-29 22 views
1

How to convert an Array of pixels to HBITMAPの指示に従って、ピクセル配列をHBITMAPに変換しようとしています。ビット配列をHBITMAPに変換した後にNULLポインタbmBits

基本的に、配列はHBITMAPに変換され、クリップボードにコピーされて検証されます。しかし、BITMAP構成要素のビット値にbmBitsメンバーでアクセスすると、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である:

hgdiobjCreateDIBSectionを呼び出すことによって作成されたビットマップへのハンドルで、指定されたバッファが十分に大きい場合、GetObject関数はDIBSECTION構造体を返します。さらに、DIBSECTIONに含まれるBITMAP構造体のbmBitsメンバには、ビットマップのビット値へのポインタが含まれます。

HGDIOBJは、任意の他の手段、GetObject戻るだけの幅、高さ、およびビットマップのカラーフォーマット情報によって作成されたビットマップへのハンドルである場合。 GetDIBits()またはGetBitmapBits()関数を呼び出して、ビットマップのビット値を取得できます。

これは、とりわけBITMAPが含まれているDIBSECTION構造のためのDIBビットマップを照会するときbmBitsのみが取り込まれることを意味します。

BITMAP構造体のDDBビットマップを照会しているため、bmBitsにデータが取り込まれず、ピクセルビットを個別に取得する必要があります。

関連する問題