direct2d图像刚性弯曲代码
时间: 2023-11-12 10:46:33 浏览: 72
以下是使用 Direct2D 实现图像刚性弯曲的示例代码:
```cpp
#include <Windows.h>
#include <d2d1.h>
#include <d2d1helper.h>
#include <wincodec.h>
#pragma comment(lib, "d2d1.lib")
#pragma comment(lib, "windowscodecs.lib")
// 定义图像刚性变换的矩阵
D2D1_MATRIX_3X2_F g_transformMatrix = D2D1::Matrix3x2F(1, 0, 0, 0, 1, 0);
// 定义 Direct2D 绘图对象
ID2D1Factory* g_pD2DFactory = nullptr;
ID2D1HwndRenderTarget* g_pRenderTarget = nullptr;
ID2D1Bitmap* g_pBitmap = nullptr;
ID2D1BitmapBrush* g_pBitmapBrush = nullptr;
// 定义窗口大小
const int g_width = 800;
const int g_height = 600;
// 加载位图文件
HRESULT LoadBitmapFromFile(ID2D1RenderTarget* pRenderTarget, IWICImagingFactory* pIWICFactory, LPCWSTR uri, UINT destinationWidth, UINT destinationHeight, ID2D1Bitmap** ppBitmap)
{
HRESULT hr = S_OK;
// 创建 WIC 图像解码器
IWICBitmapDecoder* pDecoder = nullptr;
hr = pIWICFactory->CreateDecoderFromFilename(uri, nullptr, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &pDecoder);
if (SUCCEEDED(hr))
{
// 读取位图帧
IWICBitmapFrameDecode* pSource = nullptr;
hr = pDecoder->GetFrame(0, &pSource);
if (SUCCEEDED(hr))
{
// 缩放位图
IWICBitmapScaler* pScaler = nullptr;
hr = pIWICFactory->CreateBitmapScaler(&pScaler);
if (SUCCEEDED(hr))
{
UINT originalWidth = 0;
UINT originalHeight = 0;
hr = pSource->GetSize(&originalWidth, &originalHeight);
if (SUCCEEDED(hr))
{
FLOAT scaleX = static_cast<FLOAT>(destinationWidth) / originalWidth;
FLOAT scaleY = static_cast<FLOAT>(destinationHeight) / originalHeight;
WICPixelFormatGUID pixelFormat;
hr = pSource->GetPixelFormat(&pixelFormat);
if (SUCCEEDED(hr))
{
if (scaleX != 1.0f || scaleY != 1.0f)
{
pScaler->Initialize(pSource, static_cast<UINT>(destinationWidth), static_cast<UINT>(destinationHeight), WICBitmapInterpolationModeCubic);
pRenderTarget->CreateBitmapFromWicBitmap(pScaler, nullptr, ppBitmap);
}
else
{
pRenderTarget->CreateBitmapFromWicBitmap(pSource, nullptr, ppBitmap);
}
}
}
pScaler->Release();
}
pSource->Release();
}
pDecoder->Release();
}
return hr;
}
// 初始化 Direct2D
HRESULT InitializeDirect2D(HWND hWnd)
{
HRESULT hr = S_OK;
// 创建 Direct2D 工厂
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &g_pD2DFactory);
if (SUCCEEDED(hr))
{
// 获取窗口大小
RECT rc;
GetClientRect(hWnd, &rc);
D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);
// 创建 Direct2D 渲染目标
hr = g_pD2DFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties(hWnd, size), &g_pRenderTarget);
if (SUCCEEDED(hr))
{
// 加载位图文件
IWICImagingFactory* pIWICFactory = nullptr;
hr = CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pIWICFactory));
if (SUCCEEDED(hr))
{
hr = LoadBitmapFromFile(g_pRenderTarget, pIWICFactory, L"test.jpg", g_width, g_height, &g_pBitmap);
if (SUCCEEDED(hr))
{
// 创建位图画刷
hr = g_pRenderTarget->CreateBitmapBrush(g_pBitmap, &g_pBitmapBrush);
if (SUCCEEDED(hr))
{
// 设置画刷的平铺模式为重复
g_pBitmapBrush->SetExtendModeX(D2D1_EXTEND_MODE_WRAP);
g_pBitmapBrush->SetExtendModeY(D2D1_EXTEND_MODE_WRAP);
}
}
pIWICFactory->Release();
}
}
}
return hr;
}
// 渲染场景
void RenderScene()
{
// 开始渲染
g_pRenderTarget->BeginDraw();
// 清空背景
g_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
// 应用刚性变换矩阵
g_pRenderTarget->SetTransform(g_transformMatrix);
// 绘制位图
g_pRenderTarget->FillRectangle(D2D1::RectF(0, 0, g_width, g_height), g_pBitmapBrush);
// 结束渲染
g_pRenderTarget->EndDraw();
}
// 释放资源
void ReleaseResources()
{
SafeRelease(&g_pD2DFactory);
SafeRelease(&g_pRenderTarget);
SafeRelease(&g_pBitmap);
SafeRelease(&g_pBitmapBrush);
}
// 处理窗口消息
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
// 初始化 Direct2D
if (FAILED(InitializeDirect2D(hWnd)))
{
MessageBox(hWnd, L"初始化 Direct2D 失败", L"错误", MB_OK | MB_ICONERROR);
return -1;
}
break;
case WM_PAINT:
// 渲染场景
RenderScene();
ValidateRect(hWnd, NULL);
break;
case WM_SIZE:
// 重新创建渲染目标
ReleaseResources();
if (FAILED(InitializeDirect2D(hWnd)))
{
MessageBox(hWnd, L"初始化 Direct2D 失败", L"错误", MB_OK | MB_ICONERROR);
return -1;
}
break;
case WM_DESTROY:
// 释放资源
ReleaseResources();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// WinMain 函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// 注册窗口类
WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.lpszClassName = L"Direct2DApp";
RegisterClassEx(&wcex);
// 创建窗口
HWND hWnd = CreateWindow(L"Direct2DApp", L"Direct2D App", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, g_width, g_height, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
// 显示窗口
ShowWindow(hWnd, nCmdShow);
// 消息循环
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
```
在上面的示例代码中,`g_transformMatrix` 变量表示图像的刚性变换矩阵,可以使用 `D2D1::Matrix3x2F` 函数来创建。在 `RenderScene` 函数中,可以使用 `g_pRenderTarget->SetTransform` 函数来应用刚性变换矩阵。
阅读全文