C++使用Win32GDI DC进行屏幕截图

news/2024/9/20 10:41:27

代码

#include <windows.h>
#include <Psapi.h>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include <dxgi.h>
#include <d3d11.h>
#include <wrl.h>BOOL SaveBitmapToFile(HBITMAP hBitmap, LPCTSTR filename)
{BITMAP bmp;GetObject(hBitmap, sizeof(BITMAP), &bmp);DWORD dwBmpSize = ((bmp.bmWidth * bmp.bmBitsPixel + 31) / 32) * 4 * bmp.bmHeight;HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);char *lpbitmap = (char *)GlobalLock(hDIB);BITMAPINFOHEADER bi;bi.biSize = sizeof(BITMAPINFOHEADER);bi.biWidth = bmp.bmWidth;bi.biHeight = bmp.bmHeight;bi.biPlanes = 1;bi.biBitCount = 24;bi.biCompression = BI_RGB;bi.biSizeImage = 0;bi.biXPelsPerMeter = 0;bi.biYPelsPerMeter = 0;bi.biClrImportant = 0;bi.biClrUsed = 0;// 获取位图数据GetDIBits(GetDC(NULL), hBitmap, 0, (UINT)bmp.bmHeight, lpbitmap, (BITMAPINFO *)&bi, DIB_RGB_COLORS);// 创建文件并写入数据HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);DWORD dwWritten;BITMAPFILEHEADER bfh;bfh.bfType = 0x4D42; // BMbfh.bfSize = sizeof(BITMAPFILEHEADER) + dwBmpSize;bfh.bfReserved1 = 0;bfh.bfReserved2 = 0;bfh.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);WriteFile(hf, (LPSTR)&bfh, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);WriteFile(hf, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwWritten, NULL);WriteFile(hf, lpbitmap, dwBmpSize, &dwWritten, NULL);// 清理GlobalUnlock(hDIB);GlobalFree(hDIB);CloseHandle(hf);return TRUE;
}bool CaptureScreen(const wchar_t *filePath)
{// 获取屏幕宽高int width = GetSystemMetrics(SM_CXSCREEN);int height = GetSystemMetrics(SM_CYSCREEN);// 创建屏幕DCHDC hScreenDC = GetDC(NULL);if (!hScreenDC){std::cerr << "Failed to get screen DC" << std::endl;return 1;}// 创建一个与屏幕DC兼容的内存DCHDC hMemoryDC = CreateCompatibleDC(hScreenDC);if (!hMemoryDC){std::cerr << "Failed to create memory DC" << std::endl;ReleaseDC(NULL, hScreenDC);return 1;}// 创建一个与屏幕兼容的位图HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);if (!hBitmap){std::cerr << "Failed to create bitmap" << std::endl;DeleteDC(hMemoryDC);ReleaseDC(NULL, hScreenDC);return 1;}// 将位图选入内存DCHGDIOBJ old_obj = SelectObject(hMemoryDC, hBitmap);// 捕获屏幕到内存DCif (!BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY)){std::cerr << "Failed to capture screen" << std::endl;SelectObject(hMemoryDC, old_obj);DeleteObject(hBitmap);DeleteDC(hMemoryDC);ReleaseDC(NULL, hScreenDC);return 1;}// 保存位图if (!SaveBitmapToFile(hBitmap, filePath)){std::cerr << "Failed to save bitmap" << std::endl;}// 清理资源SelectObject(hMemoryDC, old_obj);DeleteObject(hBitmap);DeleteDC(hMemoryDC);ReleaseDC(NULL, hScreenDC);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/62449.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

设计原理图:417-基于XCVU9P+ C6678的8T8R的无线MIMO平台

基于XCVU9P+ C6678的8T8R的无线MIMO平台 一、板卡概述 北京太速科技板卡基于TI TMS320C6678 DSP和XCVU9P高性能FPGA,FPGA接入4片AD9361 无线射频,构建8输入8输出的无线MIMO平台,丰富的FPGA资源和8核DSP为算法验证和信号处理提供强大能力。二、技术指标 ● 板卡为自定义结构…

“模”力十足!天翼云息壤一体化智算服务平台训推服务能力重磅升级!

9月4日,“天翼云息壤——大模型训推一体化服务能力升级”线上发布会成功举办。会上,息壤平台训推服务能力重磅升级,新增闭源、多模态基座大模型以及数据集,支持万卡规模训练,训练稳定性再次提升,新增体验空间,为基础大模型训练、行业大模型训推提供一站式解决方案。9月4…

全国省市县区的JOSN

[{"name": "北京市","code": "110000","city": [{"name": "市辖区","code": "110100","area": [{"name": "东城区","code": "11010…

关于api接口详解大全

API接口,即应用程序编程接口(Application Programming Interface),是一组预定义的函数或协议,它允许不同的软件应用程序之间进行交互。API在现代软件开发中扮演着至关重要的角色,它促进了不同系统之间的集成和通信,为开发者提供了强大的工具来构建更加高效、安全和创新的…

Amazon Bedrock 模型微调实践(二):数据准备篇

本博客内容翻译自作者于 2024 年 9 月在亚马逊云科技开发者社区发表的同名博客: “Mastering Amazon Bedrock Custom Models Fine-tuning (Part 2): Data Preparation for Fine-tuning”亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技…

Spark(一)概述

基本概念Spark是一种基于内存的快速、通用、可扩展的大数据分析计算引擎Spark vs HadoopSpark和Hadoop的根本差异是多个作业之间的数据通信问题:Spark多个作业之间数据通信是基于内存,而Hadoop是基于磁盘Hadoop Spark类型 分布式基础平台, 包含计算, 存储, 调度 分布式计算工…

基于语义增强的少样本检测,突破新类别偏见 | ICIP24

Few-shot目标检测(FSOD)旨在在有限标注实例的情况下检测新颖对象,在近年取得了显著进展。然而,现有方法仍然存在偏见表示问题,特别是在极低标注情况下的新颖类别。在微调过程中,一种新颖类别可能会利用来自相似基础类别的知识来构建自己的特征分布,导致分类混淆和性能下…

如何解决Warning: include(): Failed opening file_path for inclusion问题

解决方法检查文件路径确认文件路径是否正确无误,包括路径中的每个目录和文件名。验证文件是否存在使用file_exists()函数检查文件是否真的存在于指定路径上。检查文件权限确认文件具有足够的权限供当前用户读取。可以使用chmod命令修改文件权限:bashchmod 644 file_path确认文…