What is wrong with my code? I can't print a Barcode or a Qrcode
I have a problem with a print that is compatible with ESC/POS commands, I print successfully texts and lines.
this is my model from : https://www.inputservice.com.br/leopardo-a8
and in the documentation, the print support:
Códigos de Barras (Barcode translating): EAN8, EAN13, CODE39, ITF, CODEBAR, CODE128, CODE93, UPC-A, UPC-E, PDF417* e QR CODE. Emulação (EMULATION): ESC/POS
I don't understand that if I want to print a barcode I need to transform the bar in an image? or not?
I found a tutorial to print large images, this is the link : http://new-grumpy-mentat.blogspot.com/2014/06/java-escpos-image-printing.html
I follow the tutorial but the image from my Qrcode or Barcode is not always good, see the picture :
Now see my code :
PrintCommands.java
package com.bravos.automap.Util.Print;
public class PrinterCommands {
public static final byte HT = 0x9;
public static final byte LF = 0x0A;
public static final byte CR = 0x0D;
public static final byte ESC = 0x1B;
public static final byte DLE = 0x10;
public static final byte GS = 0x1D;
public static final byte FS = 0x1C;
public static final byte STX = 0x02;
public static final byte US = 0x1F;
public static final byte CAN = 0x18;
public static final byte CLR = 0x0C;
public static final byte EOT = 0x04;
public final static char ESC_CHAR = 0x1B;
public final static byte[] LINE_FEED = new byte[]{0x0A};
public final static byte[] CUT_PAPER = new byte[]{GS, 0x56, 0x00};
public final static byte[] INIT_PRINTER = new byte[]{ESC_CHAR, 0x40};
public final static byte[] SET_LINE_SPACE_24 = new byte[]{ESC_CHAR, 0x33, 24};
public final static byte[] SET_LINE_SPACE_30 = new byte[]{ESC_CHAR, 0x33, 30};
public static final byte[] INIT = {27, 64};
public static byte[] FEED_LINE = {10};
public static byte[] SELECT_FONT_A = {27, 33, 0};
public static byte[] HEADER_FONT = {27, 33, 32};
public static byte[] FONT_3X = {0x1D, 0x21, 0x21};
public static byte[] FONT_2X = {0x1D, 0x21, 0x11};
public static byte[] FONT_1X = {0x1D, 0x21, 0x00};
// Bold
public static byte FONT_BOLD = ((byte)(0x8 | SELECT_FONT_A[2]));
// Height
public static byte FONT_HEIGHT = ((byte)(0x10 | SELECT_FONT_A[2]));
// Width
public static byte FONT_WIDTH = ((byte) (0x20 | SELECT_FONT_A[2]));
// Underline
public static byte FONT_UNDER = ((byte)(0x80 | SELECT_FONT_A[2]));
// Small
public static byte FONT_SMALL = ((byte)(0x1 | SELECT_FONT_A[2]));
public static byte[] SET_BAR_CODE_HEIGHT = {29, 104, 100};
public static byte[] PRINT_BAR_CODE_1 = {29, 107, 2};
public static byte[] SEND_NULL_BYTE = {0x00};
public static byte[] SELECT_PRINT_SHEET = {0x1B, 0x63, 0x30, 0x02};
public static byte[] FEED_PAPER_AND_CUT = {0x1D, 0x56, 66, 0x00};
public static byte[] SELECT_CYRILLIC_CHARACTER_CODE_TABLE = {0x1B, 0x74, 0x11};
public static byte[] SELECT_BIT_IMAGE_MODE = {0x1B, 0x2A, 33, (byte) 255, 3};
public static byte[] SELECT_BIT_IMAGE_MODE_OFI = {ESC_CHAR, 0x2A, 33};;
public static byte[] SELECT_BIT_IMAGE_MODE_V3 = {0x1B, 0x2A, 33, -128, 0};
public static byte[] SELECT_BIT_IMAGE_MODE_V4 = {0x1B, 0x2A, 33, 127, 0};
public static byte[] SELECT_BIT_IMAGE_MODE_V2 = {0x1B, 0x2A, 33};
public static byte[] SELECT_BIT_IMAGE_MODE_V5 = {0x1B, 0x2A, 33, 124, 1};
public static byte[] SET_LINE_SPACING_24 = {0x1B, 0x33, 24};
public static byte[] SET_LINE_SPACING_30 = {0x1B, 0x33, 30};
public static byte[] TRANSMIT_DLE_PRINTER_STATUS = {0x10, 0x04, 0x01};
public static byte[] TRANSMIT_DLE_OFFLINE_PRINTER_STATUS = {0x10, 0x04, 0x02};
public static byte[] TRANSMIT_DLE_ERROR_STATUS = {0x10, 0x04, 0x03};
public static byte[] TRANSMIT_DLE_ROLL_PAPER_SENSOR_STATUS = {0x10, 0x04, 0x04};
public static final byte[] ESC_FONT_COLOR_DEFAULT = new byte[] { 0x1B, 'r',0x00 };
public static final byte[] FS_FONT_ALIGN = new byte[] { 0x1C, 0x21, 1, 0x1B,
0x21, 1 };
public static final byte[] ESC_ALIGN_LEFT = new byte[] { 0x1b, 'a', 0x00 };
public static final byte[] ESC_ALIGN_RIGHT = new byte[] { 0x1b, 'a', 0x02 };
public static final byte[] ESC_ALIGN_CENTER = new byte[] { 0x1b, 'a', 0x01 };
public static final byte[] ESC_CANCEL_BOLD = new byte[] { 0x1B, 0x45, 0 };
/*********************************************/
public static final byte[] ESC_HORIZONTAL_CENTERS = new byte[] { 0x1B, 0x44, 20, 28, 00};
public static final byte[] ESC_CANCLE_HORIZONTAL_CENTERS = new byte[] { 0x1B, 0x44, 00 };
/*********************************************/
public static final byte[] ESC_ENTER = new byte[] { 0x1B, 0x4A, 0x40 };
public static final byte[] PRINTE_TEST = new byte[] { 0x1D, 0x28, 0x41 };
}
SendPrint.java ( this example is from my EAN_13 code, but is the same thing, just change to QRCODE
printerConstants = new PrinterConstants(mmOutputStream);
mmOutputStream.write(PrinterCommands.INIT);
mmOutputStream.write(PrinterCommands.ESC_ALIGN_CENTER);
printerConstants.printString("TESTANDO A FUNÇÃO");
mmOutputStream.write(PrinterCommands.FEED_LINE);
mmOutputStream.write(PrinterCommands.FEED_LINE);
printerConstants.setBold(true);
printerConstants.printString("TESTANDO A FUNÇÃO");
mmOutputStream.write(PrinterCommands.FEED_LINE);
printerConstants.resetToDefault();
String code = "7800000017106";
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
try {
BitMatrix bitMatrix = multiFormatWriter.encode(code, BarcodeFormat.EAN_13,200,80);
BarcodeEncoder barcodeEncoder = new BarcodeEncoder();
Bitmap bitmap = barcodeEncoder.createBitmap(bitMatrix);
int[][] pixels = getPixelsSlow(bitmap);
printImage(pixels);
// printPhoto(bitmap);
} catch (WriterException e) {
e.printStackTrace();
}
Solution 1:
In Following Fucntion :
- data : can be link or anything you want to put in QR-Code
- size : howbig you want QR-Code to be
public static byte[] QRCodeDataToBytes(String data, int size) throws EscPosBarcodeException {
ByteMatrix byteMatrix = null;
try {
EnumMap<EncodeHintType, Object> hints = new EnumMap<EncodeHintType, Object>(EncodeHintType.class);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
QRCode code = Encoder.encode(data, ErrorCorrectionLevel.L, hints);
byteMatrix = code.getMatrix();
} catch (WriterException e) {
e.printStackTrace();
throw new EscPosBarcodeException("Unable to encode QR code");
}
if (byteMatrix == null) {
return EscPosPrinterCommands.initImageCommand(0, 0);
}
int
width = byteMatrix.getWidth(),
height = byteMatrix.getHeight(),
coefficient = Math.round((float) size / (float) width),
imageWidth = width * coefficient,
imageHeight = height * coefficient,
bytesByLine = (int) Math.ceil(((float) imageWidth) / 8f),
i = 8;
if (coefficient < 1) {
return EscPosPrinterCommands.initImageCommand(0, 0);
}
byte[] imageBytes = EscPosPrinterCommands.initImageCommand(bytesByLine, imageHeight);
for (int y = 0; y < height; y++) {
byte[] lineBytes = new byte[bytesByLine];
int x = -1, multipleX = coefficient;
boolean isBlack = false;
for (int j = 0; j < bytesByLine; j++) {
StringBuilder stringBinary = new StringBuilder();
for (int k = 0; k < 8; k++) {
if (multipleX == coefficient) {
isBlack = ++x < width && byteMatrix.get(x, y) == 1;
multipleX = 0;
}
stringBinary.append(isBlack ? "1" : "0");
++multipleX;
}
lineBytes[j] = (byte) Integer.parseInt(stringBinary.toString(), 2);
}
for (int multipleY = 0; multipleY < coefficient; ++multipleY) {
System.arraycopy(lineBytes, 0, imageBytes, i, lineBytes.length);
i += lineBytes.length;
}
}
return imageBytes;
}
I Prefer this library for printing over thermal printer