GDI+ Graphics Obj - 使用 GDI 直接绘制到 DC 时消除锯齿丢失
Posted
技术标签:
【中文标题】GDI+ Graphics Obj - 使用 GDI 直接绘制到 DC 时消除锯齿丢失【英文标题】:GDI+ Graphics Obj - antialias lost when drawing straight to DC with GDI 【发布时间】:2015-12-29 09:07:15 【问题描述】:我们目前正在将旧应用程序转换为通过 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 中填充一个矩形会消除伪影。 如果您在一个位图上绘制抗锯齿,然后尝试在另一个位图上进行 alphablend 混合,您可能会得到类似的效果 - 顶部的 alpha 信息被展平,然后在 ColorMatrix 中指定的新 alpha 值应用于整个图像。
如果有人能提供一些见解,了解当您从图形对象中获取/释放 HDC 时究竟发生了什么,以及为什么使用 GDI 绘图会直接丢失 alpha,我将不胜感激。
【问题讨论】:
图像没有抗锯齿。如果图像包含透明像素(alpha 【参考方案1】:支持 HDC 的位图是副本,而不是原件,如 described here。
在位图支持的 GDI+ 图形对象上使用 GDI
当为支持的 Graphics 对象调用 Graphics::GetHDC() 时 通过位图而不是屏幕,创建了一个内存 HDC,并创建了一个新的 HBITMAP 被创建并选择到内存 HDC 中。这段新记忆 位图不是用原始位图的图像初始化的,而是 带有哨兵模式,它允许 GDI+ 跟踪对 位图。通过使用对内存位图所做的任何更改 GDI 代码的变化在哨兵模式的变化中变得明显。什么时候 Graphics::ReleaseHDC() 被调用,这些更改被复制回 原始位图......此外,这种方法存在性能成本,因为 GDI+ 必须将更改复制回原始位图。
显然,当您使用 GDI 在 HDC 上绘图时,您不会获得任何抗锯齿功能。 GDI 不支持它。这就是 GDI+ 的用途。
【讨论】:
以上是关于GDI+ Graphics Obj - 使用 GDI 直接绘制到 DC 时消除锯齿丢失的主要内容,如果未能解决你的问题,请参考以下文章
C# 获取指定 “QQ头像“ 绘制 “圆形头像框“GDI(Graphics)
C# 使用GDI(Graphics)绘制 应用 网站 “登录验证码“