From 9566d9dc4b0c8c9f2ca6f48aef24ca131ce0525c Mon Sep 17 00:00:00 2001 From: greg-elmi Date: Thu, 17 Sep 2020 14:57:04 +0200 Subject: [PATCH 1/6] pulled changes from testy --- .../thermal_printer_2168.py | 109 +++++++++++++++++- 1 file changed, 107 insertions(+), 2 deletions(-) diff --git a/adafruit_thermal_printer/thermal_printer_2168.py b/adafruit_thermal_printer/thermal_printer_2168.py index 0cf6aa6..ce447ab 100644 --- a/adafruit_thermal_printer/thermal_printer_2168.py +++ b/adafruit_thermal_printer/thermal_printer_2168.py @@ -29,7 +29,7 @@ versions and care must be taken to select the appropriate module inside this package for your firmware printer: -* thermal_printer_2168 = Printers with firmware version 2.168+. +* thermal_printer_2164 = Printers with firmware version 2.168+. * thermal_printer = The latest printers with firmware version 2.68 up to 2.168 * thermal_printer_264 = Printers with firmware version 2.64 up to 2.68. * thermal_printer_legacy = Printers with firmware version before 2.64. @@ -37,10 +37,14 @@ * Author(s): Tony DiCola, Grzegorz Nowicki """ - +import math +import imageio +import numpy as np +from PIL import Image import adafruit_thermal_printer.thermal_printer as thermal_printer + # pylint: disable=too-many-arguments class ThermalPrinter(thermal_printer.ThermalPrinter): """Thermal printer for printers with firmware version from 2.168""" @@ -92,3 +96,104 @@ def warm_up(self, heat_time=120): """ self._set_timeout(0.5) # Half second delay for printer to initialize. self.reset() + + + def print_bitmap(self, file): + """ Convert bitmap file and print as picture using GS v 0 command """ + # pylint: disable=too-many-locals + img = imageio.imread(file) + try: + if img.shape[2] == 4: # 3 colors with alpha channel + red, green, blue, alpha = np.split(img, 4, axis=2) + else: # just 3 colors + red, green, blue = np.split(img, 3, axis=2) + + red = red.reshape(-1) + green = green.reshape(-1) + blue = blue.reshape(-1) + + bitmap = list(map(lambda x: 0.333*x[0]+0.333*x[1]+0.333*x[2], zip(red, green, blue))) + bitmap = np.array(bitmap).reshape([img.shape[0], img.shape[1]]) + bitmap = np.multiply((bitmap > 208).astype(float), 255) + + im = Image.fromarray(bitmap.astype(np.uint8)) + f = np.array(im) + except IndexError: # 2D monochromatic array + f = np.array(img) + + assert f.shape[1] < 385, "bitmap should be less than 385 pixels wide" + assert f.shape[0] < 65535, "bitmap should be less than 65535 pixels high" + + ### Assertion for height is irrelevant. I tested it for over 6000 pixels high + ### picture and while it took a long time to send, it printed it without a hitch. + ### Theoretical maximum is 65535 pixels but I don't want to waste 7m of paper + + data = self._convert_data_horizontally(f.shape[1], f.shape[0], f) + + ### split into two bytes and prepare to format for printer, x and y sizes of an image + img_x = math.ceil(f.shape[1]/8) + img_y = f.shape[0] + img_lx = (img_x & 0xFF).to_bytes(1, byteorder="big") + img_hx = ((img_x & 0xFF00) >> 8).to_bytes(1, byteorder="big") + img_ly = (img_y & 0xFF).to_bytes(1, byteorder="big") + img_hy = ((img_y & 0xFF00) >> 8).to_bytes(1, byteorder="big") + mode = b"\x00" + + self._print_horizontal(mode, img_lx, img_hx, img_ly, img_hy, data) + # pylint: enable=too-many-locals + + def _print_horizontal(self, mode, img_lx, img_hx, img_ly, img_hy, data): + """ Send "Print Graphics horizontal module data" command, + GS v 0 and append it with provided data, + data must conform to printer's required format, + use _convert_data_horizontally() to convert data from bitmap to this format + """ + self._uart.write(b"\x1D\x76\x30%s%s%s%s%s%s" % (mode, img_lx, img_hx, img_ly, img_hy, data)) + # pylint: disable=invalid-name + ### this is pain in the butt + for d in data: + self._uart.write(d) + # pylint: enable=invalid-name + + + def _write_to_byte(self, pos, byte): + """ Helper method used in _convert_data_horizontally to compress pixel data into bytes + """ + if pos == 0: + return byte | 0b10000000 + if pos == 1: + return byte | 0b01000000 + if pos == 2: + return byte | 0b00100000 + if pos == 3: + return byte | 0b00010000 + if pos == 4: + return byte | 0b00001000 + if pos == 5: + return byte | 0b00000100 + if pos == 6: + return byte | 0b00000010 + if pos == 7: + return byte | 0b00000001 + + def _convert_data_horizontally(self, x_size, y_size, file_array): + """Convert data from numpy array format to printer's horizontal printing module format + """ + datas = bytearray() + # pylint: disable=invalid-name + for y in range(y_size): + for x in range(0, x_size, 8): + data = 0 + for bit in range(8): + try: + if file_array[y][x+bit] == 0: + data = self._write_to_byte(bit, data) + + except IndexError: + pass + finally: + pass + datas.append(data) + return datas + # pylint: enable=invalid-name + From 7803d1e8d4331f3eb78d2f78d5e500c29555abe6 Mon Sep 17 00:00:00 2001 From: greg-elmi Date: Thu, 17 Sep 2020 15:17:09 +0200 Subject: [PATCH 2/6] black formatting --- .../thermal_printer_2168.py | 63 ++++++++++--------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/adafruit_thermal_printer/thermal_printer_2168.py b/adafruit_thermal_printer/thermal_printer_2168.py index ce447ab..f0cbe71 100644 --- a/adafruit_thermal_printer/thermal_printer_2168.py +++ b/adafruit_thermal_printer/thermal_printer_2168.py @@ -40,11 +40,9 @@ import math import imageio import numpy as np -from PIL import Image import adafruit_thermal_printer.thermal_printer as thermal_printer - # pylint: disable=too-many-arguments class ThermalPrinter(thermal_printer.ThermalPrinter): """Thermal printer for printers with firmware version from 2.168""" @@ -97,42 +95,48 @@ def warm_up(self, heat_time=120): self._set_timeout(0.5) # Half second delay for printer to initialize. self.reset() - def print_bitmap(self, file): """ Convert bitmap file and print as picture using GS v 0 command """ # pylint: disable=too-many-locals img = imageio.imread(file) try: - if img.shape[2] == 4: # 3 colors with alpha channel + if img.shape[2] == 4: # 3 colors with alpha channel red, green, blue, alpha = np.split(img, 4, axis=2) - else: # just 3 colors + else: # just 3 colors red, green, blue = np.split(img, 3, axis=2) red = red.reshape(-1) green = green.reshape(-1) blue = blue.reshape(-1) - bitmap = list(map(lambda x: 0.333*x[0]+0.333*x[1]+0.333*x[2], zip(red, green, blue))) + bitmap = list( + map( + lambda x: 0.333 * x[0] + 0.333 * x[1] + 0.333 * x[2], + zip(red, green, blue), + ) + ) bitmap = np.array(bitmap).reshape([img.shape[0], img.shape[1]]) bitmap = np.multiply((bitmap > 208).astype(float), 255) - im = Image.fromarray(bitmap.astype(np.uint8)) - f = np.array(im) - except IndexError: # 2D monochromatic array - f = np.array(img) + data_array = np.array(bitmap.astype(np.uint8)) + + except IndexError: # 2D monochromatic array + data_array = np.array(img) - assert f.shape[1] < 385, "bitmap should be less than 385 pixels wide" - assert f.shape[0] < 65535, "bitmap should be less than 65535 pixels high" + assert data_array.shape[1] < 385, "bitmap should be less than 385 pixels wide" + assert ( + data_array.shape[0] < 65535 + ), "bitmap should be less than 65535 pixels high" - ### Assertion for height is irrelevant. I tested it for over 6000 pixels high + ### Assertion for height is irrelevant. I tested it for over 6000 pixels high ### picture and while it took a long time to send, it printed it without a hitch. ### Theoretical maximum is 65535 pixels but I don't want to waste 7m of paper - data = self._convert_data_horizontally(f.shape[1], f.shape[0], f) + data = self._convert_data_horizontally(data_array) ### split into two bytes and prepare to format for printer, x and y sizes of an image - img_x = math.ceil(f.shape[1]/8) - img_y = f.shape[0] + img_x = math.ceil(data_array.shape[1] / 8) + img_y = data_array.shape[0] img_lx = (img_x & 0xFF).to_bytes(1, byteorder="big") img_hx = ((img_x & 0xFF00) >> 8).to_bytes(1, byteorder="big") img_ly = (img_y & 0xFF).to_bytes(1, byteorder="big") @@ -143,22 +147,22 @@ def print_bitmap(self, file): # pylint: enable=too-many-locals def _print_horizontal(self, mode, img_lx, img_hx, img_ly, img_hy, data): - """ Send "Print Graphics horizontal module data" command, - GS v 0 and append it with provided data, - data must conform to printer's required format, - use _convert_data_horizontally() to convert data from bitmap to this format + """Send "Print Graphics horizontal module data" command, + GS v 0 and append it with provided data, + data must conform to printer's required format, + use _convert_data_horizontally() to convert data from bitmap to this format """ - self._uart.write(b"\x1D\x76\x30%s%s%s%s%s%s" % (mode, img_lx, img_hx, img_ly, img_hy, data)) + self._uart.write( + b"\x1D\x76\x30%s%s%s%s%s%s" % (mode, img_lx, img_hx, img_ly, img_hy, data) + ) # pylint: disable=invalid-name ### this is pain in the butt for d in data: self._uart.write(d) # pylint: enable=invalid-name - def _write_to_byte(self, pos, byte): - """ Helper method used in _convert_data_horizontally to compress pixel data into bytes - """ + """Helper method used in _convert_data_horizontally to compress pixel data into bytes""" if pos == 0: return byte | 0b10000000 if pos == 1: @@ -176,9 +180,11 @@ def _write_to_byte(self, pos, byte): if pos == 7: return byte | 0b00000001 - def _convert_data_horizontally(self, x_size, y_size, file_array): - """Convert data from numpy array format to printer's horizontal printing module format - """ + def _convert_data_horizontally(self, data_array): + """Convert data from numpy array format to printer's horizontal printing module format""" + x_size = data_array.shape[1] + y_size = data_array.shape[0] + datas = bytearray() # pylint: disable=invalid-name for y in range(y_size): @@ -186,7 +192,7 @@ def _convert_data_horizontally(self, x_size, y_size, file_array): data = 0 for bit in range(8): try: - if file_array[y][x+bit] == 0: + if data_array[y][x + bit] == 0: data = self._write_to_byte(bit, data) except IndexError: @@ -196,4 +202,3 @@ def _convert_data_horizontally(self, x_size, y_size, file_array): datas.append(data) return datas # pylint: enable=invalid-name - From f607caac93b52e4727ec0fdbb9c35914e770cedf Mon Sep 17 00:00:00 2001 From: greg-elmi Date: Thu, 17 Sep 2020 15:20:18 +0200 Subject: [PATCH 3/6] update for regressions --- adafruit_thermal_printer/thermal_printer_2168.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_thermal_printer/thermal_printer_2168.py b/adafruit_thermal_printer/thermal_printer_2168.py index f0cbe71..6ca3888 100644 --- a/adafruit_thermal_printer/thermal_printer_2168.py +++ b/adafruit_thermal_printer/thermal_printer_2168.py @@ -29,7 +29,7 @@ versions and care must be taken to select the appropriate module inside this package for your firmware printer: -* thermal_printer_2164 = Printers with firmware version 2.168+. +* thermal_printer_2168 = Printers with firmware version 2.168+. * thermal_printer = The latest printers with firmware version 2.68 up to 2.168 * thermal_printer_264 = Printers with firmware version 2.64 up to 2.68. * thermal_printer_legacy = Printers with firmware version before 2.64. From 18bf96b2468d64217c44dcf9282ef4e8cf065475 Mon Sep 17 00:00:00 2001 From: greg-elmi Date: Mon, 21 Sep 2020 14:55:27 +0200 Subject: [PATCH 4/6] linintg and black --- adafruit_thermal_printer/thermal_printer_2168.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/adafruit_thermal_printer/thermal_printer_2168.py b/adafruit_thermal_printer/thermal_printer_2168.py index 6ca3888..0423d29 100644 --- a/adafruit_thermal_printer/thermal_printer_2168.py +++ b/adafruit_thermal_printer/thermal_printer_2168.py @@ -99,9 +99,11 @@ def print_bitmap(self, file): """ Convert bitmap file and print as picture using GS v 0 command """ # pylint: disable=too-many-locals img = imageio.imread(file) + # pylint: disable=unused-variable try: if img.shape[2] == 4: # 3 colors with alpha channel red, green, blue, alpha = np.split(img, 4, axis=2) + # pylint: enable=unused-variable else: # just 3 colors red, green, blue = np.split(img, 3, axis=2) @@ -163,6 +165,7 @@ def _print_horizontal(self, mode, img_lx, img_hx, img_ly, img_hy, data): def _write_to_byte(self, pos, byte): """Helper method used in _convert_data_horizontally to compress pixel data into bytes""" + # pylint: disable=too-many-return-statements if pos == 0: return byte | 0b10000000 if pos == 1: @@ -179,6 +182,7 @@ def _write_to_byte(self, pos, byte): return byte | 0b00000010 if pos == 7: return byte | 0b00000001 + # pylint: enable=too-many-return-statements def _convert_data_horizontally(self, data_array): """Convert data from numpy array format to printer's horizontal printing module format""" From 81612ed3f973ca17cd228588f249c637bd4d484a Mon Sep 17 00:00:00 2001 From: greg-elmi Date: Mon, 21 Sep 2020 14:56:17 +0200 Subject: [PATCH 5/6] linintg and black2 --- adafruit_thermal_printer/thermal_printer_2168.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/adafruit_thermal_printer/thermal_printer_2168.py b/adafruit_thermal_printer/thermal_printer_2168.py index 0423d29..749bbc8 100644 --- a/adafruit_thermal_printer/thermal_printer_2168.py +++ b/adafruit_thermal_printer/thermal_printer_2168.py @@ -100,13 +100,14 @@ def print_bitmap(self, file): # pylint: disable=too-many-locals img = imageio.imread(file) # pylint: disable=unused-variable + # pylint: disable=unbalanced-tuple-unpacking try: if img.shape[2] == 4: # 3 colors with alpha channel red, green, blue, alpha = np.split(img, 4, axis=2) - # pylint: enable=unused-variable + # pylint: enable=unused-variable else: # just 3 colors red, green, blue = np.split(img, 3, axis=2) - + # pylint: enable=unbalanced-tuple-unpacking red = red.reshape(-1) green = green.reshape(-1) blue = blue.reshape(-1) @@ -163,9 +164,11 @@ def _print_horizontal(self, mode, img_lx, img_hx, img_ly, img_hy, data): self._uart.write(d) # pylint: enable=invalid-name + # pylint: disable=no-self-use def _write_to_byte(self, pos, byte): """Helper method used in _convert_data_horizontally to compress pixel data into bytes""" # pylint: disable=too-many-return-statements + if pos == 0: return byte | 0b10000000 if pos == 1: @@ -182,8 +185,11 @@ def _write_to_byte(self, pos, byte): return byte | 0b00000010 if pos == 7: return byte | 0b00000001 + return byte | 0b00000000 # pylint: enable=too-many-return-statements + # pylint: enable=no-self-use + def _convert_data_horizontally(self, data_array): """Convert data from numpy array format to printer's horizontal printing module format""" x_size = data_array.shape[1] @@ -191,6 +197,7 @@ def _convert_data_horizontally(self, data_array): datas = bytearray() # pylint: disable=invalid-name + # pylint: disable=too-many-nested-blocks for y in range(y_size): for x in range(0, x_size, 8): data = 0 @@ -205,4 +212,5 @@ def _convert_data_horizontally(self, data_array): pass datas.append(data) return datas + # pylint: enable=too-many-nested-blocks # pylint: enable=invalid-name From 494be941b8cc1ad0a21128f8310a0077f201e79c Mon Sep 17 00:00:00 2001 From: greg-elmi Date: Wed, 23 Sep 2020 10:50:47 +0200 Subject: [PATCH 6/6] added requirements to enable printing bitmaps --- requirements.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements.txt b/requirements.txt index c61620e..aab2c4d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,4 @@ Adafruit-Blinka pyserial +imageio +numpy