使用GDI +旋转位图,然后转换为HDC

时间:2018-09-22 23:17:05

标签: c++ winapi bitmap drawing gdi+

我正在尝试按照标题说的做。

下面是应该返回带有旋转图标的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;

1 个答案:

答案 0 :(得分:0)

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);应该被修改为返回旧的位图句柄。最后应恢复旧手柄。