C++ 怎么截取当前屏幕全屏图像或指定窗口画面并保存为 PNG 或 BMP 压缩文件

秋瑶君_7897

秋瑶君_7897

2026-10-25

401人浏览

原创

windows平台用bitblt+gdiplus截全屏最稳方式是调用getdc(null)获取屏幕dc,绑定createcompatiblebitmap位图后bitblt拷贝,需gdiplusstartup初始化、动态获取png编码器clsid,并配对释放gdi资源。

c++ 怎么截取当前屏幕全屏图像或指定窗口画面并保存为 png 或 bmp 压缩文件

Windows 平台用 BitBlt + Gdiplus 截全屏最稳

直接调 Windows GDI 是目前 C++ 全屏截图最轻量、兼容性最好的方式,不依赖第三方库,Win7 及以上原生支持。关键不是“能不能”,而是BitBlt 的源设备上下文(HDC)必须来自屏幕,且目标 HDC 要绑定到兼容位图(CreateCompatibleBitmap),否则截出来是黑图或乱码。

常见错误:GetDC(NULL) 拿到的是整个屏幕 DC,但若没调 SelectObject 把位图选入目标 DC,BitBlt 实际没写入任何像素;还有人漏掉 GdiplusStartup,导致 Gdiplus::Bitmap::Save 直接崩溃。

  • 必须先调 Gdiplus::GdiplusStartup,否则 PNG/BMP 保存失败,报错 GenericError
  • BitBlt 的 dwRop 参数固定用 SRCCOPY,别用 NOTSRCCOPY 等非常规值
  • 全屏宽高要用 GetSystemMetrics(SM_CXSCREEN) 和 GetSystemMetrics(SM_CYSCREEN),别硬写 1920×1080

抓指定窗口画面得用 GetWindowDC 而非 GetDC

GetDC(hwnd) 只能取客户区(Client Area),标题栏、边框、阴影全丢;要完整窗口画面(含非客户区),必须用 GetWindowDC(hwnd),并确保窗口未最小化(IsIconic(hwnd) 返回 false)。

容易踩的坑:GetWindowRect 返回的是屏幕坐标,但 BitBlt 的目标矩形是相对于目标位图左上角的,所以宽高直接用 rect.right - rect.left 即可,无需平移坐标。

  • 调 GetWindowRect(hwnd, &rect) 后,位图尺寸就是 rect.right - rect.left × rect.bottom - rect.top
  • 如果窗口被其他窗口遮挡,BitBlt 仍能捕获其原始画面(GDI 层面未裁剪),这是预期行为
  • 对无窗口句柄的 UWP 应用(如 Microsoft Store 版 Edge),此法无效,需换用 Desktop Duplication API

保存为 PNG 时注意 CLSID 初始化和压缩质量

C++ 里 Gdiplus::Bitmap::Save 不支持直接设 PNG 压缩级别——PNG 本身无损,所谓“压缩”实为滤波器选择和 zlib 级别,GDI+ 封装里不暴露该控制权。你只能靠 CLSID 区分格式,而 PNG 的 CLSID 必须从 Gdiplus::GetEncoderClsid(L"image/png", &clsid) 动态获取,硬编码会失败。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

BMP 则简单得多:L"image/bmp" 对应的 CLSID 可静态定义,且无压缩参数,文件体积大但 100% 兼容。

  • PNG 保存失败常见报错:InvalidParameter → 多半是 GetEncoderClsid 返回 -1,检查传入的 MIME 字符串是否带空格或大小写错误
  • 想减小 PNG 体积?只能靠后期用 libpng 或 ImageMagick 二次压缩,GDI+ 不提供接口
  • 路径含中文时,务必用 wchar_t* 和 Save(L"out.png", &clsid),传 char* 会乱码或静默失败

跨 DPI 缩放场景下截图内容会被拉伸或裁剪

在高 DPI 显示器(如 150% 缩放)上,GetSystemMetrics(SM_CXSCREEN) 返回的是逻辑像素,而 BitBlt 操作的是物理像素。若程序未声明 DPI 感知(manifest 中缺 dpiAware=true),系统会自动缩放 DC,导致截图模糊或只有一半画面。

解决方案只有两个:要么在 manifest 加 <dpiaware>true</dpiaware>,要么改用 GetDpiForSystem() + GetSystemMetricsForDpi(Win10 1703+)动态算物理尺寸。

  • 没加 DPI 感知时,GetSystemMetrics(SM_CXSCREEN) 可能返回 1280(逻辑宽),但实际屏幕物理宽是 1920 —— 这就是截图缺右边的原因
  • 使用 GetDC(NULL) 前,先调 SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)(需 Win8.1+)比改 manifest 更灵活
  • Qt 或 wxWidgets 等框架封装了 DPI 适配,纯 Win32 API 必须自己扛

实际代码里最易出问题的是 GDI 对象泄漏:ReleaseDC、DeleteDC、DeleteObject 必须严格配对,少一次就内存缓慢增长。这事没法靠 RAII 自动兜底,得手写 wrapper 或用 ATL 的 CDCHandle。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2248

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1039

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

447

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

327

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

426

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

600

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1429

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1237

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ 手册教程
C++ 手册教程

共41课时 | 78.4万人学习

C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习