我这里强调的是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)
站点信息
- 文章2305
- 用户1336
- 访客11455538
每日一句
Talent without working hard is nothing.
没有努力,天份不代表什么。
没有努力,天份不代表什么。
MySQL 数据库优化
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de
免ROOT实现模拟点击任意位置
Mobaxterm终端神器
CreateProcessW要注意的细节问题
Autonomous NAT Traversal
【教程】win10 彻底卸载edge浏览器
eclipse工程基于Xposed的一个简单Hook
排名前5的开源在线机器学习
Mac OS最简单及(Karabiner)快捷键设置
发一款C++编写的麻将
VMware NAT端口映射外网访问虚拟机linux
独家发布最新可用My-AutoPost——wordpress 采集器
新会员