打印/图形问题

Posted

技术标签:

【中文标题】打印/图形问题【英文标题】:Printing / Graphics Problems 【发布时间】:2013-02-08 08:51:57 【问题描述】:

语言: VB .NET 2010 赢表

范围: 我开发了一个标签打印程序,旨在将自定义标签打印到斑马打印机。当我尝试将整个标签打印为图像时,打印机的清晰度出现问题,因此我尝试将标签中的所有文本存储到数组中,清除标签,将剩余图像发送到打印机,然后根据存储的数组覆盖新文本。此结果旨在将文本而不是图像发送到打印机。

问题: 生成的标签对于我想要的文本非常清晰,但是我在对齐打印方法时遇到了麻烦。对于测试,我将原始图像与顶部的覆盖文本一起显示,它们应该完全对齐或在合理范围内接近。这样做的结果是它们没有对齐。

测试:

    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 相比改进了结果。然而,当使用这个时,结果似乎是从原来的一些未知的比例因子缩放...

下面是原始顶部的叠加层:

【问题讨论】:

在创建新画笔之前,不要忘记处理旧画笔。 请注意,在屏幕上打印Rectangle 总是从(0,0) 开始,而不是在打印机上。检查打印矩形.Left.Top 属性并相应地偏移文本。 Margin bounds = (100,100) 和 Page bounds = (0,0) 所以我真的看不出相关性。 【参考方案1】:

您正在重新发现 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() 将文本呈现到窗口。它没有尝试使渲染的文本平滑缩放,它总是更喜欢适合像素网格。 WPF 的 idealdisplay 渲染模式相同,added in .NET 4。

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

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

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

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

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

【讨论】:

【参考方案2】:

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

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

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

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

【讨论】:

所以我假设您正在谈论 TextRenderer.DrawText 方法并尝试检查该方法的比例与打印机图形比例?我会尝试并发布结果。

以上是关于打印/图形问题的主要内容,如果未能解决你的问题,请参考以下文章

JSK-16014 打印字母图形打印图案

打印图形(第1届第1题)

java打印图形

C语言打印图形

如何在 Simulink Scope 中以编程方式“打印到图形”

2.1实现打印图形