C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++ Direct3D屏幕截图

使用C++和Direct3D (d3d)获取屏幕截图并根据传入分辨率进行缩放图片大小(最新推荐)

作者:拉伊卜

这篇文章主要介绍了使用C++和Direct3D (d3d)获取屏幕截图并根据传入分辨率进行缩放图片大小,本文给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

一,函数清单

1.Direct3DCreate9 函数

Direct3DCreate9 函数创建 IDirect3D9 对象并返回一个接口。

IDirect3D9 * Direct3DCreate9(
  UINT SDKVersion
);

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
);

3.IDirect3DDevice9::GetDisplayMode 方法

检索显示模式的空间分辨率、颜色分辨率和刷新频率。

HRESULT GetDisplayMode(
  [in]  UINT           iSwapChain,
  [out] D3DDISPLAYMODE *pMode
);

4.IDirect3DDevice9::CreateOffscreenPlainSurface 方法

创建屏幕外图面。

HRESULT CreateOffscreenPlainSurface(
  [in]          UINT              Width,
  [in]          UINT              Height,
  [in]          D3DFORMAT         Format,
  [in]          D3DPOOL           Pool,
  [out, retval] IDirect3DSurface9 **ppSurface,
  [in]          HANDLE            *pSharedHandle
);

5.IDirect3DDevice9::GetFrontBufferData 方法

生成设备的前缓冲区的副本,并将该副本放置在应用程序提供的系统内存缓冲区中。

HRESULT GetFrontBufferData(
  [in] UINT              iSwapChain,
  [in] IDirect3DSurface9 *pDestSurface
);

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
);

7. D3DXSaveSurfaceToFile 函数

将图面保存到文件。

HRESULT D3DXSaveSurfaceToFile(
  _In_       LPCTSTR              pDestFile,
  _In_       D3DXIMAGE_FILEFORMAT DestFormat,
  _In_       LPDIRECT3DSURFACE9   pSrcSurface,
  _In_ const PALETTEENTRY         *pSrcPalette,
  _In_ const RECT                 *pSrcRect
);

二,关键代码实现

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.最终展示效果

打开工程所在的目录,然后会看到有一张图片,图片效果如下,没有看错!就是一张图片!(温馨提示:该图片是通过代码截的,不是我自己截的哦)

到此这篇关于使用C++和Direct3D (d3d)获取屏幕截图并根据传入分辨率进行缩放图片大小(最新推荐)的文章就介绍到这了,更多相关C++ Direct3D屏幕截图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文