Printing Images with /tmp/DEVTERM_PRINTER_IN

When I was reading the source code for printer for undocumented commands, I found a command for printing images:

The command for image mode is as the following, followed by the raw image data where each bit corresponds to a pixel:
GS(\x1d) v 0 p wL wH hL hH, where:

  • Width is (wL+256*wH)*8 pixels (because it’s in bytes)
  • Height is (hL+256*hH) pixels (because it’s in lines)

There is an upper limit of allowed image size of 9224 bytes (73792 pixels), which when used with full width of 384 dots, can fits a 384*192 image. For the image data, every 8 pixels are grouped in a byte, with the left most pixel being the LSB. Groups are arranged left to right for each line. The image data can be generated with Python:

img_data = PIL.ImageOps.invert(img.convert('L')).convert('1').tobytes()

Results:

  • Left: 1st attempt that went terribly wrong due to not adding the header properly
  • Middle: several attempts that got the size parameter wrong
  • Right: 3 successful attempts (32*32, 64*64, 256*256) with several failed ones in between

5 Likes

See: Devterm printer kernelspace driver - no length limit and grayscale possible.

4 Likes

@Leo3065 If you’d be interested in sharing more details of how you printed those images from python, it would be cool to see and experiment with.

Sorry, I’m very much new with this, could you explain how to print an image, like, for dummies? I truly don’t understand the instructions you gave, I guess I’m not in that level yet :sweat_smile:

Actually you need to divide by 8pixels (as each byte represents 8 dots), image data provided by OP works.

Here is example, how you can generate command for printing png in python (slashes are integer divisions, not comments):

import PIL
from PIL import Image
file1 = "/tmp/calligraphy.png"
def makestr(f):
    img = Image.open(f)
    img_data = PIL.ImageOps.invert(img.convert('L')).convert('1').tobytes()
    w = img.width // 8
    h = img.height
    wL = (w % 256).to_bytes(1,'big')
    wH = (w // 256).to_bytes(1,'big')
    hL = (h % 256).to_bytes(1,'big')
    hH = (h // 256).to_bytes(1,'big')
    data = "\x1dv0p".encode('ascii') +wL + wH + hL + hH + img_data
    return data
open("h1.txt", 'wb').write(makestr(file1))

Then execute the following command in the shell :

cat h1.txt > /tmp/DEVTERM_PRINTER_IN
1 Like