关于 DXGI 截图 截屏 获取屏幕
装好DX11 SDK,直接用,完事。
#include <d3d11.h>
#include <dxgi1_2.h>
class VideoDXGICaptor
{
public:
VideoDXGICaptor();
~VideoDXGICaptor();
public:
BOOL Init();
VOID Deinit();
public:
virtual BOOL CaptureImage(RECT &rect, void *pData, INT &nLen);
virtual BOOL CaptureImage(void *pData, INT &nLen);
virtual BOOL ResetDevice();
private:
BOOL AttatchToThread(VOID);
BOOL QueryFrame(void *pImgData, INT &nImgSize);
BOOL QueryFrame(void *pImgData, INT &nImgSize, int z);
private:
IDXGIResource *zhDesktopResource;
DXGI_OUTDUPL_FRAME_INFO zFrameInfo;
ID3D11Texture2D *zhAcquiredDesktopImage;
IDXGISurface *zhStagingSurf;
private:
BOOL m_bInit;
int m_iWidth, m_iHeight;
ID3D11Device *m_hDevice;
ID3D11DeviceContext *m_hContext;
IDXGIOutputDuplication *m_hDeskDupl;
DXGI_OUTPUT_DESC m_dxgiOutDesc;
};
#include "stdafx.h"
#include "DXGICaptor.h"
#include <windows.h>
#include <gdiplus.h>
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "dxgi.lib")
#define RESET_OBJECT(obj) { if(obj) obj->Release(); obj = NULL; }
static BOOL g_bAttach = FALSE;
VideoDXGICaptor::VideoDXGICaptor()
{
m_bInit = FALSE;
m_hDevice = NULL;
m_hContext = NULL;
m_hDeskDupl = NULL;
ZeroMemory(&m_dxgiOutDesc, sizeof(m_dxgiOutDesc));
}
VideoDXGICaptor::~VideoDXGICaptor()
{
Deinit();
}
BOOL VideoDXGICaptor::Init()
{
HRESULT hr = S_OK;
if (m_bInit)
{
return FALSE;
}
// 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;
//
// Create D3D device
//
for (UINT DriverTypeIndex = 0; DriverTypeIndex < NumDriverTypes; ++DriverTypeIndex)
{
hr = D3D11CreateDevice(NULL, DriverTypes[DriverTypeIndex], NULL, 0, FeatureLevels, NumFeatureLevels, D3D11_SDK_VERSION, &m_hDevice, &FeatureLevel, &m_hContext);
if (SUCCEEDED(hr))
{
break;
}
}
if (FAILED(hr))
{
return FALSE;
}
//
// Get DXGI device
//
IDXGIDevice *hDxgiDevice = NULL;
hr = m_hDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&hDxgiDevice));
if (FAILED(hr))
{
return FALSE;
}
//
// Get DXGI adapter
//
IDXGIAdapter *hDxgiAdapter = NULL;
hr = hDxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&hDxgiAdapter));
RESET_OBJECT(hDxgiDevice);
if (FAILED(hr))
{
return FALSE;
}
//
// Get output
//
INT nOutput = 0;
IDXGIOutput *hDxgiOutput = NULL;
hr = hDxgiAdapter->EnumOutputs(nOutput, &hDxgiOutput);
RESET_OBJECT(hDxgiAdapter);
if (FAILED(hr))
{
return FALSE;
}
//
// get output description struct
//
hDxgiOutput->GetDesc(&m_dxgiOutDesc);
//
// QI for Output 1
//
IDXGIOutput1 *hDxgiOutput1 = NULL;
hr = hDxgiOutput->QueryInterface(__uuidof(hDxgiOutput1), reinterpret_cast<void**>(&hDxgiOutput1));
RESET_OBJECT(hDxgiOutput);
if (FAILED(hr))
{
return FALSE;
}
//
// Create desktop duplication
//
hr = hDxgiOutput1->DuplicateOutput(m_hDevice, &m_hDeskDupl);
RESET_OBJECT(hDxgiOutput1);
if (FAILED(hr))
{
return FALSE;
}
// 初始化成功
m_bInit = TRUE;
return TRUE;
// #else
// 小于vs2012,此功能不能实现
return FALSE;
// #endif
}
VOID VideoDXGICaptor::Deinit()
{
if (!m_bInit)
{
return;
}
m_bInit = FALSE;
if (m_hDeskDupl)
{
m_hDeskDupl->Release();
m_hDeskDupl = NULL;
}
if (m_hDevice)
{
m_hDevice->Release();
m_hDevice = NULL;
}
if (m_hContext)
{
m_hContext->Release();
m_hContext = NULL;
}
// #endif
}
BOOL VideoDXGICaptor::AttatchToThread(VOID)
{
if (g_bAttach)
{
return TRUE;
}
HDESK hCurrentDesktop = OpenInputDesktop(0, FALSE, GENERIC_ALL);
if (!hCurrentDesktop)
{
return FALSE;
}
// Attach desktop to this thread
BOOL bDesktopAttached = SetThreadDesktop(hCurrentDesktop);
CloseDesktop(hCurrentDesktop);
hCurrentDesktop = NULL;
g_bAttach = TRUE;
return bDesktopAttached;
}
BOOL VideoDXGICaptor::CaptureImage(RECT &rect, void *pData, INT &nLen)
{
return QueryFrame(pData, nLen);
}
BOOL VideoDXGICaptor::CaptureImage(void *pData, INT &nLen)
{
return QueryFrame(pData, nLen);
}
BOOL VideoDXGICaptor::ResetDevice()
{
Deinit();
return Init();
}
BOOL VideoDXGICaptor::QueryFrame(void *pImgData, INT &nImgSize)
{
if (!m_bInit || !AttatchToThread())
{
return FALSE;
}
nImgSize = 0;
IDXGIResource *hDesktopResource = NULL;
DXGI_OUTDUPL_FRAME_INFO FrameInfo;
HRESULT hr = m_hDeskDupl->AcquireNextFrame(0, &FrameInfo, &hDesktopResource);
if (FAILED(hr))
{
//
// 在一些win10的系统上,如果桌面没有变化的情况下,;
// 这里会发生超时现象,但是这并不是发生了错误,而是系统优化了刷新动作导致的。;
// 所以,这里没必要返回FALSE,返回不带任何数据的TRUE即可;
//
return TRUE;
}
//
// query next frame staging buffer
//
ID3D11Texture2D *hAcquiredDesktopImage = NULL;
hr = hDesktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&hAcquiredDesktopImage));
RESET_OBJECT(hDesktopResource);
if (FAILED(hr))
{
return FALSE;
}
//
// copy old description
//
D3D11_TEXTURE2D_DESC frameDescriptor;
hAcquiredDesktopImage->GetDesc(&frameDescriptor);
//
// create a new staging buffer for fill frame image
//
ID3D11Texture2D *hNewDesktopImage = NULL;
frameDescriptor.Usage = D3D11_USAGE_STAGING;
frameDescriptor.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
frameDescriptor.BindFlags = 0;
frameDescriptor.MiscFlags = 0;
frameDescriptor.MipLevels = 1;
frameDescriptor.ArraySize = 1;
frameDescriptor.SampleDesc.Count = 1;
hr = m_hDevice->CreateTexture2D(&frameDescriptor, NULL, &hNewDesktopImage);
if (FAILED(hr))
{
RESET_OBJECT(hAcquiredDesktopImage);
m_hDeskDupl->ReleaseFrame();
return FALSE;
}
//
// copy next staging buffer to new staging buffer
//
m_hContext->CopyResource(hNewDesktopImage, hAcquiredDesktopImage);
RESET_OBJECT(hAcquiredDesktopImage);
m_hDeskDupl->ReleaseFrame();
//
// create staging buffer for map bits
//
IDXGISurface *hStagingSurf = NULL;
hr = hNewDesktopImage->QueryInterface(__uuidof(IDXGISurface), (void **)(&hStagingSurf));
RESET_OBJECT(hNewDesktopImage);
if (FAILED(hr))
{
return FALSE;
}
//
// copy bits to user space
//
DXGI_MAPPED_RECT mappedRect;
hr = hStagingSurf->Map(&mappedRect, DXGI_MAP_READ);
if (SUCCEEDED(hr))
{
// nImgSize = GetWidth() * GetHeight() * 3;
// PrepareBGR24From32(mappedRect.pBits, (BYTE*)pImgData, m_dxgiOutDesc.DesktopCoordinates);
// mappedRect.pBits;
// am_dxgiOutDesc.DesktopCoordinates;
memcpy((BYTE*)pImgData, mappedRect.pBits, m_dxgiOutDesc.DesktopCoordinates.right * m_dxgiOutDesc.DesktopCoordinates.bottom * 4);
hStagingSurf->Unmap();
}
RESET_OBJECT(hStagingSurf);
return SUCCEEDED(hr);
}
关于 DXGI 截图 截屏 获取屏幕相关推荐
- ARFoundation入门教程U2-AR场景截图截屏
ARFoundation入门教程U2-AR场景截图截屏 <ARFoundation入门教程U1-android权限申请和配置升级>配置了android权限申请,获取权限后使用代码截屏,AR ...
- iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏)
iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏) 2017.03.16 12:18* 字数 52 阅读 563评论 4喜欢 2 1. 截取屏幕尺寸大小的图片并保存至相册 ...
- 怎么用计算机截图快捷键,电脑怎么截图截屏 电脑截图的快捷键是什么
电脑怎么截图截屏 电脑截图的快捷键是什么 来源:www.18183.com作者:皮卡时间:2015-10-23 很多人打开电脑的时候就会习惯性的登上各类社交应用,例如QQ.阿里旺旺.微博客户端等,这些 ...
- mac录屏快捷键 - mac截图截屏快捷键 - 自带录屏软件QuickTime Player如何使用
mac截图截屏快捷键 全屏截图 command + shift + 3 (截图文件自动保存到桌面) 区域截图 command + shift + 4 再用鼠标框选截图范围(截图文件自动保存到桌面) ...
- 荣耀android手机怎么截图,华为荣耀畅玩5C怎么截图/截屏方法教程
华为荣耀畅玩5C怎么截图/截屏方法教程 来源:www.18183.com作者:皮卡时间:2016-04-29 作为荣耀今年的首款开年作品,该机受到了很多用户们的关注,而小编也相信有不少花粉们已经入手了 ...
- DXGI快速截屏录屏技术
DXGI快速截屏录屏技术 概述 很多地方都需要用到截屏/录屏技术,比如桌面直播,桌面录制等等.在微软Windows平台,有很多截屏的接口,不过大多数性能并不理想,Windows8以后微软引入了一套 ...
- DXGI快速截屏录屏技术,高帧率直播桌面
DXGI快速截屏录屏技术 概述 很多地方都需要用到截屏/录屏技术,比如桌面直播,桌面录制等等.在微软Windows平台,有很多截屏的接口,不过大多数性能并不理想,Windows8以后微软引入了一套 ...
- 树莓派(Raspberry Pi)中如何截图截屏(截图)
树莓派(Raspberry Pi)中截图截屏(截图) 需要使用scrot软件,在Raspberry Pi OS安装过程中,如果你选择的是Raspberry Pi OS with Desktop and ...
- 截图截屏小工具Snipaste简单易用
截图截屏小工具Snipaste简单易用 百度网盘地址:https://pan.baidu.com/s/195T96Al-plXSxXezTdybqg
- java实现录屏_java录屏截屏: 用java代码实现的录屏和截图截屏,并在springboot上实现...
由于习惯了springboot 所以就写在springboot上了,并暴露了一个接口来触发录屏功能 核心代码在fxbase包下的VideoRecorder类中 但是代码写的有点乱,使用者可以不必过度关 ...
最新文章
- python怎么读取txt文件并统计其字数-python计算文件的行数和读取某一行内容的实现方法...
- 2016.6.17——Remove Duplicates from Sorted Array
- curl 请求日志_HTTP入门(一):在Bash中curl查看请求与响应
- Excel 自定义关闭按钮
- [游戏服务器]第一章:多人聊天室-服务端
- DRBD 管理、故障处理部分
- 修改才是写作的本质所在
- JAVA在线小说电子书阅读系统毕业设计 开题报告
- 阴阳师哪个服务器可以用微信登录,网易大神怎么绑定阴阳师QQ微信账号 网易大神绑定阴阳师QQ微信账号方法...
- 如何添加Cydia源?如何通过Cydia下载软件?如何卸载软件?
- 我从《阿里云:人工智能应用实践与趋势》白皮书学到了什么?
- Java基础学习——操作系统批处理(操作系统命令)
- 非线性回归-转化为线性回归以及非线性模型-用R语言实现
- 移动安全--22--Android应用安全防护技术
- python 隐函数绘制_Python隐函数作图
- 编程语言“破剑式”——编程语言学什么?
- Hive之——Hive和Oozie整合
- 8421码(快速的进制转换法)
- 串行、并行都是什么?为什么串行可以高速?
- 【XSS漏洞-02】XSS靶场介绍(含BlueLotus_XSSReceiver、DVWA、XSS-labs等)