4

语言: 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

..对上面显示的打印图形执行此操作会导致错位...

欢迎任何想法,因为我会尝试任何事情。我猜测打印图形正在做一些我不知道的普通图形的附加操作。


我确实注意到 TextRenderer.DrawText 与 DrawString 相比改进了结果。然而,当使用这个时,结果似乎是从原始的一些未知的比例因子缩放...

下面是原始顶部的结果叠加层: 在此处输入图像描述

4

2 回答 2

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);
    }
}

看起来像这样:

在此处输入图像描述

再多的魔法都不会让你在字符串中字母 i 之间的间距突然改变的部分重叠。GDI+ 是微软首次尝试独立于分辨率的文本渲染,但效果并不好。这是一个很好的公司,WPF 是第二次尝试,它在模糊输出方面受到了很多批评。解决方法与在 .NET 2.0 for Winforms 中修复的方法类似,您应该始终使用 TextRenderer.DrawText() 将文本呈现到窗口。它没有尝试使渲染的文本平滑缩放,它总是更喜欢适合像素网格。在 .NET 4 中添加的WPF 的理想显示渲染模式也是如此。

您的方法还有其他重大问题,文本的呈现方式明显不适合打印机。您可以看到,当您放大时可以看到像素,SysInternals 的 ZoomIt 实用程序非常适合。我放大了右侧图形中的字母 a:

在此处输入图像描述

注意字母形状边缘的红色和蓝色像素。这是一种称为ClearType的抗锯齿技术,它增强了 LCD 显示器的感知分辨率。它只适用于 LCD 面板,不适用于没有相同条纹图案的打印机。在纸上,这封信看起来很模糊,带有彩色边缘。尽管它在 Zebra 打印机上并没有那么糟糕,因为它不支持彩色打印。

这些是特定于将文本呈现到显示器、分辨率相当差的设备的工件。像素网格拟合和 ClearType 是使文本看起来不错的技巧。典型的监视器每英寸不超过约 120 个像素。尽管随着苹果对“视网膜”显示器的推动,这最终得到了改善。一家拥有高分辨率显示器的公司,他们传统上以“理想”模式呈现文本。

这些渲染技巧完全不适用于具有更高分辨率的打印机。每英寸 600 像素是典型的,比显示器好 5 倍。通过在打印机上绘制图片框实际上是在浪费直接在打印机上绘制时所获得的改进。它们的差异非常显着,并且很容易用肉眼看到。当您以 600 dpi 渲染文本时,文本看起来更加美观和清晰。最初以 120 dpi 渲染并为打印机放大的文本看起来“臃肿”且粗糙。

始终使用 PrintDocument 类绘制到打印机。

于 2013-03-02T23:45:42.473 回答
1

很久以前,我编写了一个用于将标签打印到 Zebra 打印机的应用程序,所以也许我可以提供帮助。过去我们只有 ZPL2 API,只有打印的文本和简单的图形,没有这些图像的东西。反正...

我怀疑这是一个扩展问题。这可能解释了为什么您的原始图像模糊 - 也许打印机正在自动尝试缩放以适合标签,并且做得很差?当然,这可以解释上面显示的结果标签。

你上面的代码让我印象深刻的是你如何获得 Graphics 对象。一张来自画框;另一个大概来自打印机。请记住,Graphics 对象是设备相关的。也就是说,它的属性及其打印方式取决于您是打印到特定控件(不同的控件可以有不同的缩放比例)还是打印到特定的打印机。

您是否尝试过使用现有代码打印到激光打印机?看到结果可能会很有趣。另请参阅图形属性,例如 ScaleTransform。

于 2013-02-28T17:52:11.727 回答