【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…...
动态规划 -- 最长公共子序列
最长公共子序列的结构设序列 X{x1,x2,…,x m} 和 Y{y1,y2,…,y n} 的最长公共子序列为 Z{z1,z2,…,z k},则有以下结论:若 x my n,则 z kx my n,且 Z k−1(即 Z 去掉最后一个元素 z k 后的子序列)是 X m−1&…...
Linux内核链表安全遍历:list_for_each_entry_safe 深度解析
1. 为什么需要安全的链表遍历 在Linux内核开发中,链表是最基础也是最常用的数据结构之一。内核开发者经常需要遍历链表来访问或操作其中的节点。但有一个场景特别棘手:当你需要在遍历过程中删除当前节点时,普通的遍历方法会导致链表断裂甚至系…...
告别复杂状态机:用C语言结构体数组为STM32设计可维护的多级菜单
用结构体数组重构STM32菜单系统:从状态机到模块化设计的进阶之路 在嵌入式开发中,菜单系统是许多产品不可或缺的交互界面。传统的状态机或switch-case实现方式虽然直接,但随着功能迭代,代码往往会变得臃肿难维护。我曾接手过一个使…...
Unity LineRenderer不只是画线:5个实战案例教你做激光、轨迹与魔法特效
Unity LineRenderer实战进阶:从激光瞄准到魔法光束的5种创意实现 在Unity游戏开发中,LineRenderer常被简单地视为"画线工具",但它的潜力远不止于此。当我们将这个组件与物理系统、着色器技术和游戏逻辑相结合时,它能创造…...
PX4串口通讯避坑指南:从波特率设置到数据收发全流程解析(以Serial4/5为例)
PX4串口通讯实战指南:从硬件配置到数据交互的深度解析 在无人机和机器人开发领域,PX4作为一款开源的飞控系统,其串口通讯功能是实现传感器数据采集、地面站通信以及外设控制的核心技术。然而,许多开发者在实际项目中常会遇到数据丢…...
搜索时代的命名战略:如何在亚马逊规避“品牌失语症”
在亚马逊这个由算法与关键词统治的商业世界里,一个名字的恰当与否,直接决定了品牌是“响亮宣言”还是“沉默失语”。许多名字如同《时代》或《财富》杂志,在传统语境中或许优雅,但在需要极致精准的数字货架上,却可能因…...
Mac Mouse Fix:释放第三方鼠标潜能,重构macOS输入体验
Mac Mouse Fix:释放第三方鼠标潜能,重构macOS输入体验 【免费下载链接】mac-mouse-fix Mac Mouse Fix - A simple way to make your mouse better. 项目地址: https://gitcode.com/GitHub_Trending/ma/mac-mouse-fix 现象解构:当高端鼠…...
数学学习者的终极指南:如何高效利用开源资源库构建完整知识体系
数学学习者的终极指南:如何高效利用开源资源库构建完整知识体系 【免费下载链接】awesome-math A curated list of awesome mathematics resources 项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-math 在数字化学习时代,如何从海量的…...
DB2数据迁移实战:除了EXPORT/LOAD,这几种备份还原方法你试过吗?
DB2数据迁移实战:超越基础工具的高效策略全景 当测试环境的DB2数据库需要整体搬迁到新服务器时,大多数DBA的第一反应是使用EXPORT/LOAD这对经典组合。但真实场景中,数据迁移远不止简单的导出导入——表结构依赖、CLOB字段处理、编码转换、存储…...
基于PyTorch Geometric的交通网络流量预测与优化
基于PyTorch Geometric的交通网络流量预测与优化 【免费下载链接】pytorch_geometric Graph Neural Network Library for PyTorch 项目地址: https://gitcode.com/GitHub_Trending/py/pytorch_geometric 问题定义:破解城市交通网络的复杂性挑战 交通网络的图…...
