C语言 屏幕截图 (GDI)
截取全屏幕
#include <windows.h>void echo(CHAR *str);int CaptureImage(HWND hWnd, CHAR *dirPath, CHAR *filename);int main(){ echo(TEXT("Ready")); CaptureImage(GetDesktopWindow(), "E:\", "screen"); // 保存为 E:screen.bmp echo(TEXT("end")); return 0;}/** * 调试输出 */void echo(CHAR *str){ MessageBox(NULL, str, NULL, MB_OK);}/** * GDI 截屏函数 * * 参数 hwnd 要截屏的窗口句柄 * 参数 dirPath 截图存放目录 * 参数 filename 截图名称 */int CaptureImage(HWND hwnd, CHAR *dirPath, CHAR *filename){ HANDLE hDIB; HANDLE hFile; DWORD dwBmpSize; DWORD dwSizeofDIB; DWORD dwBytesWritten; CHAR FilePath[MAX_PATH]; HBITMAP hbmScreen = NULL; BITMAP bmpScreen; BITMAPFILEHEADER bmfHeader; BITMAPINFOHEADER bi; CHAR *lpbitmap; INT width = GetSystemMetrics(SM_CXSCREEN); // 屏幕宽 INT height = GetSystemMetrics(SM_CYSCREEN); // 屏幕高 HDC hdcScreen = GetDC(NULL); // 全屏幕DC HDC hdcMemDC = CreateCompatibleDC(hdcScreen); // 创建兼容内存DC if (!hdcMemDC) { echo(TEXT("CreateCompatibleDC has failed")); goto done; } // 通过窗口DC 创建一个兼容位图 hbmScreen = CreateCompatibleBitmap(hdcScreen, width, height); if (!hbmScreen) { echo(TEXT("CreateCompatibleBitmap Failed")); goto done; } // 将位图块传送到我们兼容的内存DC中 SelectObject(hdcMemDC, hbmScreen); if (!BitBlt( hdcMemDC, // 目的DC 0, 0, // 目的DC的 x,y 坐标 width, height, // 目的 DC 的宽高 hdcScreen, // 来源DC 0, 0, // 来源DC的 x,y 坐标 SRCCOPY)) // 粘贴方式 { echo(TEXT("BitBlt has failed")); goto done; } // 获取位图信息并存放在 bmpScreen 中 GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = bmpScreen.bmWidth; bi.biHeight = bmpScreen.bmHeight; bi.biPlanes = 1; bi.biBitCount = 32; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight; // 在 32-bit Windows 系统上, GlobalAlloc 和 LocalAlloc 是由 HeapAlloc 封装来的 // handle 指向进程默认的堆. 所以开销比 HeapAlloc 要大 hDIB = GlobalAlloc(GHND, dwBmpSize); lpbitmap = (char *)GlobalLock(hDIB); // 获取兼容位图的位并且拷贝结果到一个 lpbitmap 中. GetDIBits( hdcScreen, // 设备环境句柄 hbmScreen, // 位图句柄 0, // 指定检索的第一个扫描线 (UINT)bmpScreen.bmHeight, // 指定检索的扫描线数 lpbitmap, // 指向用来检索位图数据的缓冲区的指针 (BITMAPINFO *)&bi, // 该结构体保存位图的数据格式 DIB_RGB_COLORS // 颜色表由红、绿、蓝(RGB)三个直接值构成 ); wsprintf(FilePath, "%s\%s.bmp", dirPath, filename); // 创建一个文件来保存文件截图 hFile = CreateFile( FilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); // 将 图片头(headers)的大小, 加上位图的大小来获得整个文件的大小 dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); // 设置 Offset 偏移至位图的位(bitmap bits)实际开始的地方 bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); // 文件大小 bmfHeader.bfSize = dwSizeofDIB; // 位图的 bfType 必须是字符串 "BM" bmfHeader.bfType = 0x4D42; //BM dwBytesWritten = 0; WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL); WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL); WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL); // 解锁堆内存并释放 GlobalUnlock(hDIB); GlobalFree(hDIB); // 关闭文件句柄 CloseHandle(hFile); // 清理资源done: DeleteObject(hbmScreen); DeleteObject(hdcMemDC); ReleaseDC(NULL, hdcScreen); return 0;}截取指定窗口
#include <windows.h>void echo(CHAR *str);int CaptureImage(HWND hWnd, CHAR *dirPath, CHAR *filename);int main(){ echo("准备截图"); CaptureImage(GetDesktopWindow(), "E:\", "hello"); // 保存为 E:hello.bmp echo("截图结束"); return 0;}/** * 调试输出 */void echo(CHAR *str) { MessageBox(NULL, str, NULL, MB_OK);}/** * GDI 截取指定窗口 * * 参数 hwnd 要截屏的窗口句柄 * 参数 dirPath 截图存放目录 * 参数 filename 截图名称 */int CaptureImage(HWND hwnd, CHAR *dirPath, CHAR *filename){ HDC mdc; HBITMAP hbmp; CHAR FilePath[MAX_PATH]; HDC hdcScreen; HDC hdcWindow; HDC hdcMemDC = NULL; HBITMAP hbmScreen = NULL; BITMAP bmpScreen; RECT rcClient; BITMAPFILEHEADER bmfHeader; BITMAPINFOHEADER bi; DWORD dwBmpSize; HANDLE hDIB; CHAR *lpbitmap; HANDLE hFile; DWORD dwSizeofDIB; DWORD dwBytesWritten; hdcScreen = GetDC(NULL); // 全屏幕DC hdcWindow = GetDC(hwnd); // 截图目标窗口DC // 创建兼容内存DC hdcMemDC = CreateCompatibleDC(hdcWindow); if(!hdcMemDC) { echo(TEXT("CreateCompatibleDC has failed")); goto done; } // 获取客户端区域用于计算大小 GetClientRect(hwnd, &rcClient); // 设置延展模式 SetStretchBltMode(hdcWindow, HALFTONE); // 来源 DC 是整个屏幕而目标 DC 是当前的窗口 (HWND) if(!StretchBlt(hdcWindow, 0,0, rcClient.right, rcClient.bottom, hdcScreen, 0,0, GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN), SRCCOPY)) { echo(TEXT("StretchBlt has failed")); goto done; } // 通过窗口DC 创建一个兼容位图 hbmScreen = CreateCompatibleBitmap( hdcWindow, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top ); if(!hbmScreen) { echo(TEXT("CreateCompatibleBitmap Failed")); goto done; } // 将位图块传送到我们兼容的内存DC中 SelectObject(hdcMemDC,hbmScreen); if(!BitBlt( hdcMemDC, // 目的DC 0,0, // 目的DC的 x,y 坐标 rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, // 目的 DC 的宽高 hdcWindow, // 来源DC 0,0, // 来源DC的 x,y 坐标 SRCCOPY)) // 粘贴方式 { echo(TEXT("BitBlt has failed")); goto done; } // 获取位图信息并存放在 bmpScreen 中 GetObject(hbmScreen,sizeof(BITMAP),&bmpScreen); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = bmpScreen.bmWidth; bi.biHeight = bmpScreen.bmHeight; bi.biPlanes = 1; bi.biBitCount = 32; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight; // 在 32-bit Windows 系统上, GlobalAlloc 和 LocalAlloc 是由 HeapAlloc 封装来的 // handle 指向进程默认的堆. 所以开销比 HeapAlloc 要大 hDIB = GlobalAlloc(GHND,dwBmpSize); lpbitmap = (char *)GlobalLock(hDIB); // 获取兼容位图的位并且拷贝结果到一个 lpbitmap 中. GetDIBits( hdcWindow, // 设备环境句柄 hbmScreen, // 位图句柄 0, // 指定检索的第一个扫描线 (UINT)bmpScreen.bmHeight, // 指定检索的扫描线数 lpbitmap, // 指向用来检索位图数据的缓冲区的指针 (BITMAPINFO *)&bi, // 该结构体保存位图的数据格式 DIB_RGB_COLORS // 颜色表由红、绿、蓝(RGB)三个直接值构成 ); wsprintf(FilePath, "%s\%s.bmp", dirPath, filename); // 创建一个文件来保存文件截图 hFile = CreateFile( FilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); // 将 图片头(headers)的大小, 加上位图的大小来获得整个文件的大小 dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); // 设置 Offset 偏移至位图的位(bitmap bits)实际开始的地方 bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); // 文件大小 bmfHeader.bfSize = dwSizeofDIB; // 位图的 bfType 必须是字符串 "BM" bmfHeader.bfType = 0x4D42; //BM dwBytesWritten = 0; WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL); WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL); WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL); // 解锁堆内存并释放 GlobalUnlock(hDIB); GlobalFree(hDIB); // 关闭文件句柄 CloseHandle(hFile); // 清理资源done: DeleteObject(hbmScreen); DeleteObject(hdcMemDC); ReleaseDC(NULL,hdcScreen); ReleaseDC(hwnd,hdcWindow); return 0;}C语言 屏幕截图 (GDI)的更多相关文章
- 疯狂的图形(利用C# + GDI plus模拟杂乱无章的现实场景)
原文:疯狂的图形(利用C# + GDI plus模拟杂乱无章的现实场景) 本文给出了模拟竹叶.长叶草.杂乱石头.天上繁星等关键代码.使用.Net环境下C#语言,GDI+编写. 模拟竹叶 挺像的吧? ...
- iOS - Harpy版本更新工具兼容版本第三方库
Harpy(兼容版) git地址:https://github.com/yangchao0033/Harpy ###(iOS5-9适配版本,基于ArtSabintsev/Harpy v3.4.5) 提 ...
- 如何在GooglePlay上面发布应用
上传和发布应用 注册开发者帐户后,您便可使用 Google Play 开发者控制台将应用上传到 Google Play. 访问 Google Play 开发者控制台. 点击屏幕顶部附近的添加新用户. ...
- C语言集锦(三)Direct3D和GDI+的例子
0.前言 有些时候你可能想了解,如何用纯C语言来写Direct3D和GDI+的Demo.注意,下面的Direct3D例子不适用于TCC编译器,GDI+的例子是可以的. 1.Direct3D C语言的例 ...
- Windows GDI 窗口与 Direct3D 屏幕截图
前言 Windows 上,屏幕截图一般是调用 win32 api 完成的,如果 C# 想实现截图功能,就需要封装相关 api.在 Windows 上,主要图形接口有 GDI 和 DirectX.GDI ...
- WinForm GDI+ 资料收集
UI(User Interface)编程在整个项目开发过程中是个颇为重要的环节,任何好的解决方案若没有良好的用户界面呈现给最终用户,那么就算包含了最先进的技术也不能算是好程序.UI编程体现在两个方面, ...
- C# WinForm开发系列 - GDI+【转】
http://blog.csdn.net/blue_sky6/article/details/53811435?locationNum=6&fps=1 C# WinForm开发系列 - GDI ...
- 使用Python保存屏幕截图(不使用PIL)
起因 在极客学院讲授<使用Python编写远程控制程序>的课程中,涉及到查看被控制电脑屏幕截图的功能. 如果使用PIL,这个需求只需要三行代码: from PIL import Image ...
- 吉特仓库管理系统- 斑马打印机 ZPL语言的腐朽和神奇
上一篇文章说到了.NET中的打印机,在PrintDocument类也暴露一些本质上上的问题,前面也提到过了,虽然使用PrintDcoument打印很方便.对应条码打印机比如斑马等切刀指令,不依赖打印机 ...
随机推荐
- [ 浙江大学 数据库系统原理 ] [ MiniSQL ]课程设计
工作流程图如下.代码详见https://github.com/gstggsstt/minisql. 注:课程设计时间紧迫,编码基本没有性能考虑,仅限于实现功能,索引未使用B+tree.
- 2016中国银行Top100榜单发布 工行排首位
2016中国银行Top100榜单发布 工行排首位 2016-07-09 15:13:19 第一财经 2016年7月8日,中国银行业协会在京召开“<中国银行业发展报告(2016)>发布会 ...
- Path Sum 深度搜索
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all ...
- 安装 FastAdmin 时忘记 MySQL 密码怎么办?
安装 FastAdmin 时忘记 MySQL 密码怎么办? 给 MySQL 启动时加上 skip-grant-tables 参数,然后随便使用用户名都可以进入 MySQL. 接着就可以使用 命令改了 ...
- sql函数的使用——转换函数
转换函数用于将数据类型从一种转为另外一种,在某些情况下,oracle server允许值的数据类型和实际的不一样,这时oracle server会隐含的转化数据类型,比如: create table ...
- 去除selet标签默认样式
select { /*Chrome和Firefox里面的边框是不一样的,所以复写了一下*/ border: solid 1px #000; /*很关键:将默认的select选择框样式清除*/ appe ...
- 《DL/T 1476-2015 电力安全工器具预防性试验规程》中的样品名称及试验项目
- HDU 5673 Robot【卡特兰数】
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5673 题意: 有一个机器人位于坐标原点上.每秒钟机器人都可以向右移到一个单位距离,或者在原地不动.如 ...
- 模板—LCT
#include<iostream> #include<cstring> #include<cstdio> #define LL long long using n ...
- 《C语言深度解剖》学习笔记之关键字
第一章 关键字 C语言共有32个关键字. 关键字 auto 声明自动变量 int 声明整型变量 long 声明长整型变量 char 声明字符型变量 float 声明浮点型变量 short 声明短整 ...