不会c嘎嘎 2024-09-24 07:59 采纳率: 33.3%
浏览 40
已结题

无法正常使用dxgi截图

img


#include "movement.h"
#include <opencv2/opencv.hpp>
#include <vector>
#include <cstdlib>
#include <algorithm>
#define NOMINMAX
#include <Windows.h>
#include "config.h"
#include "serial_communication.h"
#include <algorithm> // std::min, std::max
#include <limits>
#include <dxgi1_2.h>
#include <d3d11.h>
#include <wrl/client.h>

// 全局变量
float previous_x = 0.0f;
float previous_y = 0.0f;

// 使用 Microsoft::WRL::ComPtr 来管理 DXGI 和 D3D11 对象
using Microsoft::WRL::ComPtr;

cv::Mat capture_screen() {
    // 初始化 D3D11 设备和 DXGI 工厂
    ComPtr<ID3D11Device> device;
    ComPtr<ID3D11DeviceContext> context;
    ComPtr<IDXGIFactory1> factory;
    ComPtr<IDXGIAdapter1> adapter;
    ComPtr<IDXGIOutput> output;
    ComPtr<IDXGIOutput1> output1;
    ComPtr<IDXGIOutputDuplication> duplication;
    ComPtr<IDXGIResource> desktopResource;
    ComPtr<ID3D11Texture2D> acquiredDesktopImage;

    // 创建 D3D11 设备
    D3D_FEATURE_LEVEL featureLevel;
    HRESULT hr = D3D11CreateDevice(NULL, D3D11_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &device, &featureLevel, &context);
    if (FAILED(hr)) {
        std::cerr << "D3D11CreateDevice failed!" << std::endl;
        return cv::Mat();
    }

    // 获取 DXGI 工厂
    hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(factory.GetAddressOf()));
    if (FAILED(hr)) {
        std::cerr << "CreateDXGIFactory1 failed!" << std::endl;
        return cv::Mat();
    }

    // 获取第一个适配器
    hr = factory->EnumAdapters1(0, adapter.GetAddressOf());
    if (FAILED(hr)) {
        std::cerr << "EnumAdapters1 failed!" << std::endl;
        return cv::Mat();
    }

    // 获取输出
    hr = adapter->EnumOutputs(0, output.GetAddressOf());
    if (FAILED(hr)) {
        std::cerr << "EnumOutputs failed!" << std::endl;
        return cv::Mat();
    }

    hr = output.As(&output1);
    if (FAILED(hr)) {
        std::cerr << "Failed to get IDXGIOutput1 interface!" << std::endl;
        return cv::Mat();
    }

    // 创建屏幕捕获的复制对象
    hr = output1->DuplicateOutput(device.Get(), duplication.GetAddressOf());
    if (FAILED(hr)) {
        std::cerr << "DuplicateOutput failed!" << std::endl;
        return cv::Mat();
    }

    // 捕获屏幕
    DXGI_OUTDUPL_FRAME_INFO frameInfo;
    hr = duplication->AcquireNextFrame(1000, &frameInfo, desktopResource.GetAddressOf());
    if (FAILED(hr)) {
        std::cerr << "AcquireNextFrame failed!" << std::endl;
        return cv::Mat();
    }

    // 获取桌面图像的纹理
    hr = desktopResource.As(&acquiredDesktopImage);
    if (FAILED(hr)) {
        std::cerr << "Failed to get desktop image as texture!" << std::endl;
        return cv::Mat();
    }

    // 获取桌面图像的描述
    D3D11_TEXTURE2D_DESC textureDesc;
    acquiredDesktopImage->GetDesc(&textureDesc);

    // 创建 OpenCV Mat 并从桌面图像中复制像素数据
    cv::Mat screenshot(textureDesc.Height, textureDesc.Width, CV_8UC4);
    D3D11_MAPPED_SUBRESOURCE mappedResource;
    hr = context->Map(acquiredDesktopImage.Get(), 0, D3D11_MAP_READ, 0, &mappedResource);
    if (FAILED(hr)) {
        std::cerr << "Failed to map the texture!" << std::endl;
        return cv::Mat();
    }

    // 复制像素数据到 OpenCV Mat
    memcpy(screenshot.data, mappedResource.pData, textureDesc.Height * textureDesc.Width * 4);

    // 解除映射
    context->Unmap(acquiredDesktopImage.Get(), 0);

    // 释放屏幕帧
    duplication->ReleaseFrame();

    // 返回捕获的屏幕
    return screenshot;
}

链接了dxgi.lib和d3d11.lib,但是还是显示未定义标识符

  • 写回答

1条回答 默认 最新

  • IT工程师_二师兄 2024-09-24 08:33
    关注

    debug哪一段报的错误

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 9月29日
  • 创建了问题 9月24日