C++ 数组[字节]到HBITMAP或CBitmap
我有一个字节数组(我直接从.bmp中通过流读取,然后作为BLOB存储在数据库中),我想在CImageList中显示为图标。因此,我想以某种方式将数据加载到HBITMAP或CBitmap中。到目前为止,我一直是这样做的,从一个文件中读取:C++ 数组[字节]到HBITMAP或CBitmap,c++,mfc,C++,Mfc,我有一个字节数组(我直接从.bmp中通过流读取,然后作为BLOB存储在数据库中),我想在CImageList中显示为图标。因此,我想以某种方式将数据加载到HBITMAP或CBitmap中。到目前为止,我一直是这样做的,从一个文件中读取: hPic = (HBITMAP)LoadImage(NULL, strPath, IMAGE_BITMAP, dwWidth, dwHeight, LR_LOADFROMFILE | LR_VGACOLOR); ... CBitmap bitmap; bitma
hPic = (HBITMAP)LoadImage(NULL, strPath, IMAGE_BITMAP, dwWidth, dwHeight, LR_LOADFROMFILE | LR_VGACOLOR);
...
CBitmap bitmap;
bitmap.Attach(hPicRet);
但显然,这只适用于文件,而不适用于字节数组。如何获得相同的结果,但从字节数组中读取
编辑:
请注意,我的阵列不仅包含颜色信息,还包含写入磁盘的完整文件,包括所有标题和元数据。在我看来,放弃所有这些信息是一个坏主意。以下示例可能会对您有所帮助
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 );
BITMAPINFO-bmInfo;
BitMapInfo头文件&bmInfohdr=(BitMapInfo头文件)bmInfo.bmiHeader;
bminfo.biSize=40+255//我觉得没用
bminfo.biWidth=x;
bminfo.biHeight=y;
双翼飞机=1;
bminfo.bibibitcount=8;
bminfo.biCompression=0;
bminfo.biSizeImage=0;
bmInfohdr.biXPelsPerMeter=0;
bmInfohdr.biYPelsPerMeter=0;
bminfo.biClrUsed=0;
bminfo.biclr=0;
//我应该将内存分配到比
//bmColors[1]??无论如何,编译器给出了一个
//类型不匹配错误!
//bmInfo.bmiColors=(RGBQUAD*)
malloc(sizeof(RGBguad)*256);
//这里我定义了256灰度调色板
对于(int i=0;iGetDC();
HBITMAP hBmp=CreateDIBitmap(pdcDest->m_hDC,
&bmInfohdr,
CBM_INIT,
矩阵,
&bmInfo,
DIB_RGB_颜色);
m_bmpBitmap.附件(hBmp);
像这样的东西对我很有用:
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位颜色配置的,但您可以指定任何类型)。假设您已将信息加载到名为bytes的字节数组中
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);
它有点混乱,可能需要大量的错误检查,但基本思想是正确的。好的,下面是一个完整的示例:
#包括
#包括
#pragma注释(lib,“gdi32.lib”)
#pragma注释(lib,“user32.lib”)
char buf[1I我认为在我的代码中我想写这篇文章的地方没有(实际的)窗口句柄。GetDC()部分有解决方法吗?@Kdansky:您可以使用GetDC(NULL)返回的屏幕DC
。虽然这不会崩溃或造成其他不良后果,但只会导致我的所有图片都是空的。你确定当数组包含完整的位图(包括所有标题)时,它会工作吗?我真的在数据库中存储文件,包含所有的元数据,而不仅仅是像素颜色。开箱即用!谢谢!我可以问什么类型的您可以建议错误检查吗?@ K丹天空验证BMI、BMIH和位都在字节数组内。验证GETDC成功。验证创建didiMAP是否成功。您还可以考虑用更合适的调用交换GetDC(NULL)来获得DC。GetDC(NULL)。使用整个屏幕的DC来计算适当的颜色深度,这可能合适,也可能不合适-这取决于您计划使用hbitmap的内容。相关:(相反方向)
#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;
}