2011-02-14 51 views
8

我有一個字節數組(我通過直接從一個.bmp讀取流,然後作爲BLOB存儲在數據庫中),我想在CImageList中顯示爲圖標。因此,我想以某種方式將我的數據加載到HBITMAP或CBitmap中。我已經做了這樣的到現在爲止,從文件中讀取:陣列[字節] HBITMAP或CBitmap

hPic = (HBITMAP)LoadImage(NULL, strPath, IMAGE_BITMAP, dwWidth, dwHeight, LR_LOADFROMFILE | LR_VGACOLOR); 
... 
CBitmap bitmap; 
bitmap.Attach(hPicRet); 

但很明顯,這僅適用於文件,而不是字節數組。我怎樣才能得到相同的結果,但從字節數組中讀取?

編輯: 請注意,我的數組不包含只是顏色信息,而是完整的文件,因爲它是寫在磁盤上,包括所有頁眉和元數據。在我看來,丟棄所有這些信息是一個壞主意。

+0

相關:(相反的方向)[?:: Gdiplus位圖來BYTE陣列(http://stackoverflow.com/questions/3340017/gdiplusbitmap-to字節數組) – jrh 2016-12-15 13:16:15

回答

16

假設你已經裝載到一個名爲字節一個字節數組的信息....

BITMAPFILEHEADER* bmfh; 
bmfh = (BITMAPFILEHEADER*)bytes; 

BITMAPINFOHEADER* bmih; 
bmih = (BITMAPINFOHEADER*)(bytes + sizeof(BITMAPFILEHEADER)); 
BITMAPINFO* bmi; 
bmi = (BITMAPINFO*)bmih; 

void* bits; 
bits = (void*)(bytes + bmfh->bfOffBits); 

HDC hdc = ::GetDC(NULL); 

HBITMAP hbmp = CreateDIBitmap(hdc, bmih, CBM_INIT, bits, bmi, DIB_RGB_COLORS) ; 

::ReleaseDC(NULL, hdc); 

這是一個有點亂,可以使用錯誤檢查的一個沉重的劑量,但其基本思想是健全的。

2

下面的示例可以幫助你。

BITMAPINFO bmInfo; 
BITMAPINFOHEADER &bmInfohdr = (BITMAPINFOHEADER)bmInfo.bmiHeader; 

bmInfohdr.biSize = 40 + 255; //I think it's not of use 
bmInfohdr.biWidth = x; 
bmInfohdr.biHeight = y; 
bmInfohdr.biPlanes=1; 
bmInfohdr.biBitCount=8; 
bmInfohdr.biCompression=0; 
bmInfohdr.biSizeImage=0; 
bmInfohdr.biXPelsPerMeter = 0; 
bmInfohdr.biYPelsPerMeter = 0; 
bmInfohdr.biClrUsed = 0; 
bmInfohdr.biClrImportant = 0; 

      // should I allocate memory further than the 
      // bmColors[1]?? anyway the compiler gives an 
      // error for type mismatch! 
//bmInfo.bmiColors = (RGBQUAD *) 
        malloc(sizeof(RGBQUAD) * 256); 

// here I define the 256 graylevel palette 
for (int i=0; i<256; i++) 
{ 
    bmInfo.bmiColors[i].rgbRed = i; 
    bmInfo.bmiColors[i].rgbGreen = i; 
    bmInfo.bmiColors[i].rgbBlue = i; 
} 


BYTE *matrix; 
matrix = (BYTE*)malloc(size*sizeof(BYTE)); 
// here I put the BYTE values of the pixels 

CDC *pdcDest = this->GetDC(); 

HBITMAP hBmp = CreateDIBitmap(pdcDest->m_hDC, 
       &bmInfohdr, 
       CBM_INIT, 
       matrix,  
       &bmInfo, 
       DIB_RGB_COLORS); 
m_bmpBitmap.Attach(hBmp); 
0

事情是這樣的工作對我來說:


    int bitmap[WX*WY]; // truecolor bitmap data 
    BITMAPINFO bm = { sizeof(BITMAPINFOHEADER), WX, WY, 1, 32, BI_RGB, 0, 0, 0, 0, 0 }; 
    HBITMAP bmp = CreateDIBSection(GetDC(win), &bm, DIB_RGB_COLORS, (void**)&bitmap, 0,0); 

(這具體配置爲32位色,但您可以指定任何一種)。

+0

我相信在我的代碼中我沒有(實際的)窗口句柄來寫這個。 GetDC()部分是否有解決方法? – 2011-02-14 15:21:47

+0

@Kdansky:您可以使用`GetDC(NULL)`返回的屏幕DC。 – casablanca 2011-02-14 16:34:42

0

好的,這是一個完整的例子:http://nishi.dreamhosters.com/u/so_bmp_v0.zip

#include <stdio.h> 
#include <windows.h> 

#pragma comment(lib,"gdi32.lib") 
#pragma comment(lib,"user32.lib") 

char buf[1<<22]; 

int main(int argc, char **argv) { 

    FILE* f = fopen("winnt.bmp", "rb"); if(f==0) return 1; 
    fread(buf, 1,sizeof(buf), f); 
    fclose(f); 

    BITMAPFILEHEADER& bfh = (BITMAPFILEHEADER&)buf[0]; 
    BITMAPINFO& bi = (BITMAPINFO&)buf[sizeof(BITMAPFILEHEADER)]; 
    BITMAPINFOHEADER& bih = bi.bmiHeader; 
    char* bitmap = &buf[bfh.bfOffBits]; 

    int WX=1024, WY=512; // window's width/height 
    int SX=bih.biWidth, SY=bih.biHeight; 

    HWND win = CreateWindow("STATIC", "Bitmap test", 0x90C0, 0,0, WX,WY, 0,0, GetModuleHandle(0), 0); 

    MSG msg; 
    PAINTSTRUCT ps; 
    HDC DC = GetDC(win); // window's DC 
    HBITMAP dib = CreateDIBitmap(DC, &bih, CBM_INIT, bitmap, &bi, DIB_RGB_COLORS); 
    HDC dibDC = CreateCompatibleDC(DC); SelectObject(dibDC, dib); 

    ShowWindow(win, SW_SHOWNOACTIVATE); 
    SetFocus(win); 

    while(GetMessage(&msg,win,0,0)) { 
    int m = msg.message; 
    if(m==WM_PAINT) { 
     DC = BeginPaint(win, &ps); 
     StretchBlt(DC, 0,0,WX,WY, dibDC,0,0,SX,SY, SRCCOPY); 
     EndPaint(win, &ps); 
    } else if((m==WM_KEYDOWN) || (m==WM_SYSKEYDOWN)) { 
     break; 
    } else { 
     DispatchMessage(&msg); 
    } 
    } 

    return 0; 
}