【问题标题】:TransparentBlt Produces a Non-Sharp ImageTransparentBlt 产生不清晰的图像
【发布时间】:2013-07-10 20:25:09
【问题描述】:

我正在使用FillRectangle 方法将文本(使用TextRenderer.DrawText)渲染到一个背景为纯白色(Color.White)的位图上。 然后我将TransparentBlt这个Bitmap放到一个包含彩色背景图片的内存DC上,使用Color.White And &HFFFFFF作为透明色的RGB值(crTransparent参数),如下:

TransparentBlt(hDestMemDc, 0, 0, iTextWidth, iTextHeight, hTextMemDc, 0, 0, iTextWidth, iTextHeight, Color.White.ToArgb() And &HFFFFFF)

{ 然后我将BitBlt 组合图像放到我的控件表面上,但这并不重要}

虽然呈现的文本清晰明了,但其TransparentBlt 结果清晰。

这是文本的快照,呈现在白色背景上(这是一张图片,不是输入文本):

这是在彩色背景上对上面的图像进行 Trans-Blitting 的结果:

请注意白色(待透明)点仍在红色文本周围。

此外,请注意在图像左侧绘制的白色垂直线,以及在右上角绘制的类似较短的水平线。

我正在使用 VB.NET 2005(又名 VB8)。非常感谢您的建议。

【问题讨论】:

  • 看起来像字体平滑。你是如何渲染文本的?
  • oGraphics.CompositingQuality = Drawing.Drawing2D.CompositingQuality.HighQuality oGraphics.InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic oGraphics.SmoothingMode = Drawing.Drawing2D.SmoothingMode.HighQuality oGraphics.TextContrast = 0 oGraphics.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
  • Dim sRect As Rectangle = New Rectangle(0, 0, m_sTextSize.Width, m_sTextSize.Height) Dim oBrush As Brush = New SolidBrush(const_sTextBackColor) oGraphics.FillRectangle(oBrush, sRect) TextRenderer.DrawText(oGraphics, Me.Text, Me.Font, sRect, Me.ForeColor, const_sTextBackColor, m_eTextFormatFlags) 如果确实是这个原因,那么渲染的结果(上图)如何锐利?

标签: .net winapi transparency bitblt bitblit


【解决方案1】:

文本抗锯齿/ClearType 意味着并非所有文本都以相同的颜色呈现。文本的外部像素与绘制它们的背景颜色混合,具有平滑边缘的效果。因此,您无法在一种背景颜色上渲染文本,将其剪掉,并期望它在另一种背景下看起来也一样好。

您可以在渲染文本时禁用抗锯齿,但结果看起来也不会那么好。

相反,您应该在内存中制作最终目标位图的副本,在其上渲染文本,然后将其再次blit 返回屏幕。

【讨论】:

  • 首先 - 感谢您的教育性回答。这是有义务的。我没有提到这个的应用,它是一个文本滚动器。我使用 blitting 作为一种更高效的 CPU 方法。如果我必须每 20[mSec] 向上渲染一个像素,我就会失去 blitting 的 CPU 消耗优势(我尝试过)。有什么想法吗?
  • 您可以尝试使用透明窗口(即使用WS_EX_LAYERED 创建并使用UpdateLayeredWindow 更新的窗口),然后将文本直接渲染到该窗口,但您仍然需要重新绘制文本每次。或者尝试两个分层的窗口,都是屏幕的宽度 - 然后移动窗口本身以获得滚动效果,但我不知道这在 CPU 使用率方面是否会更好。
  • OnPaint event-handler-function 中的文本渲染(通过在每个计时器滴答时调用 Refresh() 间接调用)和 text- 之间预期的(CPU 使用)性能差异在 timer-tick 处理函数本身内渲染(之后也会将结果传送到控件的表面)?
  • 可能不是很明显,OnPaint 可能会稍微少一些,因为 WM_PAINT 消息仅在队列中没有其他消息时才会发送,但实际上不会有太大差异。
  • 我已经形成了一个内存-DC(使用CreateCompatibleDC),我正在将背景图像放在上面。我现在想试试你的建议,在它上面渲染文本(然后将组合图像blit到控制表面)。 TextRenderer.DrawText 函数如何与 memory-DC 一起使用?它的第一个参数是System.Drawing.IDeviceContext 类型,而内存-DC 是IntPtr 类型。
猜你喜欢
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 2017-07-21
  • 1970-01-01
  • 1970-01-01
  • 2011-07-21
  • 2011-08-16
  • 1970-01-01
相关资源
最近更新 更多