c++ - 使用 GDI+ 旋转位图然后转换为 HDC
问题描述
我正在尝试做标题所说的。
下面是应该返回带有旋转图标的 HDC 的代码。我不确定为什么它没有返回任何东西。当我尝试绘制返回的 HDC 时,什么都没有出现,而且我测试它不是我的绘图中的错误。
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Gdiplus::Bitmap SrcBitmap(L"H:\\Company\\iOG\\blue_arrow.tif", FALSE);
Gdiplus::Graphics DstGraphics(&SrcBitmap);
Gdiplus::REAL angle = lAngle;
DstGraphics.ResetTransform();
DstGraphics.RotateTransform(angle);
DstGraphics.TranslateTransform(SrcBitmap.GetWidth() / 2.0f, SrcBitmap.GetHeight() / 2.0f, Gdiplus::MatrixOrderAppend);
DstGraphics.DrawImage(&SrcBitmap, -((INT)SrcBitmap.GetWidth() / 2), -((INT)SrcBitmap.GetHeight() / 2), SrcBitmap.GetWidth(), SrcBitmap.GetHeight());
HBITMAP hBmp;
SrcBitmap.GetHBITMAP(Gdiplus::Color::Transparent, &hBmp);
HDC dcIcon = CreateCompatibleDC(NULL);
SelectObject(dcIcon, hBmp);
return dcIcon;
解决方案
Gdiplus::Bitmap::GetHBITMAP
创建一个新的位图句柄。当不再需要此句柄时,应将其删除。上面代码的设置方式,位图句柄丢失,无法清理。这将导致资源泄漏,程序最终将停止工作。
您应该在修改图像的位图句柄之后,而不是在绘制该位图的设备上下文之后。您可以按如下方式修改代码:
HBITMAP convert(const wchar_t* filename, UINT& w, UINT& h)
{
Gdiplus::Bitmap src(filename, FALSE);
if(0 != src.GetLastStatus())
return NULL;
w = src.GetWidth();
h = src.GetHeight();
Gdiplus::Graphics gr(&src);
gr.ResetTransform();
gr.RotateTransform(45);
gr.TranslateTransform(w / 2.0f, h / 2.0f, Gdiplus::MatrixOrderAppend);
gr.DrawImage(&src, -(INT)w / 2, -(INT)h / 2);// , w, h);
HBITMAP hbitmap = NULL;
src.GetHBITMAP(Gdiplus::Color::Transparent, &hbitmap);
return hbitmap;
}
void draw(HDC hdc)
{
UINT w, h;
HBITMAP hbitmap = convert(L"filename.bmp", w, h);
if(hbitmap)
{
HDC memdc = CreateCompatibleDC(hdc);
auto oldbmp = SelectObject(memdc, hbitmap);
BitBlt(hdc, 0, 0, w, h, memdc, 0, 0, SRCCOPY);
SelectObject(memdc, oldbmp);
DeleteDC(memdc);
DeleteObject(hbitmap);
}
}
此外,调用GdiplusStartup
应该以GdiplusShutdown
SelectObject(dcIcon, hBmp);
应修改为返回旧的位图句柄。旧手柄应在最后恢复。
推荐阅读
- python-3.x - filedialog 不显示顶部的窗口
- laravel - 如何修复“GET css/app.css net::ERR_ABORTED 404(未找到)”?
- xamarin - 未找到 JetBrains Rider 的 Xamarin SDK
- android - 我无法在未解决的参考中找出错误
- razor - 如何用foreach编写复选框?
- regex - 用正则表达式替换进行它的单词
- python - MySQL游标使用最后一个游标更新所有列
- android - 为什么 contentResolver.query() 返回 null?
- vue.js - 无法使用 JsPdf 导出 pdf
- python - 如何使用 argparse 以 xml 格式传递参数?