[Image-SIG] Converting to zebra (ZPL) format

Peter Dempsey yarglags at eircom.net
Sun Jun 19 03:31:15 CEST 2005

On Saturday 18 Jun 2005 02:40, you wrote:
> Hi Peter,
> despite Fredik's lengthy and carefull answer, I think that is not what
> you were asking for - his program is suitable to print images inpout
> inline inside a Python program as sequences of 0 and 1's.
> But I think you were asking for a way to print a generic image read
> from a disk file.
> I can code that for you, if you wish so - just write me if no one else
> mailed yu a complete answer, and tell me more details about the
> images you want to print, maximum width of the printer, and stuff
> like that.
> I also did nt understand if the Hexadecimal data you send to the
> printer is actual ASCII - i.e. You send a real  "F" character to get
> four dots "1111", or if you send a 15 decimal value standing for 0x0F
> ANd please, do confirm that you have PIL installed (call a interactive
> Python shell and type 'import Image' there if you are not sure).
> Regards,
> 	JS
> 	-><-
Thanks for the reply folks. Here is the code I have produced so far...
#! /usr/bin/python

import sys
import string

def hexit(n):		# convert n to two digit Hex string.
	result = string.upper(str(hex(ord(n))))[2:4]
	if len(result) == 1:
		result = '0' + result
	return result

def ImageWidth(n):	# read image width from PCX header
	n = 1 + (ord(n[8]) + ord(n[9]) * 256) - (ord(n[4]) + ord(n[5]) * 256)
	if n % 8 > 0:	# if mod width non zero image needs extra byte
		n = n / 8 + 1
		n = n / 8

	return n

def ImageHeight(n):	# read height from PCX header
	return 1 + (ord(n[10]) + ord(n[11]) * 256) - (ord(n[6]) + ord(n[7]) * 256)

def PrintDetails(n):
        print 'Input length:\t', len(n)
	print 'Image Width: \t', ImageWidth(n), ' bytes'
	print 'Image Width: \t', 1 + (ord(n[8]) + ord(n[9]) * 256) - (ord(n[4]) + 
ord(n[5]) * 256), ' px'
        print 'Image Height:\t', ImageHeight(n)
        print 'Bits/Pixel:  \t', ord(n[3]), '\n'

def hex2dec(n):		# convert hex digit to decimal
	return string.find('0123456789ABCDEF',n)

def invhex(n):		# forgot that printer treats 1 as 'on' - no ink dot.
	n = string.upper(hex(255 - hex2dec(n[0])*16 - hex2dec(n[1]))[2:])
	if len(n) == 2:
		return n
		return '0'+n

i = sys.argv[1:]

for arg in i:
        source = open(arg, 'rb')
	dest = arg
	dest = dest[:string.find(dest,'.')]+'.hex'
        print 'Input file:\t', i
        print 'Output file:\t', dest
    except IOError:
        print 'cannot open', arg
	header = '~DG_ZEBRA,' + str(ImageWidth(b) * ImageHeight(b)) + ',' + 
str(ImageWidth(b)) + ',\n'
	mult = 0		# pcx byte multiplier begins with a 'C'
        for x in b[128:]:	# Skip pcx header
		byte = hexit(x)
		if byte[:1] == 'C' and mult == 0:
			mult = hex2dec(byte[1])
			if mult == 0:
				n = n + invhex(byte)
				n = n + invhex(byte) * mult
				mult = 0
	n = header + n[:(ImageWidth(b) * ImageHeight(b)*2)]
	print 'Output:\n', n

This works for small simple graphics but goes pear-shaped as the image size 
grows. I thought I was making some headway but, being new to python and image 
manipulation, I am getting disheartened. It could be to do with my 
understanding of the PCX file format. I just thought I was re-inventing the 
wheel and was missing something basic.

The data sent to the printer is an ascii representation of the data, 
"FFFF0000" etc. Surely any graphic image ends up on screen as a set od pixels 
either on or off? The data read by the PIL must exist in a format that can be 
converted to binary to hex to ascii characters.

I have PIL installed. I can read in from a file. The code above is written to 
work on a pcx file which, thanks to PIL, I can get from almost any image.

FYI the programming manual for these printers is available here. 
The download grapgic details are on page 202/211.

Thanks again for the replies,


More information about the Image-SIG mailing list