当前位置: 首页 > news >正文

【GDI/GDI+】如何抓取屏幕保存到bitmap文件?

问题

如何抓取屏幕保存到bitmap文件?

方法

GDI 方法

1、抓取。

HBITMAP CRectChartUI::GetBitmap(HDC hDC)
{HDC hMemDC;int x, y;int nWidth, nHeight;HBITMAP hBitmap, hOldBitmap;hMemDC = CreateCompatibleDC(hDC);nWidth = GetDeviceCaps(hDC, HORZRES);nHeight = GetDeviceCaps(hDC, VERTRES);hBitmap = CreateCompatibleBitmap(hDC, nWidth, nHeight);hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);BitBlt(hMemDC, 0, 0, nWidth, nHeight, hDC, 0, 0, SRCCOPY);hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);DeleteDC(hMemDC);return hBitmap;
}

2、保存bitmap文件函数

// 保存位图到文件
int CScreenshotsWnd::SaveBitmapToFile(HBITMAP hBitmap, LPCWSTR lpFileName)
{           WORD   wBitCount;   //位图中每个像素所占字节数     // 定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数     DWORD   dwPaletteSize = 0, dwBmBitsSize, dwDIBSize, dwWritten;BITMAP   Bitmap; //位图属性结构     BITMAPFILEHEADER   bmfHdr;   //位图文件头结构     BITMAPINFOHEADER   bi;   //位图信息头结构     HANDLE   fh;   //定义文件,分配内存句柄,调色板句柄   LPSTR   lpbk, lpmem;wBitCount = 32;//设置位图信息头结构     GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);bi.biSize = sizeof(BITMAPINFOHEADER);bi.biWidth = Bitmap.bmWidth;bi.biHeight = Bitmap.bmHeight; //为负,正向的位图;为正,倒向的位图   bi.biPlanes = 1;bi.biBitCount = wBitCount;bi.biCompression = BI_RGB;bi.biSizeImage = 0;bi.biXPelsPerMeter = 0;bi.biYPelsPerMeter = 0;bi.biClrUsed = 0;bi.biClrImportant = 0;dwBmBitsSize = ((Bitmap.bmWidth*wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;//创建位图文件fh = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);if (fh == INVALID_HANDLE_VALUE)return   FALSE;//设置位图文件头     bmfHdr.bfType = 0x4D42;   //   "BM"     dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize;bmfHdr.bfSize = dwDIBSize;bmfHdr.bfReserved1 = 0;bmfHdr.bfReserved2 = 0;bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);//写入位图文件头WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);//写入位图信息头   WriteFile(fh, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwWritten, NULL);//获取位图阵列lpmem = new   char[dwBmBitsSize];lpbk = (LPSTR)   new   char[dwBmBitsSize];GetBitmapBits(hBitmap, dwBmBitsSize, lpmem);//正向的内存图象数据  //转化为倒向数据(仅在bmHeight为正时需要)   for (int i = 0; i < Bitmap.bmHeight; i++){memcpy(lpbk + Bitmap.bmWidth*i * 4, lpmem + Bitmap.bmWidth*(Bitmap.bmHeight - i - 1) * 4, Bitmap.bmWidth * 4);}//写位图数据WriteFile(fh, lpbk, dwBmBitsSize, &dwWritten, NULL);//清除     delete[]lpbk;delete[]lpmem;CloseHandle(fh);return   TRUE;
}

3、调用方式

SaveBitmapToFile(GetBitmap(hDC), _T("d:\\debug\\1.bmp"));

GDI+方法

1、抓屏幕保存至文件。

