【问题标题】:Can I improve on this code to draw outlined text我可以改进此代码以绘制轮廓文本吗
【发布时间】:2013-10-26 02:24:52
【问题描述】:

我正在使用 GDI+ 绘制一些带有黑色轮廓的白色文本。

我尝试使用图形路径,但效果不佳(尤其是使用小文本),因此我考虑在文本周围 8 个像素的位置渲染黑色文本,然后在顶部绘制白色。

结果是我想要的那种东西,但代码似乎没有那么高效。有没有更好的方法来达到同样的结果?

我的代码:

Private _whiteFont As New Font("Segoe UI", 8)
Private _blackFont As New Font("Segoe UI", 8)

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    DrawTextWithOutline("12", New Point(18, 9))
End Sub

Private Sub DrawTextWithOutline(ByVal text As String, ByVal pt As Point)
    Using g As Graphics = Me.CreateGraphics
        g.DrawString(text, _blackFont, Brushes.Black, pt.X - 1, pt.Y) 'left
        g.DrawString(text, _blackFont, Brushes.Black, pt.X, pt.Y + 1) 'top
        g.DrawString(text, _blackFont, Brushes.Black, pt.X + 1, pt.Y) 'right
        g.DrawString(text, _blackFont, Brushes.Black, pt.X, pt.Y + 1) 'bottom
        g.DrawString(text, _blackFont, Brushes.Black, pt.X - 1, pt.Y - 1) 'top left
        g.DrawString(text, _blackFont, Brushes.Black, pt.X - 1, pt.Y + 1) 'bottom left
        g.DrawString(text, _blackFont, Brushes.Black, pt.X + 1, pt.Y - 1) 'top right
        g.DrawString(text, _blackFont, Brushes.Black, pt.X + 1, pt.Y + 1) 'bottom right
        g.DrawString(text, _whiteFont, Brushes.White, pt)
    End Using
End Sub

示例结果:

【问题讨论】:

  • 我认为 GDI+ 中没有更好的方法,但如果您要使用较新的 System.Windows.Media 命名空间,您可以按照 MSDN 中题为“如何:创建大纲文本”的说明进行操作": msdn.microsoft.com/en-us/library/ms745816.aspx 不过他们的方法似乎比你的效率低​​。
  • 尝试在背景中绘制稍大的字体,然后在前面绘制较小的字体,这样您就只需调用两次 g.DrawString 而不是 8 次?
  • @DaiBok - 我最初尝试过(也先绘制粗体文本),但两者之间的差异可能大于或小于一个像素,因此无法将白色文本“居中”
  • 是的,我也确信它可能因字体而异。如果它需要是动态的,它可能需要更多的工作,但如果你可以坚持使用单一字体,也许你可以找到一个最佳的 - 字体大小和粗体的可能组合(粗体大小 10)?例如 Private _whiteFont As New Font("Segoe UI", 8) Private _blackFont As New Font("Segoe UI", 10)
  • 查看this solution,首先将adds the string 转换为GraphicsPath,然后分别绘制和填充该路径。

标签: .net vb.net gdi+ text-rendering


【解决方案1】:

您没有发布您的 GraphicsPath 尝试,但这个版本似乎画得不错。我使用粗体字体尝试在内部获得更多空白空间,并使用 2 像素黑色笔来获得轮廓:

e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
Using gp As New GraphicsPath, _
      f As New Font("Segoe UI", 8, FontStyle.Bold), _
      p As New Pen(Brushes.Black, 2)
  gp.AddString(text, f.FontFamily, f.Style, f.Size + 3, New Point(100, 40), _
               StringFormat.GenericTypographic)
  e.Graphics.DrawPath(p, gp)
  e.Graphics.FillPath(Brushes.White, gp)
End Using

美丽在旁观者的眼中:

【讨论】:

  • +1 感谢您抽出宝贵时间拉斯;您的解决方案似乎比我的图形路径尝试更好,但我认为我更喜欢我的版本并排查看它们。如果没有发布更好的解决方案,我会接受。
  • 我非常喜欢这个——前段时间我试图做轮廓,但暂时放弃了。一件奇怪的事情是,像黑色和蓝紫罗兰这样的深色轮廓颜色似乎会导致比深灰色更小的轮廓。这是一种视觉错觉,但看起来很奇怪。 (我画的是位图而不是表格)。
猜你喜欢
  • 1970-01-01
  • 2011-05-27
  • 1970-01-01
  • 1970-01-01
  • 2013-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多