装好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 截图 截屏 获取屏幕相关推荐

  1. ARFoundation入门教程U2-AR场景截图截屏

    ARFoundation入门教程U2-AR场景截图截屏 <ARFoundation入门教程U1-android权限申请和配置升级>配置了android权限申请,获取权限后使用代码截屏,AR ...

  2. iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏)

    iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏) 2017.03.16 12:18* 字数 52 阅读 563评论 4喜欢 2 1. 截取屏幕尺寸大小的图片并保存至相册 ...

  3. 怎么用计算机截图快捷键,电脑怎么截图截屏 电脑截图的快捷键是什么

    电脑怎么截图截屏 电脑截图的快捷键是什么 来源:www.18183.com作者:皮卡时间:2015-10-23 很多人打开电脑的时候就会习惯性的登上各类社交应用,例如QQ.阿里旺旺.微博客户端等,这些 ...

  4. mac录屏快捷键 - mac截图截屏快捷键 - 自带录屏软件QuickTime Player如何使用

    mac截图截屏快捷键 全屏截图 command + shift + 3 (截图文件自动保存到桌面) 区域截图 command + shift + 4  再用鼠标框选截图范围(截图文件自动保存到桌面) ...

  5. 荣耀android手机怎么截图,华为荣耀畅玩5C怎么截图/截屏方法教程

    华为荣耀畅玩5C怎么截图/截屏方法教程 来源:www.18183.com作者:皮卡时间:2016-04-29 作为荣耀今年的首款开年作品,该机受到了很多用户们的关注,而小编也相信有不少花粉们已经入手了 ...

  6. DXGI快速截屏录屏技术

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

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

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

  8. 树莓派(Raspberry Pi)中如何截图截屏(截图)

    树莓派(Raspberry Pi)中截图截屏(截图) 需要使用scrot软件,在Raspberry Pi OS安装过程中,如果你选择的是Raspberry Pi OS with Desktop and ...

  9. 截图截屏小工具Snipaste简单易用

    截图截屏小工具Snipaste简单易用 百度网盘地址:https://pan.baidu.com/s/195T96Al-plXSxXezTdybqg

  10. java实现录屏_java录屏截屏: 用java代码实现的录屏和截图截屏,并在springboot上实现...

    由于习惯了springboot 所以就写在springboot上了,并暴露了一个接口来触发录屏功能 核心代码在fxbase包下的VideoRecorder类中 但是代码写的有点乱,使用者可以不必过度关 ...

最新文章

  1. python怎么读取txt文件并统计其字数-python计算文件的行数和读取某一行内容的实现方法...
  2. 2016.6.17——Remove Duplicates from Sorted Array
  3. curl 请求日志_HTTP入门(一):在Bash中curl查看请求与响应
  4. Excel 自定义关闭按钮
  5. [游戏服务器]第一章:多人聊天室-服务端
  6. DRBD 管理、故障处理部分
  7. 修改才是写作的本质所在
  8. JAVA在线小说电子书阅读系统毕业设计 开题报告
  9. 阴阳师哪个服务器可以用微信登录,网易大神怎么绑定阴阳师QQ微信账号 网易大神绑定阴阳师QQ微信账号方法...
  10. 如何添加Cydia源?如何通过Cydia下载软件?如何卸载软件?
  11. 我从《阿里云:人工智能应用实践与趋势》白皮书学到了什么?
  12. Java基础学习——操作系统批处理(操作系统命令)
  13. 非线性回归-转化为线性回归以及非线性模型-用R语言实现
  14. 移动安全--22--Android应用安全防护技术
  15. python 隐函数绘制_Python隐函数作图
  16. 编程语言“破剑式”——编程语言学什么?
  17. Hive之——Hive和Oozie整合
  18. 8421码(快速的进制转换法)
  19. 串行、并行都是什么?为什么串行可以高速?
  20. 【XSS漏洞-02】XSS靶场介绍(含BlueLotus_XSSReceiver、DVWA、XSS-labs等)

热门文章

  1. matlab画柱状图_附带调色、字体
  2. Android 鼠标键值列表,安卓键盘键值对照表
  3. iOS网络编程---根据URL下载网络文件的方法
  4. 智慧农业:农业物联网实施方案
  5. tailf追踪日志文件
  6. GZH逸佳君:照片杂色太可怕,谁丑谁尴尬:送你超实用PS降噪插件,1秒变高清
  7. 大学计算机基础知识电子版,天津大学计算机基础知识(完整版带答案)
  8. python pip 安装 升级 卸载命令
  9. 京东店铺怎么运营 掌握这些京东运营知识很有必要!
  10. freemarker 数组转字符串_freemarker中的split字符串分割