简体   繁体   English

使用ESC / POS打印位图全页宽度

[英]Print bitmap full page width using ESC/POS

I am currently implementing Android PrintService, that is able to print PDFs via thermal printers. 我目前正在实现Android PrintService,该服务能够通过热敏打印机打印PDF。 I managed to convert PDF to bitmap using PDFRenderer and I am even able to print the document. 我设法使用PDFRenderer将PDF转换为位图,甚至可以打印文档。

The thing is, the document (bitmap) is not full page width. 问题是,文档(位图)不是完整的页面宽度。

I am receiving the document in 297x420 resolution and I am using printer with 58mm paper. 我正在以297x420分辨率接收文档,并且正在使用58mm纸张的打印机。

This is how I process the document (written in C#, using Xamarin): 这是我处理文档(使用Xamarin用C#编写)的方式:

// Create PDF renderer
var pdfRenderer = new PdfRenderer(fileDescriptor);  

// Open page
PdfRenderer.Page page = pdfRenderer.OpenPage(index);

// Create bitmap for page
Bitmap bitmap = Bitmap.CreateBitmap(page.Width, page.Height, Bitmap.Config.Argb8888);

// Now render page into bitmap
page.Render(bitmap, null, null, PdfRenderMode.ForPrint);

And then, converting the bitmap into ESC/POS: 然后,将位图转换为ESC / POS:

// Initialize result
List<byte> result = new List<byte>();

// Init ESC/POS
result.AddRange(new byte[] { 0x1B, 0x33, 0x21 });

// Init ESC/POS bmp commands (will be reapeated)
byte[] escBmp = new byte[] { 0x1B, 0x2A, 0x01, (byte)(bitmap.Width % 256), (byte)(bitmap.Height / 256) };

// Iterate height
for (int i = 0; i < (bitmap.Height / 24 + 1); i++)
{
    // Add bitmapp commands to result
    result.AddRange(escBmp);

    // Init pixel color
    int pixelColor;

    // Iterate width
    for (int j = 0; j < bitmap.Width; j++)
    {
        // Init data
        byte[] data = new byte[] { 0x00, 0x00, 0x00 };

        for (int k = 0; k < 24; k++)
        {
            if (((i * 24) + k) < bitmap.Height)
            {
                // Get pixel color
                pixelColor = bitmap.GetPixel(j, (i * 24) + k);

                // Check pixel color
                if (pixelColor != 0)
                {
                    data[k / 8] += (byte)(128 >> (k % 8));
                }
            }
        }

        // Add data to result
        result.AddRange(data);
    }

    // Add some... other stuff
    result.AddRange(new byte[] { 0x0D, 0x0A });
}

// Return data
return result.ToArray();

Current result looks like this: 当前结果如下: 在此处输入图片说明

Thank you all in advance. 谢谢大家。

There is no magic "scale-to-page-width" command in the ESC/POS command-set, you need to know the max width of your printer, available in the manual, and then you can: ESC / POS命令集中没有神奇的“ scale-to-page-width”命令,您需要了解打印机的最大宽度(手册中提供),然后您可以:

  • Double the width and height for some image output commands -- You are using ESC * , which supports low-density, but height and width change in different ratios. 对于某些图像输出命令,将宽度和高度加倍-您正在使用ESC * ,它支持低密度,但是高度和宽度会以不同的比率变化。
  • Render the PDF wider to begin with - match the Bitmap size to the printer page width, and not the PDF page width. 首先将PDF渲染得更宽-将位图大小与打印机页面宽度匹配,而不是与PDF页面宽度匹配。 The same problem is solved at PDFrenderer setting scale to screen PDFrenderer设置屏幕缩放比例时解决了相同的问题
  • You can also simply stretch the image before you send it, if you are happy with the low quality. 如果您对低质量感到满意,也可以在发送图像之前先对其进行拉伸。 See: How to Resize a Bitmap in Android? 请参阅: 如何在Android中调整位图的大小?

Aside, your ESC * implementation is incorrect. 另外,您的ESC *实现不正确。 There are two bytes for the width- Check the ESC/POS manual for the correct usage, or read over the correct implementations in PHP or Python that I've linked in another question: ESC POS command ESC* for printing bit image on printer 宽度有两个字节-检查ESC / POS手册的正确用法,或阅读我在另一个问题中链接的PHP或Python的正确实现: ESC POS命令ESC *,用于在打印机上打印位图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM