语言: VB .NET 2010 Win Form
范围: 我开发了一个标签打印程序,用于打印斑马打印机的自定义标签。当我尝试将整个标签作为图像打印时,打印机的清晰度出现问题因此我试图将标签中的所有文本存储到数组中,清除标签,将剩余的图像发送到打印机,以及根据存储的数组叠加新文本。此结果旨在将文本发送到打印机而不是图像。
问题: 由此产生的标签对于文本非常清晰,因为我想要它但是我的打印方法对齐时遇到了麻烦。对于测试,我将显示原始图像,顶部有覆盖文本,它们应完全对齐或在合理范围内关闭。这样做的结果是它们没有对齐。
测试
Dim g2 As Graphics
g2 = Form1.PictureBox2.CreateGraphics
g2.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
g2.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
g2.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
g2.Clear(Color.White)
g2.DrawImage(largeimage, New Point(0, 0))
Dim myBrush As Brush
Dim i As Integer = 0
Do Until i = label_array.Count - 1
myBrush = New SolidBrush(label_array(i).ForeColor)
g2.DrawString(label_array(i).Text, label_array(i).Font, myBrush, label_array(i).Location)
i = i + 1
Loop
在打印方法中,我使用上述方法将叠加和图像输出到图片框。当这样做时,它工作,但是......
e.Graphics.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
e.Graphics.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
e.Graphics.Clear(Color.White)
e.Graphics.DrawImage(largeimage, New Point(0, 0))
i = 0
Do Until i = label_array.Count - 1
myBrush = New SolidBrush(label_array(i).ForeColor)
e.Graphics.DrawString(label_array(i).Text, label_array(i).Font, myBrush, label_array(i).Location)
i = i + 1
Loop
..对上面显示的打印图形进行操作会导致错位...
欢迎任何想法,因为我会尝试任何事情。我猜测打印图形正在做一些我不知道的普通图形。
我注意到与DrawString相比,TextRenderer.DrawText改善了结果。然而,当使用它时,结果似乎是通过一些未知的缩放因子从原始缩放...
以下是原始叠加层:
答案 0 :(得分:2)
您正在重新发现Graphics.DrawString()的一个众所周知的问题,它不是准确。这个问题的最具代表性的示例是Winforms表格样本:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e) {
e.Graphics.DrawString("Hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
this.Font, Brushes.Black, 0, 0);
}
}
看起来像这样:
任何数量的魔法都不会让你在字符串中突然改变字母之间的间距重叠。 GDI +是微软首次尝试解决独立文本渲染问题,但效果并不理想。这是一个很好的公司,WPF是第二次尝试,它有很多模糊输出的高手。解决的方式类似于在.NET 2.0 for Winforms中修复的方式,您应始终使用TextRenderer.DrawText()将文本呈现到窗口。这并不试图使渲染文本平滑地缩放,它总是更喜欢适合像素网格。 WPF的理想 vs 显示渲染模式added in .NET 4也是如此。
您的方法存在重大的其他问题,呈现文本的方式非常不适合打印机。您可以看到,当您放大时可以看到像素,SysInternals的ZoomIt实用程序对此有好处。我放大右手边图中的字母a:
请注意字母边缘的红色和蓝色像素。这是一种称为ClearType的抗锯齿技术,它增强了LCD监视器的感知分辨率。它只适用于LCD面板,它不可以在不具有相同条纹图案的打印机上工作。在纸面上,这封信看起来很模糊,带有彩色条纹。虽然它在Zebra打印机上并没有那么糟糕,因为它不支持彩色打印。
这些是专门用于向监视器渲染文本的工件,这些设备的分辨率相当低。像素网格拟合和ClearType是使文本看起来不错的技巧。典型的监视器每英寸不超过约120个像素。尽管苹果推出了“视网膜”显示屏,但这种情况最终有所改善。这是一家与高分辨率显示器有利害关系的公司,他们传统上提供文字in "ideal" mode。
这些渲染技巧完全不适合打印机,这是一种分辨率更高的设备。每英寸600像素是典型的,比显示器容易5倍。通过将图片框绘制到打印机,您实际上浪费直接绘制到打印机时所获得的改进。它们的差异非常显着,用肉眼很容易看出来。当您以600 dpi渲染文本时,文本看起来更加美观和清晰。最初为120 dpi渲染并为打印机放大的文本看起来像“blobby”和粗糙。
始终使用PrintDocument类绘制到打印机。
答案 1 :(得分:1)
很久以前我写了一个打印标签到Zebra打印机的应用程序,所以也许我可以提供帮助。在当天我们只有ZPL2 API,只有印刷文字和简单图形,没有这个图像的东西。总之...
我怀疑这是一个扩展问题。这可能解释了为什么你的原始图像是模糊的 - 也许打印机会自动尝试缩放它以适应标签,并且做得不好?当然,这可以解释上面显示的结果标签。
上面的代码让我感到震惊的是你如何获得Graphics对象。一个来自图片框;另一个可能来自打印机。请记住,Graphics对象取决于设备。也就是说,它的属性和打印方式取决于您是打印到特定控件(不同的控件可以有不同的缩放)还是打印到特定的打印机。
您是否尝试过使用现有代码打印到激光打印机?看到结果可能会很有趣。另请参见图形属性,例如ScaleTransform。