当前位置:   article > 正文

C++ Windows下使用DXGI实现屏幕截图_dxgi截图

dxgi截图

1、包含必要的头文件:

  1. #include <d3d11.h>
  2. #include <dxgi1_2.h>
  3. #pragma comment(lib, "d3d11.lib")
  4. #pragma comment(lib, "dxgi.lib")

2、创建一个函数来执行屏幕截图并过滤掉指定窗口:

  1. void SaveScreenShot(ID3D11Device* pDevice, ID3D11DeviceContext* pImmediateContext, const char* filename)
  2. {
  3.     IDXGIDevice* pDXGIDevice = nullptr;
  4.     pDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&pDXGIDevice));
  5.     IDXGIAdapter* pAdapter = nullptr;
  6.     pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&pAdapter));
  7.     IDXGIFactory1* pFactory = nullptr;
  8.     pAdapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&pFactory));
  9.     IDXGIOutput* pOutput = nullptr;
  10.     pAdapter->EnumOutputs(0, &pOutput);
  11.     IDXGIOutput1* pOutput1 = nullptr;
  12.     pOutput->QueryInterface(__uuidof(IDXGIOutput1), reinterpret_cast<void**>(&pOutput1));
  13.     IDXGIOutputDuplication* pOutputDuplication = nullptr;
  14.     pOutput1->DuplicateOutput(pDevice, &pOutputDuplication);
  15.     DXGI_OUTDUPL_DESC outputDuplicationDesc;
  16.     pOutputDuplication->GetDesc(&outputDuplicationDesc);
  17.     unsigned int bufferWidth = outputDuplicationDesc.ModeDesc.Width;
  18.     unsigned int bufferHeight = outputDuplicationDesc.ModeDesc.Height;
  19.     unsigned int bufferSize = bufferWidth * bufferHeight * 4;
  20.     ID3D11Texture2D* pScreenTexture = nullptr;
  21.     D3D11_TEXTURE2D_DESC texDesc;
  22.     ZeroMemory(&texDesc, sizeof(texDesc));
  23.     texDesc.Width = bufferWidth;
  24.     texDesc.Height = bufferHeight;
  25.     texDesc.MipLevels = 1;
  26.     texDesc.ArraySize = 1;
  27.     texDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
  28.     texDesc.SampleDesc.Count = 1;
  29.     texDesc.Usage = D3D11_USAGE_STAGING;
  30.     texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
  31.     pDevice->CreateTexture2D(&texDesc, NULL, &pScreenTexture);
  32.     ID3D11Texture2D* pStagingTexture = nullptr;
  33.     pDevice->CreateTexture2D(&texDesc, NULL, &pStagingTexture);
  34.     DXGI_OUTDUPL_FRAME_INFO frameInfo;
  35.     ID3D11Resource* pDesktopResource = nullptr;
  36.     HRESULT hr = pOutputDuplication->AcquireNextFrame(500, &frameInfo, &pDesktopResource);
  37.     if (hr == DXGI_ERROR_WAIT_TIMEOUT)
  38.     {
  39.         // 等待超时
  40.     }
  41.     else if (SUCCEEDED(hr))
  42.     {
  43.         pImmediateContext->CopyResource(pStagingTexture, pDesktopResource);
  44.         pOutputDuplication->ReleaseFrame();
  45.         pImmediateContext->CopyResource(pScreenTexture, pStagingTexture);
  46.         D3D11_MAPPED_SUBRESOURCE mappedResource;
  47.         pImmediateContext->Map(pScreenTexture, 0, D3D11_MAP_READ, 0, &mappedResource);
  48.         unsigned char* pPixels = static_cast<unsigned char*>(mappedResource.pData);
  49. // 在这里保存屏幕截图为文件
  50. SaveBitmapToFile(pPixels, desc.Width, desc.Height, “c:/screenshot.bmp”)
  51.         pImmediateContext->Unmap(pScreenTexture, 0);
  52.     }
  53.     pScreenTexture->Release();
  54.     pStagingTexture->Release();
  55.     pOutputDuplication->Release();
  56.     pOutput1->Release();
  57.     pOutput->Release();
  58.     pFactory->Release();
  59.     pAdapter->Release();
  60.     pDXGIDevice->Release();
  61. }

3、创建一个函数来保存位图到文件:

  1. HRESULT SaveBitmapToFile(char* bmBits, int bmWidth, int bmHeight, const wchar_t* filePath)
  2. {
  3.     HRESULT result = S_OK;
  4.  
  5.     // 创建位图文件头
  6.     BITMAPFILEHEADER fileHeader;
  7.     fileHeader.bfType = 0x4D42;  // "BM"
  8.     fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bmWidthBytes * bmHeight;
  9.     fileHeader.bfReserved1 = 0;
  10.     fileHeader.bfReserved2 = 0;
  11.     fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  12.  
  13.     // 创建位图信息头
  14.     BITMAPINFOHEADER infoHeader;
  15.     infoHeader.biSize = sizeof(BITMAPINFOHEADER);
  16.     infoHeader.biWidth = bmWidth;
  17.     infoHeader.biHeight = -bmHeight;
  18.     infoHeader.biPlanes = 1;
  19.     infoHeader.biBitCount = 32;
  20.     infoHeader.biCompression = BI_RGB;
  21.     infoHeader.biSizeImage = 0;
  22.     infoHeader.biXPelsPerMeter = 0;
  23.     infoHeader.biYPelsPerMeter = 0;
  24.     infoHeader.biClrUsed = 0;
  25.     infoHeader.biClrImportant = 0;
  26.  
  27.     // 创建文件并写入位图数据
  28.     HANDLE fileHandle = CreateFileW(filePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  29.     if (fileHandle != INVALID_HANDLE_VALUE)
  30.     {
  31.         DWORD bytesWritten = 0;
  32.         WriteFile(fileHandle, &fileHeader, sizeof(BITMAPFILEHEADER), &bytesWritten, NULL);
  33.         WriteFile(fileHandle, &infoHeader, sizeof(BITMAPINFOHEADER), &bytesWritten, NULL);
  34.         WriteFile(fileHandle, bmBits, bmWidth * bmp.bmHeight * 4, &bytesWritten, NULL);
  35.         CloseHandle(fileHandle);
  36.     }
  37.     else
  38.     {
  39.         result = E_FAIL;
  40.     }
  41.  
  42.     return result;
  43. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/430039
推荐阅读
相关标签
  

闽ICP备14008679号