Hi Dev, baru-baru ini saya kepayahan menghadapi tantangan yang diberikan oleh klien, mengapa? karena saya diminta untuk menciptakan solusi mencetak gambar di thermal printer. Oke, tadinya saya pikir itu mudah, semudah mencetak teks saja, tapi ternyata tidak. Jadi, anggapan saya selama ini keliru jika mengikuti jalur plain text, yang mana merubahnya menjadi ByteArray, ternyata tidak semudah itu ferguso.
Sebagai gambaran berikut experimen saya untuk melakukan pendekatan terhadap pencarian solusi itu.
Pertama, katakanlah saya mempunyai sejumlah inputan text yang perlu saya cetak.
String message="abcdef any message 12345";
byte[] send;
send = message.getBytes();
mService.write(send);
Oke, kode diatas berjalan mulus untuk tugas cetak teks, tapi kacau jika input ByteArray saya ganti dengan ByteArray miliknya gambar, kira-kira seperti ini cara saya melakukannya.
Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.qrcode);
ByteArrayOutputStream stream=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
byte[] image=stream.toByteArray();
Sial, yang terjadi malah mucul cetakan seperti karakter tidak jelas yang tidak readable, dan jika itu saya biarkan, maka panjang cetakannya bisa mencapai 50 cm.
Oke, setelah banyak sekali membuang-buang waktu hanya untuk memecahkan masalah mencetak gambar di thermal printer, akhirnya saya merubah metode saya yang terlalu simpel menjadi metode yang lumayan ribet. Semoga saja ini bisa berjalan di jenis / model thermal printer milik kamu!
Saya membuat fungsi umum yang perlu mencantumkan paramter file image bertipe string, yang mana ini dimaksudkan untuk menaruh path gambar / alamat lokasi gambar di lokal storage.
private void printImage(String file) {
File fl = new File(file);
if (fl.exists()) {
Bitmap bmp = BitmapFactory.decodeFile(file);
convertBitmap(bmp);
mService.write(PrinterCommands.SET_LINE_SPACING_24);
int offset = 0;
while (offset < bmp.getHeight()) {
mService.write(PrinterCommands.SELECT_BIT_IMAGE_MODE);
for (int x = 0; x < bmp.getWidth(); ++x) {
for (int k = 0; k < 3; ++k) {
byte slice = 0;
for (int b = 0; b < 8; ++b) {
int y = (((offset / 8) + k) * 8) + b;
int i = (y * bmp.getWidth()) + x;
boolean v = false;
if (i < dots.length()) {
v = dots.get(i);
}
slice |= (byte) ((v ? 1 : 0) << (7 - b));
}
mService.write(slice);
}
}
offset += 24;
mService.write(PrinterCommands.FEED_LINE);
mService.write(PrinterCommands.FEED_LINE);
mService.write(PrinterCommands.FEED_LINE);
mService.write(PrinterCommands.FEED_LINE);
mService.write(PrinterCommands.FEED_LINE);
mService.write(PrinterCommands.FEED_LINE);
}
mService.write(PrinterCommands.SET_LINE_SPACING_30);
} else {
Toast.makeText(this, "file doesn't exists", Toast.LENGTH_SHORT)
.show();
}
}
Jika kalian perhatikan, dalam service tersebut saya memanggil sebuah static variabel yang didefinisikan di class PrinterCommands, variable tersebut berisi standard instruksi ESC/POS yaitu sebuah instruksi yang dikenali thermal printer, jadi ya begitulah, agar kita bisa berkomunikasi dengan perangkat tersebut.
public class PrinterCommands {
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[] 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, -128, 0};
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};
}
Kesimpulannya adalah, saya menyimpan gambar di local storage, kemudian mengambil pathnya (alamat lokasi file gambar) dalam string, kemudian path tersebut saya gunakan untuk memanggil fungsi printImage(String file)
Jika diantara kalia masih ada yang belum bisa menangkap konsepnya atau cara kerjanya, maka silakan bisa observasi terlebih dahulu project berikut INI.
Selamat mencoba!