BOOL CRectChartUI::SaveHDCToFile(HDC hDC, Gdiplus::Rect rc, LPCWSTR lpFileName)
{BOOL bRet = FALSE;//将目标区域贴图到内存BITMAPHDC hMemDC = CreateCompatibleDC(hDC);HBITMAP hBitmap = CreateCompatibleBitmap(hDC, rc.Width, rc.Height);SelectObject(hMemDC, hBitmap);BitBlt(hMemDC, 0, 0, rc.Width, rc.Height, hDC, rc.X, rc.Y, SRCCOPY);//保存成文件{//L"image/bmp" L"image/jpeg"  L"image/gif" L"image/tiff" L"image/png"CLSID pngClsid;GetEncoderClsid(L"image/bmp", &pngClsid);//此处以BMP为例,其它格式选择对应的类型,如JPG用L"image/jpeg" Gdiplus::Bitmap *pbmSrc = Gdiplus::Bitmap::FromHBITMAP(hBitmap, NULL);if (pbmSrc->Save(lpFileName, &pngClsid) == Gdiplus::Status::Ok){bRet = TRUE;}delete pbmSrc;}//清理工作SelectObject(hMemDC, (HBITMAP)NULL);DeleteDC(hMemDC);DeleteObject(hBitmap);return bRet;
}

 

2、检索编码器的类标识符

BOOL CRectChartUI::GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{UINT num = 0;                    //number of image encodersUINT size = 0;                   //size of the image encoder array in bytesint nRet;UINT i;ImageCodecInfo* pImageCodecInfo = NULL;nRet = GetImageEncodersSize(&num, &size);if (nRet != Gdiplus::Status::Ok){return FALSE;}pImageCodecInfo = (ImageCodecInfo*)(malloc(size));if (pImageCodecInfo == NULL){return FALSE;}GetImageEncoders(num, size, pImageCodecInfo);for (i = 0; i < num; i++){if (wcscmp(pImageCodecInfo[i].MimeType, format) == 0){*pClsid = pImageCodecInfo[i].Clsid;free(pImageCodecInfo);return TRUE;}}free(pImageCodecInfo);return FALSE;
}

 3、调用方式。

SaveHDCToFile(hDC, rc, _T("d:\\debug\\test.bmp"));

总结

1、GDI+保存文件种类可以选择bmp、jpeg等多种,GDI只能是bmp。

2、流程基本一致,但GDI保存需要自己实现。

参考:【GDI+】GetEncoderClsid()函数,检索编码器的类标识符_sunriver2000的博客-CSDN博客

http://www.lryc.cn/news/112479.html

相关文章:

  • HDFS介绍
  • 每日一题——两数之和
  • Maven: ‘mvn‘ is not recognized as an internal or external command
  • CubeSLAM: Monocular 3D Object SLAM——论文简述
  • 【雕爷学编程】MicroPython动手做(30)——物联网之Blynk 2
  • linux scp 拷贝文件到目标linux系统
  • Oracle-expdp报错ORA-39077、06502(Bug-16928674)
  • Kafka入门,保姆级教学
  • RabbitMQ 过期时间(TTL)
  • C 语言练习题、持续更新
  • Android Q以上后台启动Activity初步尝试
  • 【torchlars】windows下载github中的torchlars包遇到的问题及解决方案
  • SolidUI社区-通用Prompt技巧
  • C++中类的封装写出一个文件加密的小项目
  • 【网络编程·传输层】UDP和TCP的报头
  • C语言编程技巧 全局变量在多个c文件中公用的方法
  • 【HDFS】NN处理全量块汇报时reportDiff的一些细节
  • JVM之类加载与字节码(一)
  • 【数据结构OJ题】合并两个有序数组
  • 数据结构笔记--归并排序及其拓展题(小和问题、逆序对问题)
  • flutter开发实战-实现css线性渐变转换flutter渐变LinearGradient功能
  • python推理小游戏bagels
  • DBSCAN聚类
  • java+ssm美食推荐交流系统 7jsw7
  • 基于php雪花算法工具类Snowflake -来自chatGPT
  • 怎么加密文件夹才更安全?安全文件夹加密软件推荐
  • 知识分享和Tomcat简单部署press应用
  • 回归预测 | MATLAB实现SO-CNN-BiGRU蛇群算法优化卷积双向门控循环单元多输入单输出回归预测
  • 步入React前厅 - 组件和JSX
  • SpringBoot整合Sfl4j+logback的实践