【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博客
相关文章:

【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);nHei…...

HDFS介绍
目录 编辑 一、HDFS基础 1.1 概述 1.2 HDFS的设计目标 1.2.1 硬件故障 1.2.2 流式数据访问 1.2.3 超大数据集 1.2.4 简单的一致性模型 1.2.5 移动计算而不是移动数据 1.2.6 跨异构硬件和软件平台的可移植性 1.3 基础概念 1.3.1 块(Block) 1.3.2 复制…...

每日一题——两数之和
题目 给出一个整型数组 numbers 和一个目标值 target,请在数组中找出两个加起来等于目标值的数的下标,返回的下标按升序排列。 (注:返回的数组下标从1开始算起,保证target一定可以由数组里面2个数字相加得到࿰…...

Maven: ‘mvn‘ is not recognized as an internal or external command
下载并配置好Maven之后,CMD测试安装是否成功:mvn -v 提示: mvn is not recognized as an internal or external command, operable program or batch file. 检查环境变量: MAVEN_HOME: %MAVEN_HOME%\bin: 看上去没问题&#x…...

CubeSLAM: Monocular 3D Object SLAM——论文简述
一、简介 提出一种在动态和静态环境中同时进行3D目标检测和定位建图的方法,并且能够互相提升准确度。具体地,对于3D目标,其位置、方向和尺寸通过slam进行了优化;而3D目标作为slam中的路标,可以提供额外的语义和几何约…...

【雕爷学编程】MicroPython动手做(30)——物联网之Blynk 2
知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED…...

linux scp 拷贝文件到目标linux系统
scp -P 8866 -r jsonrpc/ root192.168.6.66:/folder_path...

Oracle-expdp报错ORA-39077、06502(Bug-16928674)
问题: 用户在使用expdp进程导出时,出现队列报错ORA-39077、ORA-06502 ORA-31626: job does not exist ORA-31638: cannot attach to job SYS_EXPORT_SCHEMA_01 for user SYS ORA-06512: at "SYS.DBMS_SYS_ERROR", line 95 ORA-06512: at "SYS.KUPV$…...

Kafka入门,保姆级教学
文章目录 Kafka概念消息中间件对比消息中间件对比-选择建议Kafka常用名词介绍Kafka入门1. Kafka安装配置2.Kafka生产者与消费者关系3.Kafka依赖4.生产者发消息5.消费者接受消息6.Kafka高可用性设计6.1集群Kafka备份机制(Reolication) 7.kafka生产者详解7.1 发送类型7.2参数详解…...

RabbitMQ 过期时间(TTL)
TTL,Time to Live的简称,即过期时间,RabbitMQ可以对消息和队列设置TTL。 RabbitMQ支持设置队列的过期时间和消息的过期时间。如果设置队列的过期时间则队列中所有的消息都有相同的过期时间。如果设置消息的过期时间则每条消息的过期时间则可以不同。如两…...

C 语言练习题、持续更新
文章目录 C语言练习题读懂每个练习题才是学好一门代码的重要经历目录(先不要看答案,首先自己做才能更好的领悟,做不来没关系)题目一:有 1、2、3、4 四个数字,能组成多少个互不相同且无重复数字的三位数&…...

Android Q以上后台启动Activity初步尝试
在Android Q以后 google不允许在后台service 广播等等启动Activity 具体请看google文档从后台启动 Activity 的限制 | Android 开发者 | Android Developers 文档里有详细的说明,在哪种情况下可以后台启动Activity。 大体分为以下几种情况: 1、应用具有可见窗口,例如前…...

【torchlars】windows下载github中的torchlars包遇到的问题及解决方案
环境 python3.7 windows10 cuda11.1 pytorch1.8.1 虚拟环境miniconda 目的 windows下载github中的torchlars包 遇到的问题 问题一:直接下载好文件夹输入指令:python setup.py install 出现错误:RuntimeError: Error compiling objects f…...

SolidUI社区-通用Prompt技巧
背景 随着文本生成图像的语言模型兴起,SolidUI想帮人们快速构建可视化工具,可视化内容包括2D,3D,3D场景,从而快速构三维数据演示场景。SolidUI 是一个创新的项目,旨在将自然语言处理(NLP)与计算机图形学相…...

C++中类的封装写出一个文件加密的小项目
文件的加密较为简单,当然也可以修改它的加密方式等,供大家参考 #include<string> #include<fstream> class ReaderFile { public:string Read(const string& filename){cout << "读取文件,获取明文"<<…...

【网络编程·传输层】UDP和TCP的报头
目录 一、端口号划分 二、部分指令 1、pidof(用于查看进程id) 2、netstat(查看网络状态) 三、UDP协议 1、UDP协议格式 2、UDP协议如何进行封装、解包、分用 2.1封装、解包 2.2分用 3、UDP协议的特点 3.1UDP协议的特点 …...

C语言编程技巧 全局变量在多个c文件中公用的方法
在使用C语言编写程序时,经常会遇到这样的情况:我们希望在头文件中定义一个全局变量,并将其包含在两个不同的C文件中,以便这个全局变量可以在这两个文件中共享。举个例子,假设项目文件夹"project"下有三个文件…...

【HDFS】NN处理全量块汇报时reportDiff的一些细节
NN处理全量块汇报(FBR)时的一些细节怎么生成的toRemove怎么check 汇报上来的块是不是corrupt的?reportDiff方法里巧妙地引入delimiterBlock这个block的作用前置知识:【HDFS】Block、BlockInfo、BlockInfoContiguous、BlockInfoStriped的分析记录 上面的文章中介绍了关于Bl…...

JVM之类加载与字节码(一)
1.类文件结构 一个简单的HelloWorld.Java package cn.itcast.jvm.t5; // HelloWorld 示例 public class HelloWorld { public static void main(String[] args) { System.out.println("hello world"); } }编译为 HelloWorld.class 后的样子如下所示: […...

【数据结构OJ题】合并两个有序数组
原题链接:https://leetcode.cn/problems/merge-sorted-array/ 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 看到这道题,我们注意到nums1[ ]和nums2[ ]两个数组都是非递减的。所以我们很容易想到额外开一个数组tmp[ ]&#x…...

数据结构笔记--归并排序及其拓展题(小和问题、逆序对问题)
目录 1--归并排序 2--小和问题 3--逆序对问题 1--归并排序 归并排序的核心思想:将一个无序的序列归并排序为一个有序的系列;通过递归将无序的序列二分,从底层开始将二分的序列归并排序为有序序列; #include <iostream> #…...

flutter开发实战-实现css线性渐变转换flutter渐变LinearGradient功能
flutter开发实战-实现css线性渐变转换flutter渐变LinearGradient功能 在之前项目开发中,遇到更换样式,由于从服务器端获取的样式均为css属性值,需要将其转换成flutter类对应的属性值。这里只处理线性渐变linear-gradient 比如渐变 “linear-…...

python推理小游戏bagels
python推理小游戏bagels bagels是一个推理小游戏,你的朋友想到一个随机的、没有重复的3位数字,你尝试去猜测它是什么。每次猜测之后,朋友就会给出3中类型的线索: Bagels: 你猜测的3个数都不在神秘数字中;Pico&#x…...

DBSCAN聚类
一、概述 DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,簇集的划定完全由样本的聚集程度决定。聚集程度不足以构成簇落的那些样本视为噪声点,因此DBSCAN聚类的方式也可以用于异常点的检测。 二、算法…...

java+ssm美食推荐交流系统 7jsw7
随着社会的发展,美食推荐系统的管理形势越来越严峻。越来越多的用户利用互联网获得信息,但美食推荐信息鱼龙混杂,真假难以辨别。为了方便用户更好的获得美食推荐信息,因此,设计一款安全高效的美食推荐系统极为重要。 为…...

基于php雪花算法工具类Snowflake -来自chatGPT
<?phpclass Snowflake {// 定义Snowflake算法的各个参数private $workerIdBits 5;private $datacenterIdBits 5;private $sequenceBits 12;private $workerIdShift;private $datacenterIdShift;private $timestampLeftShift;private $maxWorkerId;private $maxDatacente…...

怎么加密文件夹才更安全?安全文件夹加密软件推荐
文件夹加密可以让其中数据更加安全,但并非所有加密方式都能够提高极高的安全强度。那么,怎么加密文件夹才更安全呢?下面我们就来了解一下那些安全的文件夹加密软件。 文件夹加密超级大师 如果要评选最安全的文件夹加密软件,那么文…...

知识分享和Tomcat简单部署press应用
一、简述静态网页和动态网页的区别。 静态网页: 静态网页是指运行于客户端的程序、网页、组件、纯粹HTML格式的网页; 如果有涉及网页内容的修改,就要修改源文件,重新上传到服务器。而且当网站信息量很大的时候,网页制作和维护都非常困…...

回归预测 | MATLAB实现SO-CNN-BiGRU蛇群算法优化卷积双向门控循环单元多输入单输出回归预测
回归预测 | MATLAB实现SO-CNN-BiGRU蛇群算法优化卷积双向门控循环单元多输入单输出回归预测 目录 回归预测 | MATLAB实现SO-CNN-BiGRU蛇群算法优化卷积双向门控循环单元多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现SO-CNN-BiGRU蛇群算法…...

步入React前厅 - 组件和JSX
目录 扩展学习资料 购物车应用 编写React元素 /src/index.js 创建组件 /src/components/listItem.jsx /src/App.js 理解JSX【JavaScriptXML】 JSX是什么 JSX规则 /src/components/listItem.jsx 使用Fragments /src/App.js 为何要使用Fragments 表格中使用Fragme…...