Printing BitImages on a thermal printer
Printing an Image (jpg,bmp,png,gif, whatever) via the BitImaging ESC * command.
Oh man, that was a hard nut to crack. The documentation on what to do is very precise and has that “shame on you if you make a mistake. just read more carefully!” philosophy to it. You need to define how much data is coming through per Image. Fair enough, it’s Widht*Hight px. …No its not. It’s byte*dotlines?
Byte of data Horizontal by dotlines in vertical direction. That’s a nice specification of a resolution. For BitImage printing on a 3inch Printer the width of an image must be 576pixel or to be exact, the data to be transmitted must be at least 72bytes. Makes sense, because the printer only prints the data that is in its buffer after a lineFeed. So it only prints full lines period.
Well then, lets load an image and convert it to black and white (1bit depth of course) and fill the empty space up to 576pixel with white.
In the code below I look at every pixel of an image. convert the pixel to gray values by weighting each color in a rough percentages like the human eye would weight them. After that I compare the 8bit gray scale value ranging from 0 - 255 with my threshold of 127. That means, if the average gray value of a pixel would be 120 I would print white because it’s not gray enough to be black.
Code Snippets:
for(int y = 0; y < fillHeight; y++){
for(int x = 0; x < fillWidth; x++){
if(x < myImage.getWidth()) {
java.awt.Color myColor = new java.awt.Color(myImage.getRGB(x,y));
int luma = (int)(myColor.getRed() * 0.3 + myColor.getGreen() * 0.59 + myColor.getBlue() * 0.11);
luma8[x][y] = luma;
dots[x][y] = (luma < threshold);
}else {
dots[x][y] = false;
}
}
}
Actuall Printing via ESC* command:
In retrospect - I could have made a better loop to write the values to the byte. But what the hell, it works.
int cHeight = dimensions[0].length;
int cWidth = 576;
int pixel = cWidth*cHeight;
picHeight[count] = myImage.getHeight() & 0xFF;
picHeight[count+1] = (myImage.getHeight() » 8) & 0xFF;
myPort.write(0x1B);//ESC
myPort.write(0x2A);//*
myPort.write((byte)97);//72byte wide
myPort.write(picHeight[count]);
myPort.write(picHeight[count+1]);
if(cWidth == 576 && cHeight <= 1023){
while(i < pixel) {
int slice = 0;
for(int b=0; b < 8;b++) {
boolean v = false;
if(y < cHeight){
if(x < cWidth){
v= dots[x][y];
x++;
}else{
x=0;
y++;
v= dots[x][y];
x++;
}
}
i++;
if(v == true) {
slice = slice | (1 « (7-b));
}else {
slice = slice | (0 « (7-b));
}
}
myPort.write((byte)slice);
}
println(“——-DONE———”);
}else{
println(“IMAGE EXCEEDS DIMENSIONS 576x1023”);
}
Before and on the thermal paper

Thermal Printer driver
Well well. ESC POS command eh? Doesn’t seem that hard, does it?
I got my hands on a 3inch thermal printer from Fujitsu Siemens.
That would be the FTP-628DSL600 Series controller board and an FTP-638MCL101 Printer.
(http://www.fujitsu.com/downloads/MICRO/fcai/printers/ftp-628dsl600.pdf)
Apply Power:
Initially nothing worked. Took some time before I found out that you had to connect not only Rx and Tx for the serial communication but the three /INPRM, /ATF and /SLCTIN, wires according to a time diagramm to actually initialize the printer. In our case that would be /SLCTIN to GND and /INPRM and /ATF to 5V.
Make it work:
Up to now we have problems finding the right power supply unit. The Voltage starts to drop off when the print ratio is high (eg printing 3inch by 3inch pictures). What happens is that the heater wont be warm enough and the motor wont move fast enough resulting in bad print quality fist repetitive voids and grayish areas.
(gray printing would be cool though :-])
Setting the printer to speedMode 5 (less power consumption) stabilizes the print quality. But the printing process on higher ratios is dam slow for a thermal printer.
Coding snippets:
println(Serial.list());
myPort = new Serial(this, Serial.list()[0], 19200,’N’,8,1);
//Initialize
myPort.write(0x1B); //ESC
myPort.write(0x40); //@//set speedMode
myPort.write(0x1B);
myPort.write(0x73);
myPort.write(0x64); //Mode5//TALK TO PRINTER
myPort.write(“Print that!”);
//line Feed
myPort.write(0xA);