Tuesday, February 24, 2015

DropPrint 2.0: Image and QR Code Support

This morning I finished up the next iteration of DropPrint, a tiny Android app that drives a thermal bluetooth printer. The big improvements: DropPrint now supports images as well as bar codes.

Check it out:

The image printing protocol for the printer I'm using, a DL58, is pretty dang simple. It consists of little more than sending each row of an image with the following format:

0x1F 0x10 NN 0x00 B1 B2 B3 ...

Where NN is the number of bytes being sent to represent the line of the image. B1, B2, etc. are bytes containing the relevant bits (0 black, 1 white) for each pixel. In other words, if my image was 1 pixel high and 8 pixels wide (I know, not a particularly interesting image):

Black Black Black White White White Black White

I'd send this as:

0x1F 0x10 0x01 0x0 [00011101]

It through me off at first, but that binary header (0X1F 0x10 ...) is sent at the start of each row, not just at the start of the image.

This whole mapping of image pixels to individual bits, followed by compressing the bits into bytes, was an interesting exercise to say the least. Not being much of a hardware interface guy, these are usually details I'm not worrying about. An interesting side effect of printer's binary protocol is that the height of the image is effectively irrelevant. All the printer knows about are the individual rows of the image. I'm using this to my advantage in DropPrint by rotating images that are taller than they are wider. The result is that especially narrow or wide images, like a panoramic shot, actually do well on the printer.

One obvious issue with the printer is that it only prints black and white, there's no ability to send any sort of gray pixels. The result is that your typical photograph, filled with not-quite-black-not-quite-white areas, looks awful when printed. Still, there's hope. The notion of the halftone was invented to solve exactly this problem. Invented back in the 1830's, it's hardly new tech. The idea is to simulate gray by interspersing black and white dots. Just like our brains can be fooled into seeing fluid movement using the principles of animation, we can also be fooled into seeing gray when only black and white is present. Anyway, this is an area I'll be coming back to.

With the basic image printing ability out of the way adding QRCode support was quite easy. I grabbed the zxing library and put it it to work. Now when DropPrint discovers a .qrc file, it encodes the text found within as a QR Code and prints that.

Next up: I'll work on improving the image printing quality as well as improving how the app handles being put in the background and losing connection to the printer. Still lots to do, but it's amazing when this guy prints out an image I've sent to it.