diff --git a/escpos/escpos.py b/escpos/escpos.py old mode 100644 new mode 100755 index b6befdd..f4c3627 --- a/escpos/escpos.py +++ b/escpos/escpos.py @@ -20,7 +20,7 @@ from exceptions import * class Escpos: """ ESC/POS Printer object """ device = None - + img_cache = [] def _check_image_size(self, size): """ Check and fix the size of the image to 32 bits """ @@ -33,13 +33,45 @@ class Escpos: else: return (image_border / 2, (image_border / 2) + 1) + def cache_image(self, path_img): + """ Open image file and store in the printer's cache """ + + img_no = len(self.img_cache) + + im_open = Image.open(path_img) + im = im_open.convert("RGB") + # Convert the RGB image into printable image + (pix_line, img_size) = self._convert_image(im) + + # Convert the buffered data directly to the printer readable format + cache = "" + buffer = "" + i = 0 + cont = 0 + + buffer = "%02X%02X%02X%02X" % (((img_size[0]/img_size[1])/8), 0, img_size[1], 0) + cache = buffer.decode('hex') + buffer = "" + + while i < len(pix_line): + hex_string = int(pix_line[i:i+8],2) + buffer += "%02X" % hex_string + i += 8 + cont += 1 + if cont % 4 == 0: + cache += buffer.decode("hex") + buffer = "" + cont = 0 + + self.img_cache.append(cache) + return img_no def _print_image(self, line, size): """ Print formatted image """ i = 0 cont = 0 buffer = "" - + self._raw(S_RASTER_N) buffer = "%02X%02X%02X%02X" % (((size[0]/size[1])/8), 0, size[1], 0) self._raw(buffer.decode('hex')) @@ -97,20 +129,25 @@ class Escpos: break elif im_color > (255 * 3 / pattern_len * pattern_len) and im_color <= (255 * 3): pix_line += im_pattern[-1] - break + break pix_line += im_right img_size[0] += im_border[1] - self._print_image(pix_line, img_size) - + return pix_line, img_size def image(self,path_img): - """ Open image file """ + """ Open and immediately print image file """ im_open = Image.open(path_img) im = im_open.convert("RGB") - # Convert the RGB image in printable image - self._convert_image(im) + # Convert the RGB image in printable image + (pix_line, img_size) = self._convert_image(im) + self._print_image(pix_line, img_size) + + def cached_image(self, index): + """ Prints an image from the image cache """ + self._raw(S_RASTER_N) + self._raw(self.img_cache[index]) def qr(self,text): """ Print QR Code for the provided string """ diff --git a/escpos/printer.py b/escpos/printer.py old mode 100644 new mode 100755 index a34edb4..1ea162c --- a/escpos/printer.py +++ b/escpos/printer.py @@ -18,6 +18,8 @@ from exceptions import * class Usb(Escpos): """ Define USB printer """ + is_open = False + def __init__(self, idVendor, idProduct, interface=0, in_ep=0x82, out_ep=0x01): """ @param idVendor : Vendor ID @@ -36,9 +38,14 @@ class Usb(Escpos): def open(self): """ Search device on USB tree and set is as escpos device """ + if self.is_open: + return # Already open; no need to reopen + self.device = usb.core.find(idVendor=self.idVendor, idProduct=self.idProduct) if self.device is None: print "Cable isn't plugged in" + else: + self.is_open = True if self.device.is_kernel_driver_active(0): try: @@ -50,9 +57,21 @@ class Usb(Escpos): self.device.set_configuration() self.device.reset() except usb.core.USBError as e: + # Seems fatal when it occurs. Should the device be closed as a result? + #self.close() print "Could not set configuration: %s" % str(e) + def close(self): + """ Manually release USB interface """ + self.is_open = False + + if self.device: + usb.util.dispose_resources(self.device) + + self.device = None + + def _raw(self, msg): """ Print any command sent in raw format """ self.device.write(self.out_ep, msg, self.interface) @@ -60,15 +79,15 @@ class Usb(Escpos): def __del__(self): """ Release USB interface """ - if self.device: - usb.util.dispose_resources(self.device) - self.device = None + self.close() class Serial(Escpos): """ Define Serial printer """ + is_open = False + def __init__(self, devfile="/dev/ttyS0", baudrate=9600, bytesize=8, timeout=1): """ @param devfile : Device file under dev filesystem @@ -84,15 +103,29 @@ class Serial(Escpos): def open(self): - """ Setup serial port and set is as escpos device """ + """ Setup serial port and set it as escpos device """ + if self.is_open: + return # Already open; no need to reopen + self.device = serial.Serial(port=self.devfile, baudrate=self.baudrate, bytesize=self.bytesize, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=self.timeout, dsrdtr=True) if self.device is not None: print "Serial printer enabled" + self.is_open = True else: print "Unable to open serial printer on: %s" % self.devfile + def close(self): + """ Manually close Serial interface """ + self.is_open = False + + if self.device is not None: + self.device.close() + + self.device = None + + def _raw(self, msg): """ Print any command sent in raw format """ self.device.write(msg) @@ -100,14 +133,14 @@ class Serial(Escpos): def __del__(self): """ Close Serial interface """ - if self.device is not None: - self.device.close() - + self.close() class Network(Escpos): """ Define Network printer """ + is_open = False + def __init__(self,host,port=9100): """ @param host : Printer's hostname or IP address @@ -120,11 +153,26 @@ class Network(Escpos): def open(self): """ Open TCP socket and set it as escpos device """ + if self.is_open: + return # Already open; no need to reopen + self.device = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.device.connect((self.host, self.port)) if self.device is None: print "Could not open socket for %s" % self.host + else: + self.is_open = True + + + def close(self): + """ Manually close TCP connection """ + self.is_open = False + + if self.device is not None: + self.device.close() + + self.device = None def _raw(self, msg): @@ -134,13 +182,15 @@ class Network(Escpos): def __del__(self): """ Close TCP connection """ - self.device.close() + self.close() class File(Escpos): """ Define Generic file printer """ + is_open = False + def __init__(self, devfile="/dev/usb/lp0"): """ @param devfile : Device file under dev filesystem @@ -151,10 +201,25 @@ class File(Escpos): def open(self): """ Open system file """ + if self.is_open: + return # Already open; no need to reopen + self.device = open(self.devfile, "wb") if self.device is None: print "Could not open the specified file %s" % self.devfile + else: + self.is_open = True + + + def close(self): + """ Manually close system file """ + self.is_open = False + + if self.device is not None: + self.device.close() + + self.device = None def _raw(self, msg): @@ -164,4 +229,4 @@ class File(Escpos): def __del__(self): """ Close system file """ - self.device.close() + self.close()