【发布时间】:2017-07-07 12:40:33
【问题描述】:
所以,马上开始接触金属。我正在编写一个 c++ 程序,其目的是将屏幕作为输入图像并使用对象检测器(来自 dlib)对其进行处理,但我无法理解如何获得指向 swapChain 和上下文/内容的指针屏幕。
ScreenGrab (DirectX Tool Kit) 的以下代码似乎可以解决问题。问题是我不知道如何让它工作。我在 Visual Studio 2017 中使用 NuGet 来获取库(称为 directxtk_uwp,还有一个我没有使用的称为 directxtk_desktop_2015。)我收到以下六个错误:
- 错误 C2065:“swapChain”:未声明的标识符
- 错误 C2227:'->GetBuffer' 的左侧必须指向类/结构/联合/泛型类型
- 错误 C2065:“immContext”:未声明的标识符
- 错误 C2228:“.Get”左侧必须有类/结构/联合
- 错误 C2653:“DX”:不是类或命名空间名称
- 错误 C3861:“ThrowIfFailed”:找不到标识符
从 ScreenGrab wiki 页面运行插入的示例代码:
#include <ScreenGrab.h>
#include <wrl\client.h>
#include <Wincodec.h>
int main() {
using namespace DirectX;
using namespace Microsoft::WRL;
ComPtr<ID3D11Texture2D> backBuffer;
HRESULT hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),
reinterpret_cast<LPVOID*>(backBuffer.GetAddressOf()));
if (SUCCEEDED(hr))
{
hr = SaveWICTextureToFile(immContext.Get(), backBuffer.Get(),
GUID_ContainerFormatJpeg, L"SCREENSHOT.JPG");
}
DX::ThrowIfFailed(hr);
return 0;
}
我刚刚开始使用 c++ 进行编程,并且来自 Java 编程,我已经积极开发了一年。所以保持简单易懂将不胜感激^^
为了清楚起见,我想要一些相当快的东西。我已经通过以下代码获得了与 GDI 一起使用的屏幕截图:
#include <iostream>
#include <Windows.h>
#include <Wincodec.h>
#include <ctime>
#include <cstring>
#include <atlimage.h>
#include <d3d9.h>
using namespace std;
int main()
{
try
{
int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
HWND hDesktopWnd = GetDesktopWindow();
HDC hDesktopDC = GetDC(hDesktopWnd);
HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);
for (int i = 0; i < 10;i++) {
clock_t begin = clock();
HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDesktopDC,
nScreenWidth, nScreenHeight);
SelectObject(hCaptureDC, hCaptureBitmap);
BitBlt(hCaptureDC, 0, 0, nScreenWidth, nScreenHeight,
hDesktopDC, 0, 0, SRCCOPY | CAPTUREBLT);
CImage image;
image.Attach(hCaptureBitmap);
image.Save("test.jpg");
DeleteObject(hCaptureBitmap);
cout << double(clock() - begin) / (clock_t)1000 << endl;
}
ReleaseDC(hDesktopWnd, hDesktopDC);
DeleteDC(hCaptureDC);
IDirect3DSurface9 *surface;
system("pause");
}
catch (exception& e)
{
cout << "\nexception thrown!" << endl;
cout << e.what() << endl;
system("pause");
}
}
结果如下:
0.091
0.05
0.052
0.06
0.047
0.05
0.057
0.06
0.06
0.051
如您所见,这实际上只能使我的速度达到每秒 1/0.47 ≈ 21 帧。我也看过this 的回答,但我还是不知道如何获取屏幕的上下文和交换链。 谢谢。
【问题讨论】:
-
您使用的示例代码避免假设您尝试截取自己的渲染目标纹理(直接创建或从您自己的交换链获得)。这适用于您自己的应用程序,但截取整个桌面的屏幕截图是另一回事,需要使用 DXGI API。您应该查看this article 的一些选项。
-
DirectX 工具包wiki 上的示例代码假设您至少简要地查看了tutorials,我在其中介绍了ThrowIfFailed。
-
谢谢,查克!正如您在变量名中可能看到的那样,我能够找到该页面,我只是不记得该站点。从来没有让 DirectX 工作的方式,但那是很早的,我想我现在有更好的理解来做它。但是,DirectX9 不是像您在有关 DirectX11 的链接问题中所说的那样已经过时了吗?无论如何,非常感谢您的帮助!
-
太棒了!非常感谢你,查克!这应该这样做。有时有专家指出正确的方向真是太好了^^
标签: c++ performance screenshot fullscreen directx-11