[C++] 纯文本查看 复制代码
#include <windows.h>
#include <dxgi1_2.h>
#include <d3d11.h>
#include <iostream>
#include <vector>
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3d11.lib")
void SaveScreenPixelsToMemory() {
// 初始化 D3D11 和 DXGI 设备
IDXGIFactory1* factory = nullptr;
HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory);
if (FAILED(hr)) {
std::cerr << "Failed to create DXGIFactory." << std::endl;
return;
}
IDXGIAdapter1* adapter = nullptr;
hr = factory->EnumAdapters1(0, &adapter);
if (FAILED(hr)) {
std::cerr << "Failed to enumerate adapters." << std::endl;
return;
}
ID3D11Device* device = nullptr;
ID3D11DeviceContext* context = nullptr;
D3D_FEATURE_LEVEL featureLevel;
/*
hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT,
nullptr, 0, D3D11_SDK_VERSION, &device, &featureLevel, &context);
if (FA
*/
const D3D_FEATURE_LEVEL featureLevels[] = {
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
};
hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT,
featureLevels, 6, D3D11_SDK_VERSION, &device, &featureLevel, &context);
/*
hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, 0,
nullptr, 0, D3D11_SDK_VERSION, &device, &featureLevel, &context);
*/
if (FAILED(hr)) {
std::cerr << "Failed to create D3D11 device." << std::endl;
return;
}
IDXGIOutput* output = nullptr;
hr = adapter->EnumOutputs(0, &output);
if (FAILED(hr)) {
std::cerr << "Failed to enumerate outputs." << std::endl;
return;
}
IDXGIOutput1* output1 = nullptr;
hr = output->QueryInterface(__uuidof(IDXGIOutput1), (void**)&output1);
if (FAILED(hr)) {
std::cerr << "Failed to get IDXGIOutput1." << std::endl;
return;
}
IDXGIOutputDuplication* duplication = nullptr;
hr = output1->DuplicateOutput(device, &duplication);
if (FAILED(hr)) {
std::cerr << "Failed to create output duplication." << std::endl;
return;
}
DXGI_OUTDUPL_DESC duplDesc;
duplication->GetDesc(&duplDesc);
int width = duplDesc.ModeDesc.Width;
int height = duplDesc.ModeDesc.Height;
// 开始捕获屏幕
DXGI_OUTDUPL_FRAME_INFO frameInfo = {0};
IDXGIResource* desktopResource = nullptr;
while(1) {
hr = duplication->AcquireNextFrame(500, &frameInfo, &desktopResource);
if (FAILED(hr)) {
std::cerr << "Failed to acquire next frame." << std::endl;
return;
}
if (frameInfo.LastPresentTime.QuadPart == 0)
{
duplication->ReleaseFrame();
Sleep(1);
continue;
}
break;
}
ID3D11Texture2D* desktopImage = nullptr;
hr = desktopResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&desktopImage);
if (FAILED(hr)) {
std::cerr << "Failed to get ID3D11Texture2D from IDXGIResource." << std::endl;
return;
}
// 创建 staging texture 用于 CPU 访问
D3D11_TEXTURE2D_DESC desc;
desktopImage->GetDesc(&desc);
desc.Usage = D3D11_USAGE_STAGING;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
ID3D11Texture2D* stagingTexture = nullptr;
hr = device->CreateTexture2D(&desc, nullptr, &stagingTexture);
if (FAILED(hr)) {
std::cerr << "Failed to create staging texture." << std::endl;
return;
}
context->CopyResource(stagingTexture, desktopImage);
// 映射纹理到 CPU
D3D11_MAPPED_SUBRESOURCE mappedResource;
hr = context->Map(stagingTexture, 0, D3D11_MAP_READ, 0, &mappedResource);
if (FAILED(hr)) {
std::cerr << "Failed to map staging texture." << std::endl;
return;
}
// 处理像素数据
std::vector<unsigned char> pixels;
pixels.resize(width * height * 4);
unsigned char* src = (unsigned char*)mappedResource.pData;
int rowPitch = mappedResource.RowPitch;
for (int y = 0; y < height; ++y) {
memcpy(&pixels[y * width * 4], &src[y * rowPitch], width * 4);
}
context->Unmap(stagingTexture, 0);
// 打印一些像素数据
for (int i = 0; i < 100; ++i) {
int pixelIndex = i * 4;
unsigned char b = pixels[pixelIndex + 0];
unsigned char g = pixels[pixelIndex + 1];
unsigned char r = pixels[pixelIndex + 2];
std::cout << "Pixel " << i << ": R=" << (int)r << " G=" << (int)g << " B=" << (int)b << std::endl;
}
// 清理资源
duplication->ReleaseFrame();
desktopResource->Release();
stagingTexture->Release();
desktopImage->Release();
duplication->Release();
output1->Release();
output->Release();
context->Release();
device->Release();
adapter->Release();
factory->Release();
}
int main() {
SaveScreenPixelsToMemory();
return 0;
}