c++ - GDI+ 图形对象 - 使用 GDI 直接绘制到 DC 时抗锯齿丢失

标签 c++ gdi+ gdi

我们目前正在将一个较旧的应用程序转换为通过 GDI+ 绘制,而不是直接使用 GDI。随着我们逐步翻译系统,有时我们需要从 Gdiplus::Graphics 对象中获取 HDC,以便允许尚未翻译的代码使用 GDI 直接绘制到它。

绘图进行得很好,除了我们似乎在使用 GDI 直接绘制到 DC 的图像上丢失抗锯齿。如果在从 Graphics 对象获取 DC 之后,我们在整个区域上绘制一个填充的矩形,然后继续绘制,结果会很好。如果我们直接开始绘制,所有内容都没有抗锯齿。

void Draw(Gdiplus::Graphics& renderContext)
{
    auto hdc = renderContext.GetHDC();
    auto dc = HDC::FromHandle(nativeDC);

    //Required to antialias drawing below
    dc->FillSolidRect(GetClientRect(), RGB(255, 255, 255));
    /* Do Drawing */

    dc ->Detach();
    renderContext.ReleaseHDC(hdc );
}

更准确地说,似乎抗锯齿 alpha 变平了,这解释了为什么在绘制之前在 GDI 中填充矩形可以消除伪影。 如果您在一个位图上使用抗锯齿绘制,然后尝试在另一个位图的顶部对其进行字母混合,则可能会得到类似的效果 - 顶部的 alpha 信息被展平,然后将 ColorMatrix 中指定的新 alpha 值应用于整个图像。

如果有人能深入了解当您从图形对象中获取/释放 HDC 时到底发生了什么,以及为什么使用 GDI 绘图会直接失去 alpha,我将不胜感激。

最佳答案

支持 HDC 的位图是一个拷贝,而不是原始的,如 described here .

Using GDI on a GDI+ Graphics Object Backed by a Bitmap

When Graphics::GetHDC() is called for a Graphics object that is backed by a bitmap rather than the screen, a memory HDC is created and a new HBITMAP is created and selected into the memory HDC. This new memory bitmap is not initialized with the original bitmap's image but rather with a sentinel pattern, which allows GDI+ to track changes to the bitmap. Any changes that are made to the memory bitmap through the use of GDI code become apparent in changes to the sentinel pattern. When Graphics::ReleaseHDC() is called, those changes are copied back to the original bitmap... Also, there is a performance cost to this approach because GDI+ must copy the changes back to the original bitmap.

很明显,当您使用 GDI 在 HDC 上绘图时,您不会获得任何抗锯齿功能。 GDI 不支持它。这就是 GDI+ 的用途。

关于c++ - GDI+ 图形对象 - 使用 GDI 直接绘制到 DC 时抗锯齿丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32885417/

相关文章:

c# - GDI+ 异常将位图保存到 MemoryStream

c++ - Win32 - 读取桌面像素的最快方法

c++ - CImage::Draw() 绘制黑色图片

c++ - 为什么这段代码没有在二叉搜索树中插入节点

c++ - 类构造函数 : unresolved externals

c++ - BitBlt 问题 GDI

白色背景的 JPG 的 GDI+ DrawImage 不是白色

windows - 加载一定分辨率的光标

c++ - 无法使用Xcode通过boost成功编译

c++ - 使用 invoke_result 的正确方法?