print image in thermal printer with printBItmap(Stream *stream)

Hello, every one.
This is my first question ever since I had started Arduino.

I bought Thermal Receipt Printer and tested it.
But I found a problem that it can't print the language KOREAN(hangul).

So I came up with the idea. I thought if I converted hangul to image, and print with the function printBitmap(), It can print hangul.

I converted all of the words that I want to print into image with Pillow which is the module of python.
and I saved it as BITMAP.

I saved the bitmap files into SD card, opened the file in Arduino code, and conveyed it to the function printBitmap(dynamic_cast<Stream*>myFiles).

Adafruit Thermal Printer LibraryžĚė 
void Adafruit_Thermal::printBitmap(Stream *stream) {
uint8_t tmp;
uint16_t width, height;

tmp = stream->read();
width = (stream->read() << 8) + tmp;

tmp = stream->read();
height = (stream->read() << 8) + tmp;

printBitmap(width, height, stream);
}

I expected it would be going very well, but It didn't.
It printed just black-grey sharped image.

I think bitmap image which I converted using Pillow has unnecessary data, because once it printed reversed with strange characters.

how can I solve this problem?
and is it the right way open the 'bitmap file' and convey it as stream?

thanks for your answer

Did you look at the documentation on the Adafruit website? They recommend a program to convert images into BMP files that allows you to specify the height/width of the image at the beginning of the file and in the correct format (little endian) for AVR. The program you used (Pillow) may or may not do it the same way. I'd start by checking there.

You also didn't post your entire program so any more help is difficult.

Hi,

When it says it can print Bitmap format it's a bit confusing. I guess they use "bitmap" word just to say that the image should only contain black or white pixels.

Now, the actual file format should contain bytes which correspond to 8 pixels groups. The first byte refers to the first 8 pixels, having a 0 if it's white, and 1 if it's black and so on. Furthermore, the file must have a pixel width divisible by 8, or it will shift all lines ending with a crap picture. So the last byte coding last pixels of a row must be filled with 1.

I created a little program that take care of all of that. Just give it an input image, and it will create the appropriate data file to be printed. You can check it out here: GitHub - henricazottes/cttp: Convert image to thermal printer format

Hope it'll help :slight_smile:

Monstercrunch81:
I created a little program that take care of all of that. Just give it an input image, and it will create the appropriate data file to be printed. You can check it out here: GitHub - henricazottes/cttp: Convert image to thermal printer format

Hello, I'm a newbie to Arduino, but I'm trying to do the same thing as OP. I want to thermal print images from a microSD card, but I can't figure out how to get the right format. (The whole bitmap vs BMP terminology thing is also really confusing!)

Anyway, I went to your github, but I can't for the life of me figure out how to run the program to create the data files. I apologize in advance if this is stupid basic!

Hi, I had the same problem, I didn't know how to print images and the program that adafruit provides you doesn't work but I found the solution

1- You need to install the ardafruit thermal library
2-Go to files and look for the option that says examples
3-Find the option ardafruit thermal library
4- And Use the example processing
5- You need to copy that code a put in processing and then just run the program and select the file that you want to convert in bit image and that program generate a file with the same name as the picture but with extension .h you can use another C compiler for to see the bitmap code

If you can't find the code

is this

void setup() {
// Select and load image
selectInput("Select image file to convert:", "processImage");
}

void processImage(File image) {
String filename, basename;
PImage img;
PrintWriter output;
int pixelNum, byteNum, bytesOnLine = 99,
x, y, b, rowBytes, totalBytes, lastBit, sum;
println("Loading image...");
filename = image.getPath();
img = loadImage(image.getPath());

// Morph filename into output filename and base name for data
x = filename.lastIndexOf('.');
if(x > 0) filename = filename.substring(0, x); // Strip current extension
x = filename.lastIndexOf('/');
if(x > 0) basename = filename.substring(x + 1); // Strip path
else basename = filename;
filename += ".h"; // Append '.h' to output filename
println("Writing output to " + filename);

// Calculate output size
rowBytes = (img.width + 7) / 8;
totalBytes = rowBytes * img.height;
// Convert image to B&W, make pixels readable
img.filter(THRESHOLD);
img.loadPixels();

// Open header file for output (NOTE: WILL CLOBBER EXISTING .H FILE, if any)
output = createWriter(filename);

// Write image dimensions and beginning of array
output.println("#ifndef _" + basename + "h");
output.println("#define _" + basename + "h");
output.println();
output.println("#define " + basename + "_width " + img.width);
output.println("#define " + basename + "_height " + img.height);
output.println();
output.print("static const uint8_t PROGMEM " + basename + "_data[] = {");

// Generate body of array
for(pixelNum=byteNum=y=0; y<img.height; y++) { // Each row...
for(x=0; x<rowBytes; x++) { // Each 8-pixel block within row...
lastBit = (x < rowBytes - 1) ? 1 : (1 << (rowBytes * 8 - img.width));
sum = 0; // Clear accumulated 8 bits
for(b=128; b>=lastBit; b >>= 1) { // Each pixel within block...
if((img.pixels[pixelNum++] & 1) == 0) sum |= b; // If black pixel, set bit
}
if(++bytesOnLine >= 10) { // Wrap nicely
output.print("\n ");
bytesOnLine = 0;
}
output.format(" 0x%02X", sum); // Write accumulated bits
if(++byteNum < totalBytes) output.print(',');
}
}

// End array, close file, exit program
output.println();
output.println("};");
output.println();
output.println("#endif // _" + basename + "h");
output.flush();
output.close();
println("Done!");
exit();
}

wow! it looks like you guys know how to prepare data for that adafruit thermal printer. I need to do kind of data logger using arduino, send this data to processing, convert it for thermal printer and print on thermal printer. The problem (one of many) is the data to print will contain some text and i need to print a plot as well (scatter plot XY). The plan is to create a label tha will be put on the 18650 battery cell after it was tested. The data on the label should contain time stamp, cell's capacity, bla bla AND a plot showing discharging process: cell voltage vs time.

I do not think all of this can be done onboard arduino nano itself so Processing is probably good environment for that.
There will be 32 channels for 32 18650 li-ion cells discharged simultaneously. When some cell's discharge will be completed, arduino should send "end" command for that particular channel and Processing should prepare data for printer and spint it on thermal printer - probably using direct connection Processing-printer via rs232 (as arduino will be too busy sending other cells discharge data).

Do you think that part of the code you are talking about can be used for that purpose?
thank you