这篇文章主要介绍“怎么使用C++和Direct3D获取屏幕截图并根据传入分辨率进行缩放图片大小”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用C++和Direct3D获取屏幕截图并根据传入分辨率进行缩放图片大小”文章能帮助大家解决问题。
一,函数清单
1.Direct3DCreate9 函数
Direct3DCreate9 函数创建 IDirect3D9 对象并返回一个接口。
IDirect3D9 * Direct3DCreate9( UINT SDKVersion );
参数:SDKVersion
返回值:如果成功,此函数将返回指向 IDirect3D9 接口的指针;否则,返回 NULL 指针。
2.IDirect3D9::CreateDevice 方法
创建一个设备来表示显示适配器。
HRESULT CreateDevice( [in] UINT Adapter, [in] D3DDEVTYPE DeviceType, [in] HWND hFocusWindow, [in] DWORD BehaviorFlags, [in, out] D3DPRESENT_PARAMETERS *pPresentationParameters, [out, retval] IDirect3DDevice9 **ppReturnedDeviceInterface );
参数:点击函数名称跳转即可查看详细介绍
返回值:如果该方法成功,则返回值为 D3D_OK。如果该方法失败,则返回值可以是以下之一:D3DERR_DEVICELOST、D3DERR_INVALIDCALL、D3DERR_NOTAVAILABLE、D3DERR_OUTOFVIDEOMEMORY。
3.IDirect3DDevice9::GetDisplayMode 方法
检索显示模式的空间分辨率、颜色分辨率和刷新频率。
HRESULT GetDisplayMode( [in] UINT iSwapChain, [out] D3DDISPLAYMODE *pMode );
参数:点击函数名称跳转即可查看详细介绍
返回值:如果方法成功,则返回值D3D_OK。 如果方法失败,则可以D3DERR_INVALIDCALL返回值。
4.IDirect3DDevice9::CreateOffscreenPlainSurface 方法
创建屏幕外图面。
HRESULT CreateOffscreenPlainSurface( [in] UINT Width, [in] UINT Height, [in] D3DFORMAT Format, [in] D3DPOOL Pool, [out, retval] IDirect3DSurface9 **ppSurface, [in] HANDLE *pSharedHandle );
参数:点击函数名称跳转即可查看详细介绍
返回值:如果方法成功,则返回值D3D_OK。 如果方法失败,则返回值可以是以下值:D3DERR_INVALIDCALL。
5.IDirect3DDevice9::GetFrontBufferData 方法
生成设备的前缓冲区的副本,并将该副本放置在应用程序提供的系统内存缓冲区中。
HRESULT GetFrontBufferData( [in] UINT iSwapChain, [in] IDirect3DSurface9 *pDestSurface );
参数:点击函数名称跳转即可查看详细介绍
返回值:如果方法成功,则返回值D3D_OK。 如果方法失败,则返回值可以是下列值之一:D3DERR_DRIVERINTERNALERROR、D3DERR_DEVICELOST、D3DERR_INVALIDCALL。
6.IDirect3DDevice9::D3DXLoadSurfaceFromSurface 方法
通过颜色转换从另一个图面加载图面。
HRESULT D3DXLoadSurfaceFromSurface( _In_ LPDIRECT3DSURFACE9 pDestSurface, _In_ const PALETTEENTRY *pDestPalette, _In_ const RECT *pDestRect, _In_ LPDIRECT3DSURFACE9 pSrcSurface, _In_ const PALETTEENTRY *pSrcPalette, _In_ const RECT *pSrcRect, _In_ DWORD Filter, _In_ D3DCOLOR ColorKey );
参数:点击函数名称跳转即可查看详细介绍
返回值:如果函数成功,则返回值D3D_OK。 如果函数失败,则返回值可以是以下值之一:D3DERR_INVALIDCALL、D3DXERR_INVALIDDATA。
7. D3DXSaveSurfaceToFile 函数
将图面保存到文件。
HRESULT D3DXSaveSurfaceToFile( _In_ LPCTSTR pDestFile, _In_ D3DXIMAGE_FILEFORMAT DestFormat, _In_ LPDIRECT3DSURFACE9 pSrcSurface, _In_ const PALETTEENTRY *pSrcPalette, _In_ const RECT *pSrcRect );
参数:点击函数名称跳转即可查看详细介绍
返回值:如果函数成功,则返回值D3D_OK。 如果函数失败,则返回值可能如下所示:D3DERR_INVALIDCALL。
二,关键代码实现
1.创建 IDirect3D9 对象
LPDIRECT3D9 pD3D = nullptr; //Direct3D 对象是图形应用程序需要创建的第一个 Direct3D COM 对象,也是应用程序需要释放的最后一个对象 if (nullptr == (pD3D = Direct3DCreate9(D3D_SDK_VERSION))) {//创建 IDirect3D9 对象并返回一个接口。 return E_FAIL; }
2.初始化用于创建 Direct3D 设备的 D3DPRESENT_PARAMETERS 结构的值。
LPDIRECT3DDEVICE9 pDevice = nullptr; D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.Windowed = TRUE; //如果应用程序运行窗口,则为 TRUE;如果应用程序全屏运行,则为 FALSE。 d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; //运行时将保证有关缓冲区交换行为的隐式语义;
3.接下来,创建 Direct3D 设备
if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetDesktopWindow(),D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice))) {//创建一个设备来表示显示适配器。指定默认适配器、硬件抽象层 (HAL) 设备和软件顶点处理。 return E_FAIL; }
4.获取屏幕截图接口实现
IDirect3DSurface9* GetScreenShot(IDirect3DDevice9* pDevice) { IDirect3DSurface9* pSurface = nullptr; D3DDISPLAYMODE displayMode; //检索显示模式的空间分辨率、颜色分辨率和刷新频率。 pDevice->GetDisplayMode(0, &displayMode); std::cout << displayMode.Width << displayMode.Height << std::endl; //创建屏幕外图面。 HRESULT hr = pDevice->CreateOffscreenPlainSurface(displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pSurface, NULL); if (FAILED(hr)) { return nullptr; } //生成设备的前缓冲区的副本,并将该副本放置在应用程序提供的系统内存缓冲区中。 hr = pDevice->GetFrontBufferData(0, pSurface); if (FAILED(hr)) { return nullptr; } return pSurface; }
5.缩放图片接口实现
IDirect3DSurface9* ResizeSurface(IDirect3DDevice9* pDevice, IDirect3DSurface9* pSrcSurface, int width, int height) { IDirect3DSurface9* pDestSurface = nullptr; //创建屏幕外图面。 HRESULT hr = pDevice->CreateOffscreenPlainSurface(width, height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pDestSurface, NULL); if (FAILED(hr)) { return nullptr; } //通过颜色转换从另一个图面加载图面。 D3DXLoadSurfaceFromSurface(pDestSurface, NULL, NULL, pSrcSurface, NULL, NULL, D3DX_FILTER_TRIANGLE, 0); return pDestSurface; }
三,最终实现和展示效果
1.d3d下载和工程属性页配置d3d
1.点击 Direct3D链接 下载,然后点击 exe 进行安装,安装好后内容如下:
2.工程配置d3d的依赖:在VC++目录中配置 d3d 的包含目录和库目录(注意:库目录的位数要和解决方案平台的位数一致)
2.全部实现代码
#include <iostream> #include <d3d9.h> #include <d3dx9.h> #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") // 获取屏幕截图 IDirect3DSurface9* GetScreenShot(IDirect3DDevice9* pDevice) { IDirect3DSurface9* pSurface = nullptr; D3DDISPLAYMODE displayMode; //检索显示模式的空间分辨率、颜色分辨率和刷新频率。 pDevice->GetDisplayMode(0, &displayMode); std::cout << displayMode.Width << displayMode.Height << std::endl; //创建屏幕外图面。 HRESULT hr = pDevice->CreateOffscreenPlainSurface(displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pSurface, NULL); if (FAILED(hr)) { return nullptr; } //生成设备的前缓冲区的副本,并将该副本放置在应用程序提供的系统内存缓冲区中。 hr = pDevice->GetFrontBufferData(0, pSurface); if (FAILED(hr)) { return nullptr; } return pSurface; } // 缩放图片 IDirect3DSurface9* ResizeSurface(IDirect3DDevice9* pDevice, IDirect3DSurface9* pSrcSurface, int width, int height) { IDirect3DSurface9* pDestSurface = nullptr; //创建屏幕外图面。 HRESULT hr = pDevice->CreateOffscreenPlainSurface(width, height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pDestSurface, NULL); if (FAILED(hr)) { return nullptr; } //通过颜色转换从另一个图面加载图面。 D3DXLoadSurfaceFromSurface(pDestSurface, NULL, NULL, pSrcSurface, NULL, NULL, D3DX_FILTER_TRIANGLE, 0); return pDestSurface; } int main() { // 1.初始化 Direct3D 设备 LPDIRECT3D9 pD3D = nullptr; //Direct3D 对象是图形应用程序需要创建的第一个 Direct3D COM 对象,也是应用程序需要释放的最后一个对象 if (nullptr == (pD3D = Direct3DCreate9(D3D_SDK_VERSION))) {//创建 IDirect3D9 对象并返回一个接口。 return E_FAIL; } // 2.创建 Direct3D 设备 LPDIRECT3DDEVICE9 pDevice = nullptr; D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.Windowed = TRUE; //如果应用程序运行窗口,则为 TRUE;如果应用程序全屏运行,则为 FALSE。 d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; //运行时将保证有关缓冲区交换行为的隐式语义; if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetDesktopWindow(), D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice))) {//创建一个设备来表示显示适配器。指定默认适配器、硬件抽象层 (HAL) 设备和软件顶点处理。 return E_FAIL; } // 3.获取屏幕截图 IDirect3DSurface9* pSrcSurface = GetScreenShot(pDevice); // 4.缩放图片(可用可不用) int targetWidth = 1920; // 目标宽度 int targetHeight = 1080; // 目标高度 IDirect3DSurface9* pDestSurface = ResizeSurface(pDevice, pSrcSurface, targetWidth, targetHeight); // 5.保存图片(保存到工程所在的目录下) D3DXSaveSurfaceToFile(L"screenshot.jpg", D3DXIFF_JPG, pDestSurface, NULL, NULL); // 6.释放资源 pDestSurface->Release(); pSrcSurface->Release(); pDevice->Release(); pD3D->Release(); return 0; }
3.最终展示效果
打开工程所在的目录,然后会看到有一张图片,图片效果如下,没有看错!就是一张图片!(温馨提示:该图片是通过代码截的,不是我自己截的哦)