Search code examples
androidprintingbitmapescpos

Print real custom size bitmap using esc/pos termal printer Android


I want to print a ScrollView using Datecs Termal printer. The view is a ticket like as a purchase ticket. I want to measure exactly 300 mm height in the paper. I using this method to convert Scrollview to Bitmap:

public static Bitmap getBitmapFromView(View view, int height, int   width) {
    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(bitmap);
    Drawable bgDrawable = view.getBackground();
    canvas.drawColor(Color.WHITE);
    if (bgDrawable != null)
        bgDrawable.draw(canvas);
    else
        canvas.drawColor(Color.WHITE);
    view.draw(canvas);

    return bitmap;
}

The problem is when hidden or show textviews, change height of Bitmap. In addition it also changes size depending on the density of the screen. I want to fill the 300 mm of paper with the view and blank spaces.

I have try two solutions:

-Feed paper as many lines as there is difference between the height of the view and 300mm

-Generate bitmap to heigh is exactly 300mm.

I could not do it in any way.

Datecs sdk contain this method to feed paper:

public void feedPaper(int lines) throws IOException {
    if (lines >= 0 && lines <= 255) {
        byte[] buf = new byte[]{27, 74, (byte)lines};
        synchronized(this) {
            this.write(buf);
        }
    } else {
        throw new IllegalArgumentException("The lines is out of range");
    }
}

But I do not know the relation between the height of the bitmap, the height of each line and the 300 mm of the paper.

Can anybody help me? Thank you very much!


Solution

  • There are three elements to your question:

    • What size to make the bitmap for it to print at 300mm tall.
    • How to get the bitmap to that size
    • How to pad the print with the correct amount of whitespace if it's not tall enough.

    What size to make the bitmap

    How many pixels do I want for a 300mm high print?

    To determine how many dots create an image of a specific size on paper (in millimetres), you need to know what density it will be printed at (measured in "DPI" or "DPMM"). For thermal printers, this is not user-selectable, and you can find the metric in the data sheet for your printer.

    For example, the DPP-250 data sheet lists a density of 8x8 DPMM, meaning 8 dots per millimetre vertically and 8 dots per millimetre horizontally.

    300mm × 8 dots/mm = 2400 dots
    

    On the same printer, the printing width is 48mm (384 dots), so you would aim to generate a 384x2400 pixel image to send to the printer for 48x300mm print.

    Until you have this part working, you can remove Android and your printer driver from your stack. Standalone command-line tools can convert images to ESC/POS code for you to debug, so take a laptop, twg/png2escpos, and a USB cable to your printer as the correct way to see how different-sized images display on your printer.

    I don't know how similar this printer is to yours, adjust these numbers to match your printer's data sheet.

    How to get the bitmap to that size

    If the View is making a Bitmap of the wrong size, then you should either scale it, or generate something of the correct size in the background. Focus on scaling the width while maintaining the aspect ratio, and then padding the bottom with whitespace (either in the image, or as a series of blank lines).

    There are other answers on StackOverflow which address image scaling better than I can, such as this one.

    How to pad the print with the correct amount of whitespace

    For padding, you are right to use blank lines instead of extending the image, because it's faster to print a blank line!

    Default line spacing is not specified in the data sheet I linked. If you want an estimate, use 32 dots (4mm), but for an accurate answer, you will want to print a few lines of underscores and measure how much space is between them.

    Note that it's not always possible to add increments of 32 up to a round 300mm, so either:

    • Pad the image with approximately the correct number of blank lines, and be happy with approximation, or
    • Pad the image with whitespace to a multiple of 32 pixels, then add blank lines.

    Once you have scaled your image to 384 pixels wide and know your line spacing, then this does not change between devices.

    For example, to pad an image that is 1234 pixels tall with 32-pixel blank lines, in order to make it 2400 pixels tall, you need about 36 lines: lines:

    (2400 dots - 1234 dots) ÷ 32 dots/line ≈ 36 lines
    

    Again, these numbers are not for your printer, adjust them based on your own data sheet and line height measurement, as described above.