/**
* @author wh445306
* @version 1.0
* @Description C++ Dxgi截屏并保存为rgb格式和bmp格式完整示例代码
* @Date 2022-09-25 20:46
*/#include <d3d11.h>
#include <dxgi1_2.h>
#include <stdio.h>#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "dxgi.lib")#pragma warning(disable:4996)// 将RGB格式图片转成bmp格式
void RGBDataSaveAsBmpFile(const char * bmpFile,                // BMP文件名称unsigned char * pRgbData,            // 图像数据int width,                           // 图像宽度  int height,                          // 图像高度int biBitCount,                      // 位图深度bool flipvertical)                   // 图像是否需要垂直翻转
{int size = 0;int bitsPerPixel = 3;if (biBitCount == 24){bitsPerPixel = 3;size = width * height * bitsPerPixel * sizeof(char); // 每个像素点3个字节}else if (biBitCount == 32){bitsPerPixel = 4;size = width * height * bitsPerPixel * sizeof(char); // 每个像素点4个字节}else return;// 位图第一部分,文件信息  BITMAPFILEHEADER bfh;bfh.bfType = (WORD)0x4d42;  //图像格式 必须为'BM'格式bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//真正的数据的位置bfh.bfSize = size + bfh.bfOffBits;bfh.bfReserved1 = 0;bfh.bfReserved2 = 0;BITMAPINFOHEADER bih;bih.biSize = sizeof(BITMAPINFOHEADER);bih.biWidth = width;if (flipvertical)bih.biHeight = -height;//BMP图片从最后一个点开始扫描,显示时图片是倒着的,所以用-height,这样图片就正了  elsebih.biHeight = height;bih.biPlanes = 1;bih.biBitCount = biBitCount;bih.biCompression = BI_RGB;bih.biSizeImage = size;bih.biXPelsPerMeter = 0;bih.biYPelsPerMeter = 0;bih.biClrUsed = 0;bih.biClrImportant = 0;FILE * fp = NULL;fopen_s(&fp, bmpFile, "wb");if (!fp)return;fwrite(&bfh, 8, 1, fp);fwrite(&bfh.bfReserved2, sizeof(bfh.bfReserved2), 1, fp);fwrite(&bfh.bfOffBits, sizeof(bfh.bfOffBits), 1, fp);fwrite(&bih, sizeof(BITMAPINFOHEADER), 1, fp);fwrite(pRgbData, size, 1, fp);fclose(fp);
}int main()
{HRESULT hr;// Driver types supported 支持的驱动程序类型D3D_DRIVER_TYPE DriverTypes[] ={D3D_DRIVER_TYPE_HARDWARE,D3D_DRIVER_TYPE_WARP,D3D_DRIVER_TYPE_REFERENCE,};UINT NumDriverTypes = ARRAYSIZE(DriverTypes);// Feature levels supported 支持的功能级别D3D_FEATURE_LEVEL FeatureLevels[] ={D3D_FEATURE_LEVEL_11_0,D3D_FEATURE_LEVEL_10_1,D3D_FEATURE_LEVEL_10_0,D3D_FEATURE_LEVEL_9_1};UINT NumFeatureLevels = ARRAYSIZE(FeatureLevels);D3D_FEATURE_LEVEL FeatureLevel;ID3D11Device *_pDX11Dev = nullptr;ID3D11DeviceContext *_pDX11DevCtx = nullptr;// Create D3D device 创建D3D设备for (UINT index = 0; index < NumDriverTypes; index++){hr = D3D11CreateDevice(nullptr,DriverTypes[index],nullptr, 0,FeatureLevels,NumFeatureLevels,D3D11_SDK_VERSION,&_pDX11Dev,&FeatureLevel,&_pDX11DevCtx);if (SUCCEEDED(hr)) {break;}}IDXGIDevice *_pDXGIDev = nullptr;// Get DXGI device 获取 DXGI 设备hr = _pDX11Dev->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&_pDXGIDev));if (FAILED(hr)) {return false;}IDXGIAdapter *_pDXGIAdapter = nullptr;// Get DXGI adapter 获取 DXGI 适配器hr = _pDXGIDev->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&_pDXGIAdapter));if (FAILED(hr)) {return false;}UINT i = 0;IDXGIOutput *_pDXGIOutput = nullptr;// Get output 获取输出hr = _pDXGIAdapter->EnumOutputs(i, &_pDXGIOutput);if (FAILED(hr)) {return false;}DXGI_OUTPUT_DESC DesktopDesc;// Get output description struct 获取输出描述结构_pDXGIOutput->GetDesc(&DesktopDesc);IDXGIOutput1 *_pDXGIOutput1 = nullptr;// QI for Output1 请求接口给Output1hr = _pDXGIOutput->QueryInterface(__uuidof(IDXGIOutput1), reinterpret_cast<void**>(&_pDXGIOutput1));if (FAILED(hr)) {return false;}IDXGIOutputDuplication *_pDXGIOutputDup = nullptr;// Create desktop duplication 创建桌面副本hr = _pDXGIOutput1->DuplicateOutput(_pDX11Dev, &_pDXGIOutputDup);if (FAILED(hr)) {return false;}for (int i = 0; i < 3; i++){IDXGIResource *desktopResource = nullptr;DXGI_OUTDUPL_FRAME_INFO frameInfo;hr = _pDXGIOutputDup->AcquireNextFrame(20, &frameInfo, &desktopResource);if (FAILED(hr)){if (hr == DXGI_ERROR_WAIT_TIMEOUT){if (desktopResource) {desktopResource->Release();desktopResource = nullptr;}hr = _pDXGIOutputDup->ReleaseFrame();}else{return false;}}ID3D11Texture2D *_pDX11Texture = nullptr;// query next frame staging buffer 查询下一帧暂存缓冲区hr = desktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&_pDX11Texture));desktopResource->Release();desktopResource = nullptr;if (FAILED(hr)) {return false;}ID3D11Texture2D *_pCopyBuffer = nullptr;D3D11_TEXTURE2D_DESC desc;// copy old description 复制旧描述if (_pDX11Texture){_pDX11Texture->GetDesc(&desc);}else if (_pCopyBuffer){_pCopyBuffer->GetDesc(&desc);}else{return false;}// create a new staging buffer for fill frame image 为填充帧图像创建一个新的暂存缓冲区if (_pCopyBuffer == nullptr) {D3D11_TEXTURE2D_DESC CopyBufferDesc;CopyBufferDesc.Width = desc.Width;CopyBufferDesc.Height = desc.Height;CopyBufferDesc.MipLevels = 1;CopyBufferDesc.ArraySize = 1;CopyBufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;CopyBufferDesc.SampleDesc.Count = 1;CopyBufferDesc.SampleDesc.Quality = 0;CopyBufferDesc.Usage = D3D11_USAGE_STAGING;CopyBufferDesc.BindFlags = 0;CopyBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;CopyBufferDesc.MiscFlags = 0;hr = _pDX11Dev->CreateTexture2D(&CopyBufferDesc, nullptr, &_pCopyBuffer);if (FAILED(hr)) {return false;}}if (_pDX11Texture){// copy next staging buffer to new staging buffer 将下一个暂存缓冲区复制到新的暂存缓冲区_pDX11DevCtx->CopyResource(_pCopyBuffer, _pDX11Texture);}IDXGISurface *CopySurface = nullptr;// create staging buffer for map bits 为映射位创建暂存缓冲区hr = _pCopyBuffer->QueryInterface(__uuidof(IDXGISurface), (void **)&CopySurface);if (FAILED(hr)) {return false;}DXGI_MAPPED_RECT MappedSurface;// copy bits to user space 将位复制到用户空间hr = CopySurface->Map(&MappedSurface, DXGI_MAP_READ);char picName[128] = { 0 };snprintf(picName, sizeof(picName), "Screen%d.rgb", i);FILE *p = fopen(picName, "wb");if (SUCCEEDED(hr)){for (int i = 0; i < 1080; ++i){fwrite(MappedSurface.pBits + i * MappedSurface.Pitch, 1, MappedSurface.Pitch, p);}CopySurface->Unmap();}fclose(p);//保存为bmp格式char picNameB[128] = { 0 };snprintf(picNameB, sizeof(picNameB), "Screen%d.bmp", i);RGBDataSaveAsBmpFile(picNameB, MappedSurface.pBits, 1920, 1080, 32, true);CopySurface->Unmap();hr = CopySurface->Release();CopySurface = nullptr;if (_pDXGIOutputDup){hr = _pDXGIOutputDup->ReleaseFrame();}//Sleep(1000);}return 0;
}

效果如下:

C++ Dxgi快速截屏并保存为rgb格式和bmp格式完整示例代码相关推荐

  1. DXGI快速截屏录屏技术

    DXGI快速截屏录屏技术 概述   很多地方都需要用到截屏/录屏技术,比如桌面直播,桌面录制等等.在微软Windows平台,有很多截屏的接口,不过大多数性能并不理想,Windows8以后微软引入了一套 ...

  2. DXGI快速截屏录屏技术,高帧率直播桌面

    DXGI快速截屏录屏技术 概述   很多地方都需要用到截屏/录屏技术,比如桌面直播,桌面录制等等.在微软Windows平台,有很多截屏的接口,不过大多数性能并不理想,Windows8以后微软引入了一套 ...

  3. windows10系统怎么快速截屏

    在 Windows 10 系统中,你可以使用几种方法来快速截屏: 使用快捷键:按下 Windows 键 + PrtScn 键.这样会将当前屏幕截图保存到电脑的"我的文档/我的图片/我的屏幕截 ...

  4. 电脑自带快速截屏工具

    电脑自带快速截屏工具 一般使用截图工具部分同学都会使用QQ自带的截图快捷键"Ctrl+alt+a",或者使用FSCapture7.5截图软件,但是在没有登录QQ,或者没有打开截图软 ...

  5. 使用Snagit安安静静的截屏并保存

    使用Snagit软件安安静静的截屏并保存需要注意两点. 1.关闭在编辑器预览. 2.打开分享--文件. 图片.png 设置好之后保存预设.并设置快捷键.这样在工作或者网游戏过程中就可以快速的截屏并保存 ...

  6. swift 将图片保存到本地_Swift实现截屏并保存相册

    func saveToLocal() { //截屏 let screenRect = UIScreen.mainScreen().bounds UIGraphicsBeginImageContext( ...

  7. 【java-调用摄像头进行截屏与保存-实例篇1-0716】

    java-调用摄像头进行截屏与保存-实例篇1-0716 一. 主要涉及功能 二. 主要涉及技术 三. 开启摄像的Webcam包导入IDEA 四.多线程入门 4.1为什么用线程 4.2 如何打开一个新的 ...

  8. python全局键盘监听(pynput快捷键);利用pywin32快速截屏并生成视频

    python全局键盘监听(pynput快捷键):利用pywin32快速截屏并生成视频 第一次在CSDN写博客,有点小紧张(/ω\) 以下内容完全个人理解,有错误请指出~ 最近在用python做一个小工 ...

  9. 使用html2canvas完成页面截屏并保存为图片

    实现网页页面截屏,并且将其转换为指定图片格式保存下来,需要使用到html2canvas.js. 前面是实现原理和步骤分析,具体实现代码在文章尾部. 一.实现HTML页面截屏并保存为图片 原理是遍历需要 ...

  10. Unity iOS 获取相册图片, 调用原生相机, 截屏并保存到相册

    原文链接 该Demo实现如下功能 1.从相册_照片 获取图片, 并贴在Image上 2.从相册_时刻 获取照片, 并贴在Image上 3.打开原生相机,拍照并把照片贴在Image上 4.截屏并保存到相 ...

最新文章

  1. UVa1491 - Compress the String(dfs)
  2. struts2中一些常用的写法 记录
  3. activiti 文档_免费、开源、多平台的PDF文档处理软件——PDFsam Basic
  4. Win10系统如何退出桌面磁贴功能
  5. HDU1755 A Number Puzzle【全排列+暴力】
  6. underscore 系列之内部函数 restArgs
  7. Zabbix实战-简易教程--WEB类--Nginx
  8. matlab中normfit在正态分布中的使用技巧如下:
  9. 西电oj python题目练习
  10. 凯恩帝k1000ti参数设置_凯恩帝KND数控K1000TI系统维修
  11. 渗透测试(445端口)
  12. spring报错→UnexpectedRollbackException: Transaction silently rolled back becaus
  13. 【python 目标检测】基于深度学习的道路破损检测|yolov5|VOC
  14. 初探数据湖(Data Lake),到底有什么用?让我们来一窥究竟...
  15. 怎样用计算机绘制幂函数图像,几何画板如何画幂函数的图像 绘制方法介绍
  16. 使用Pytorch搭建U-Net网络并基于DRIVE数据集训练(语义分割)学习笔记
  17. 第一次软工作业(数独)
  18. 【附源码】计算机毕业设计Python安卓基于安卓的校园跑腿代购476ww(源码+程序+LW+调试部署)
  19. Python:画三角形
  20. Linux差异备份的脚本,linux 差异备份 增量备份

热门文章

  1. HTTP 长连接原理
  2. URPF - 单播逆向路径转发
  3. 全国省市县行政区划SQL代码文件
  4. git创建本地代码库
  5. 热式气体质量流量计检定规程_新品发布:西尼尔ST51/54热式质量流量计
  6. python使用pip卸载和安装库
  7. 用Excel控件做动态图表
  8. 矩阵卷积运算的具体过程
  9. 多商户Saas模式云进销存系统,源码分享
  10. 解析:WMS仓库管理系统是什么,可以提供什么协助