赞
踩
1、包含必要的头文件:
- #include <d3d11.h>
- #include <dxgi1_2.h>
- #pragma comment(lib, "d3d11.lib")
- #pragma comment(lib, "dxgi.lib")
2、创建一个函数来执行屏幕截图并过滤掉指定窗口:
- void SaveScreenShot(ID3D11Device* pDevice, ID3D11DeviceContext* pImmediateContext, const char* filename)
- {
- IDXGIDevice* pDXGIDevice = nullptr;
- pDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&pDXGIDevice));
-
- IDXGIAdapter* pAdapter = nullptr;
- pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&pAdapter));
-
- IDXGIFactory1* pFactory = nullptr;
- pAdapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&pFactory));
-
- IDXGIOutput* pOutput = nullptr;
- pAdapter->EnumOutputs(0, &pOutput);
-
- IDXGIOutput1* pOutput1 = nullptr;
- pOutput->QueryInterface(__uuidof(IDXGIOutput1), reinterpret_cast<void**>(&pOutput1));
-
- IDXGIOutputDuplication* pOutputDuplication = nullptr;
- pOutput1->DuplicateOutput(pDevice, &pOutputDuplication);
-
- DXGI_OUTDUPL_DESC outputDuplicationDesc;
- pOutputDuplication->GetDesc(&outputDuplicationDesc);
-
- unsigned int bufferWidth = outputDuplicationDesc.ModeDesc.Width;
- unsigned int bufferHeight = outputDuplicationDesc.ModeDesc.Height;
- unsigned int bufferSize = bufferWidth * bufferHeight * 4;
-
- ID3D11Texture2D* pScreenTexture = nullptr;
- D3D11_TEXTURE2D_DESC texDesc;
- ZeroMemory(&texDesc, sizeof(texDesc));
- texDesc.Width = bufferWidth;
- texDesc.Height = bufferHeight;
- texDesc.MipLevels = 1;
- texDesc.ArraySize = 1;
- texDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
- texDesc.SampleDesc.Count = 1;
- texDesc.Usage = D3D11_USAGE_STAGING;
- texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
-
- pDevice->CreateTexture2D(&texDesc, NULL, &pScreenTexture);
-
- ID3D11Texture2D* pStagingTexture = nullptr;
- pDevice->CreateTexture2D(&texDesc, NULL, &pStagingTexture);
-
- DXGI_OUTDUPL_FRAME_INFO frameInfo;
- ID3D11Resource* pDesktopResource = nullptr;
- HRESULT hr = pOutputDuplication->AcquireNextFrame(500, &frameInfo, &pDesktopResource);
- if (hr == DXGI_ERROR_WAIT_TIMEOUT)
- {
- // 等待超时
- }
- else if (SUCCEEDED(hr))
- {
- pImmediateContext->CopyResource(pStagingTexture, pDesktopResource);
- pOutputDuplication->ReleaseFrame();
-
- pImmediateContext->CopyResource(pScreenTexture, pStagingTexture);
-
- D3D11_MAPPED_SUBRESOURCE mappedResource;
- pImmediateContext->Map(pScreenTexture, 0, D3D11_MAP_READ, 0, &mappedResource);
-
- unsigned char* pPixels = static_cast<unsigned char*>(mappedResource.pData);
-
- // 在这里保存屏幕截图为文件
- SaveBitmapToFile(pPixels, desc.Width, desc.Height, “c:/screenshot.bmp”)
-
- pImmediateContext->Unmap(pScreenTexture, 0);
- }
-
- pScreenTexture->Release();
- pStagingTexture->Release();
- pOutputDuplication->Release();
- pOutput1->Release();
- pOutput->Release();
- pFactory->Release();
- pAdapter->Release();
- pDXGIDevice->Release();
- }

3、创建一个函数来保存位图到文件:
- HRESULT SaveBitmapToFile(char* bmBits, int bmWidth, int bmHeight, const wchar_t* filePath)
- {
- HRESULT result = S_OK;
-
- // 创建位图文件头
- BITMAPFILEHEADER fileHeader;
- fileHeader.bfType = 0x4D42; // "BM"
- fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bmWidthBytes * bmHeight;
- fileHeader.bfReserved1 = 0;
- fileHeader.bfReserved2 = 0;
- fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
-
- // 创建位图信息头
- BITMAPINFOHEADER infoHeader;
- infoHeader.biSize = sizeof(BITMAPINFOHEADER);
- infoHeader.biWidth = bmWidth;
- infoHeader.biHeight = -bmHeight;
- infoHeader.biPlanes = 1;
- infoHeader.biBitCount = 32;
- infoHeader.biCompression = BI_RGB;
- infoHeader.biSizeImage = 0;
- infoHeader.biXPelsPerMeter = 0;
- infoHeader.biYPelsPerMeter = 0;
- infoHeader.biClrUsed = 0;
- infoHeader.biClrImportant = 0;
-
- // 创建文件并写入位图数据
- HANDLE fileHandle = CreateFileW(filePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (fileHandle != INVALID_HANDLE_VALUE)
- {
- DWORD bytesWritten = 0;
- WriteFile(fileHandle, &fileHeader, sizeof(BITMAPFILEHEADER), &bytesWritten, NULL);
- WriteFile(fileHandle, &infoHeader, sizeof(BITMAPINFOHEADER), &bytesWritten, NULL);
- WriteFile(fileHandle, bmBits, bmWidth * bmp.bmHeight * 4, &bytesWritten, NULL);
- CloseHandle(fileHandle);
- }
- else
- {
- result = E_FAIL;
- }
-
- return result;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。