我这里强调的是Win32标准C++而不是MFC,所以没用到CBITMAP,属于比较底层一点。直接上代码了!
获取位图数据核心函数就是GetDIBits,通过它来获取位图的二进制数据。
static bool BMP_SaveFile(const char* szFile, const void* pBmp, int width, int height, int bitCount=32) { HANDLE hFile = CreateFile(szFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); assert(hFile != NULL); int bmp_size = width*height*(bitCount/8); // 【写位图文件头】 BITMAPFILEHEADER bmpHeader; bmpHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bmp_size; // BMP图像文件的大小 bmpHeader.bfType = 0x4D42; // 位图类别,根据不同的操作系统而不同,在Windows中,此字段的值总为‘BM’ bmpHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); // BMP图像数据的偏移位置 bmpHeader.bfReserved1 = 0; // 总为0 bmpHeader.bfReserved2 = 0; // 总为0 DWORD dwBytesWritten = 0; WriteFile(hFile, (LPSTR)&bmpHeader, sizeof(bmpHeader), &dwBytesWritten, NULL); BITMAPINFOHEADER bmiHeader; bmiHeader.biSize = sizeof(bmiHeader); // 本结构所占用字节数,即sizeof(BITMAPINFOHEADER); bmiHeader.biWidth = width; // 位图宽度(单位:像素) bmiHeader.biHeight = height; // 位图高度(单位:像素) bmiHeader.biPlanes = 1; // 目标设备的级别,必须为1 bmiHeader.biBitCount = bitCount; // 像素的位数(每个像素所需的位数,范围:1、4、8、24、32) bmiHeader.biCompression = 0; // 压缩类型(0:不压缩 1:BI_RLE8压缩类型 2:BI_RLE4压缩类型) bmiHeader.biSizeImage = bmp_size; // 位图大小(单位:字节) bmiHeader.biXPelsPerMeter = 0; // 水平分辨率(像素/米) bmiHeader.biYPelsPerMeter = 0; // 垂直分辨率(像素/米) bmiHeader.biClrUsed = 0; // 位图实际使用的彩色表中的颜色索引数 bmiHeader.biClrImportant = 0; // 对图象显示有重要影响的颜色索引的数目 // 【写位图信息头(BITMAPINFO的bmiHeader成员)】 WriteFile(hFile, (LPSTR)&bmiHeader, sizeof(bmiHeader), &dwBytesWritten, NULL); // 【写像素内容】 WriteFile(hFile, pBmp, bmp_size, &dwBytesWritten, NULL); CloseHandle(hFile); return true; } /* *基于GDI截图到粘贴板 */ static void Capture(HWND hWnd,int width,int height,bool save=false,string fileName="pic.bmp") { //尝试BITBLT截图 HDC hSrcDC = ::GetDC(hWnd); HDC hMemDC = ::CreateCompatibleDC(hSrcDC); HBITMAP hbmp = ::CreateCompatibleBitmap(hSrcDC, width, height); HBITMAP hOldbmp = (HBITMAP) ::SelectObject(hMemDC, hbmp); ::BitBlt(hMemDC, 0, 0, width, height, hSrcDC, 0, 0, SRCCOPY); OpenClipboard(NULL); EmptyClipboard(); SetClipboardData(CF_BITMAP,hbmp); CloseClipboard(); if(save) { int bmp_size = width*height*4;//32/8 byte* pData = new byte[bmp_size];//位图片的数据 BITMAPINFOHEADER bmiHeader; bmiHeader.biSize = sizeof(bmiHeader); // 本结构所占用字节数,即sizeof(BITMAPINFOHEADER); bmiHeader.biWidth = width; // 位图宽度(单位:像素) bmiHeader.biHeight = height; // 位图高度(单位:像素) bmiHeader.biPlanes = 1; // 目标设备的级别,必须为1 bmiHeader.biBitCount = 32; // 像素的位数(每个像素所需的位数,范围:1、4、8、24、32) bmiHeader.biCompression = 0; // 压缩类型(0:不压缩 1:BI_RLE8压缩类型 2:BI_RLE4压缩类型) bmiHeader.biSizeImage = bmp_size; // 位图大小(单位:字节) bmiHeader.biXPelsPerMeter = 0; // 水平分辨率(像素/米) bmiHeader.biYPelsPerMeter = 0; // 垂直分辨率(像素/米) bmiHeader.biClrUsed = 0; // 位图实际使用的彩色表中的颜色索引数 bmiHeader.biClrImportant = 0; // 对图象显示有重要影响的颜色索引的数目 int ret = GetDIBits(hSrcDC,hbmp,0,height,pData,(LPBITMAPINFO)&bmiHeader,DIB_RGB_COLORS); if(ret)BMP_SaveFile(fileName.c_str(),pData,width,height); if(pData)delete pData;//删除开辟的内存空间 } //释放 ::SelectObject(hMemDC,hOldbmp); DeleteDC(hMemDC); DeleteObject(hbmp); ReleaseDC(NULL, hSrcDC); }
获取位图数据核心函数就是GetDIBits,通过它来获取位图的二进制数据。
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2299
- 用户1336
- 访客10619057
每日一句
You leave, or I go with you.
你留下,或者我跟你走。——《海角七号》
你留下,或者我跟你走。——《海角七号》
新会员