使用 GDI 裁纸(“送纸和裁切”)?

发布于 2024-09-14 20:46:07 字数 187 浏览 8 评论 0原文

许多打印机都有“进纸和剪切”或“剪切纸张”命令(我指的是 POS - 打印机)。

由于使用 POS.NET 并不总是可行(可怕的驱动程序不兼容)并且 GDI 可以做更多事情,因此我们希望在使用 GDI 打印时也使用切纸机。

有办法这样做吗?可能在发出 EndDocument() 时?

或者甚至可能来自.NET?

Many printers have a "feed and cut" or "cut paper" command (I'm talking about POS - printers here).

Since using POS.NET is not always possible (horrific driver incompatibilities) and GDI can do so much more, we would like to utilize the paper cutter also when printing using GDI.

Is there a way to do so? Possibly when issuing EndDocument()?

Or maybe even from .NET?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

机场等船 2024-09-21 20:46:07

GDI 甚至抽象的 Windows 打印模型可能无法为您提供帮助。您必须以打印机通常接收数据的语言将送纸和剪切命令发送到打印机。

例如,Epson TM-T88III 热敏收据打印机 使用 ESC/POS本地语言,而不是 GDI 或 PCL 命令序列。然而,大多数这些打印机都附带了打印机驱动程序,使 Windows 将它们视为常规 GDI 打印机。这些驱动程序通常的工作方式是,它们将所有 GDI 命令光栅化为软件中的一张大位图,然后将位图分配给打印机,通过其本机语言“打印位图”命令进行打印。这通常会产生不太理想的效果:

  • 将大量位图数据发送到打印机比它知道如何解释的一系列二进制命令的效率要低得多(从所需的时间和传输的数据来看)。 (您愿意发送要打印的文本图像,还是仅发送实际文本和字体大小规范?类似于 HTML/CSS 与文本图像。)
  • 这些打印机通常具有低分辨率并且是单色的(即,所有黑色或全白,无灰度或彩色)。他们的预加载字体旨在在这些限制下很好地工作,以实现清晰的渲染。通过光栅化为位图,我们失去了这种仔细的设计,因为像素被捕捉并舍入网格,导致实际打印输出上呈现锯齿状文本。如果您正在尝试绘制对这种舍入非常敏感的东西(例如条形码),那么您就是 SOL,除非您在使用 GDI 时煞费苦心地记住打印机设备上下文的 DPI。

例如,以下是 我通常不相关的博客上的广泛示例。您可以在接近尾声时看到我如何用必要的字节序列填充 BinaryWriter,这些字节序列等于 Epson 热敏收据打印机上的“进纸并剪切”命令(AsciiControlChars 是只是一个带有常量的静态类):

        using (var ms = new MemoryStream())
        using (var bw = new BinaryWriter(ms))
        {
            // Reset the printer bws (NV images are not cleared)
            bw.Write(AsciiControlChars.Escape);
            bw.Write('@');

            // Render the logo
            RenderLogo(bw);

            // Feed 3 vertical motion units and cut the paper with a 1 point cut
            bw.Write(AsciiControlChars.GroupSeparator);
            bw.Write('V');
            bw.Write((byte)66);
            bw.Write((byte)3);

            bw.Flush();

            return ms.ToArray();
        }

然后,您可以将字节作为 RAW 文档直接发送到打印机,可以使用该文章末尾的代码(该代码适用于各种 Win32 打印机函数),也可以使用 Microsoft 的 RawPrinterHelper 类

您需要查找特定于您的打印机的命令。很可能它与您在这里看到的没有太大不同:POS 语言开始标准化,但这也就像说 SQL 是一种标准——人类可以相互理解,但如果不进行一些调整就不能真正实现互操作。

如果您确实仍想使用 GDI,则可以以通常的方式将 GDI 文档打印到打印机(再次假设 GDI 打印机驱动程序存在,这很可能是存在的),然后将第二个较小的 RAW 文档发送到包含本机进纸和剪切命令的打印机。 (或者,某些 GDI 打印机驱动程序允许您在打印机控制面板中指定“始终在打印文档后进行剪切”——但祝您好运,以编程方式以有据可查的方式访问该驱动程序功能!)

希望这有助于绘制一个GDI 与 POS 打印机的关系图。

GDI and even the abstract Windows printing model are probably not going to help you here. You're going to have to send the feed and cut command to the printer in the language that it expects to typically receive data.

For example, an Epson TM-T88III thermal receipt printer speaks the ESC/POS language natively, not a sequence of GDI or PCL commands. However, most of these printers do come with printer drivers that make Windows see them as regular GDI printers. The way these drivers typically work is that they rasterize all of the GDI commands into one big bitmap in software, and then dole out the bitmap to the printer for printing via its native-language "print the bit-image" command. This usually has less-than-desirable effects:

  • It is much less efficient (in sense of time required and data transmitted) to send a lot of bitmap data to the printer than a sequence of binary commands that it knows how to interpret. (Would you rather send an image of text to print, or just the actual text and a font size specification? Analogies with HTML/CSS vs. an image of text.)
  • These printers typically have low resolutions and are monochrome (that is, all black or all white, no grayscale or color). Their pre-loaded fonts are designed to work well under these limitations for crisp, clear rendering. By rasterizing to a bitmap, we lose this careful design as pixels are snapped and rounded off of the grid, resulting in jagged text rendering on the actual printout. If you're trying to draw something that's really sensitive to this kind of rounding, like a barcode, you're SOL, unless you're painstakingly keeping the DPI of the printer device context in mind while working with GDI.

For example, here is a snippet of code from an extensive example on my usually-irrelevant blog. You can see near the end how I fill the BinaryWriter with the necessary sequence of bytes that equals the "feed paper and cut" command on our Epson thermal receipt printer (AsciiControlChars is just a static class with constants):

        using (var ms = new MemoryStream())
        using (var bw = new BinaryWriter(ms))
        {
            // Reset the printer bws (NV images are not cleared)
            bw.Write(AsciiControlChars.Escape);
            bw.Write('@');

            // Render the logo
            RenderLogo(bw);

            // Feed 3 vertical motion units and cut the paper with a 1 point cut
            bw.Write(AsciiControlChars.GroupSeparator);
            bw.Write('V');
            bw.Write((byte)66);
            bw.Write((byte)3);

            bw.Flush();

            return ms.ToArray();
        }

You can then just send the bytes directly to the printer as a RAW document, either using the code at the end of that article, which works against various Win32 printer functions, or Microsoft's RawPrinterHelper class.

You'll need to look up the commands specific for your printer. Chances are that its not too different from the one that you see here: POS languages are beginning to standardize, but that's also like saying SQL is a standard--mutually intelligible by humans but not really interoperable without some adjustments.

If you really still want to use GDI, you can print the GDI document in the usual way to the printer (again, assuming that a GDI printer driver exists, which it probably does), and then issue a second, small, RAW document to the printer that contains the native feed and cut command. (Alternatively, some of the GDI printer drivers let you specify "always cut after printing a document" right in the Printers control panel--but good luck accessing that driver feature in a well-documented fashion programmatically!)

Hope this helps to paint a picture of GDI's relationship to POS printers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文