C++学习笔记,D2D加载本地图片并显示


Direct 2d中,基本就是图片,刚开始学,花了一些时间才加载显示成功。

相关文档https://msdn.microsoft.com/en-us/library/windows/desktop/dd370994(v=vs.85).aspx


开始需要说明的是,图片文件的路径应该怎么写

1.绝对路径,例如:C:\\xxx\\xxx\\xxxx.jpg

2.相对路径,该路径默认为当前项目中存放 .vcxproj 文件的路径,需要相对路径时,不需要写前置的 ..\..这些,例如:

L"resource\\jiemian.png"


1.加载一张图片

//从文件中读取一张图片
HRESULT QZ_Graphic::LoadBitmapFromFile(
	PCWSTR uri,
	UINT destinationWidth,
	UINT destinationHeight,
	ID2D1Bitmap **ppBitmap
) {
	IWICBitmapDecoder *pDecoder = NULL;
	IWICBitmapFrameDecode *pSource = NULL;
	IWICStream *pStream = NULL;
	IWICFormatConverter *pConverter = NULL;
	IWICBitmapScaler *pScaler = NULL;

	//创建解码器
	HRESULT hr = pIWICFactory->CreateDecoderFromFilename(
		uri,
		NULL,
		GENERIC_READ,
		WICDecodeMetadataCacheOnLoad,
		&pDecoder
	);

	//获取图像第一帧( 动图会有多帧,而静态图仅有一帧 )
	if (SUCCEEDED(hr)) {
		hr = pDecoder->GetFrame(0, &pSource);
	}

	//创建格式转换器
	if (SUCCEEDED(hr)) {
		// Convert the image format to 32bppPBGRA
		// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
		hr = pIWICFactory->CreateFormatConverter(&pConverter);
	}

	//初始化资源
	if (SUCCEEDED(hr)) {
		hr = pConverter->Initialize(
			pSource,
			GUID_WICPixelFormat32bppPBGRA,
			WICBitmapDitherTypeNone,
			NULL,
			0.f,
			WICBitmapPaletteTypeMedianCut
		);
	}
	//从WIC Bitmap资源中创建一个D2D Bitmap
	if (SUCCEEDED(hr)) {
		hr = renderTarget->CreateBitmapFromWicBitmap(
			pConverter,
			NULL,
			ppBitmap
		);
	}

	if (pDecoder != nullptr)
		pDecoder->Release();
	if (pSource != nullptr)
		pSource->Release();
	if (pStream != nullptr)
		pStream->Release();
	if (pConverter != nullptr)
		pConverter->Release();
	if (pScaler != nullptr)
		pScaler->Release();

	return hr;
}

其中,加载图片时需先加载后转为D2D可用图片格式。

加载图片时需要一个IWICImagingFactory 工厂

其创建方法为:

hr = CoCreateInstance(
		CLSID_WICImagingFactory,
		NULL,
		CLSCTX_INPROC_SERVER,
		IID_IWICImagingFactory,
		(LPVOID*)&pIWICFactory
	);

若创建失败则需先初始化另外一个

CoInitialize(NULL);
若使用这个大概在程序即将退出时使用代码,

CoUninitialize();


此时,图片即被加载到内存
然后绘制之前,需要D2D工厂,渲染目标

ID2D1Factory * factory;
ID2D1HwndRenderTarget * renderTarget;


初始化
	HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory);

	GetClientRect(hwnd, &dm_size);
	D2D1_SIZE_U size = D2D1::SizeU(
		dm_size.right - dm_size.left,
		dm_size.bottom - dm_size.top
	);

	hr = factory->CreateHwndRenderTarget(
		D2D1::RenderTargetProperties(),
		D2D1::HwndRenderTargetProperties(hwnd, size),
		&renderTarget
	);

然后绘制

renderTarget->BeginDraw();
	//renderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
	renderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
	//获取绘制区域大小
	D2D1_SIZE_F size_f = renderTarget->GetSize();


	D2D1_RECT_F rc_b = D2D1::RectF(
		0.f,
		0.f,
		size_f.width,
		size_f.height
	);
		
	D2D1_RECT_F rc_bitmap = D2D1::RectF(
		0.f+ currentX,
		0.f+ currentY,
		450.f+ currentX,
		450.f+ currentY
	);

	renderTarget->DrawBitmap(bitmap, rc_b, 1.0f, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, rc_bitmap);

	renderTarget->EndDraw();

程序结束时清理资源

	if (brush != nullptr)
		brush->Release();
	if (renderTarget != nullptr)
		renderTarget->Release();
	if (factory != nullptr)
		factory->Release();
	if (pIWICFactory != nullptr)
		pIWICFactory->Release();

	if (bitmap != nullptr)
		bitmap->Release();


示例项目地址:下载




猜你喜欢

转载自blog.csdn.net/qq_26559913/article/details/77968835