From e2ae0ffaf0b4123a84431461aefafa8150cdc8a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ignacio=20G=C3=B3mez?= Date: Mon, 20 Feb 2017 12:39:52 -0300 Subject: [PATCH 1/6] Speed improvements. --- brother_ql/brother_ql_create.py | 17 +++++- brother_ql/raster.py | 102 ++++++++++++++++++++++++++++---- 2 files changed, 104 insertions(+), 15 deletions(-) diff --git a/brother_ql/brother_ql_create.py b/brother_ql/brother_ql_create.py index 04f2225..4bd71f7 100755 --- a/brother_ql/brother_ql_create.py +++ b/brother_ql/brother_ql_create.py @@ -5,11 +5,14 @@ from __future__ import division import sys, argparse, logging from PIL import Image +import PIL.ImageOps from brother_ql.raster import BrotherQLRaster from brother_ql.devicedependent import models, label_type_specs, ENDLESS_LABEL, DIE_CUT_LABEL, ROUND_DIE_CUT_LABEL from brother_ql import BrotherQLError, BrotherQLUnsupportedCmd, BrotherQLUnknownModel +import multiprocessing + try: stdout = sys.stdout.buffer except: @@ -23,6 +26,9 @@ except: logger = logging.getLogger(__name__) def main(): + + defaultCores = multiprocessing.cpu_count() + parser = argparse.ArgumentParser() parser.add_argument('image', help='The image file to create a label from.') parser.add_argument('outfile', nargs='?', type=argparse.FileType('wb'), default=stdout, help='The file to write the instructions to. Defaults to stdout.') @@ -32,6 +38,7 @@ def main(): parser.add_argument('--threshold', '-t', type=float, default=70.0, help='The threshold value (in percent) to discriminate between black and white pixels.') parser.add_argument('--no-cut', dest='cut', action='store_false', help="Don't cut the tape after printing the label.") parser.add_argument('--loglevel', type=lambda x: getattr(logging, x), default=logging.WARNING, help='Set to DEBUG for verbose debugging output to stderr.') + parser.add_argument('--cores', '-c', type=int, default=defaultCores, help='The number of cores to use on creating the bin file.') args = parser.parse_args() logging.basicConfig(level=args.loglevel) @@ -51,11 +58,14 @@ def main(): qlr.exception_on_warning = True - create_label(qlr, args.image, args.label_size, threshold=args.threshold, cut=args.cut, rotate=args.rotate) + coresMessage = "Attempting to create using " + str(args.cores) + " cores." + logger.debug(coresMessage) + + create_label(qlr, args.image, args.label_size, cores=args.cores, threshold=args.threshold, cut=args.cut, rotate=args.rotate) args.outfile.write(qlr.data) -def create_label(qlr, image, label_size, threshold=70, cut=True, **kwargs): +def create_label(qlr, image, label_size, cores, threshold=70, cut=True, **kwargs): label_specs = label_type_specs[label_size] dots_printable = label_specs['dots_printable'] @@ -100,6 +110,7 @@ def create_label(qlr, image, label_size, threshold=70, cut=True, **kwargs): new_im.paste(im, (device_pixel_width-im.size[0]-right_margin_dots, 0)) im = new_im + im = PIL.ImageOps.invert(im) threshold = min(255, max(0, int(threshold/100.0 * 255))) # from percent to pixel val im = im.point(lambda x: 0 if x < threshold else 255, mode="1") @@ -142,7 +153,7 @@ def create_label(qlr, image, label_size, threshold=70, cut=True, **kwargs): qlr.add_compression(True) except BrotherQLUnsupportedCmd: pass - qlr.add_raster_data(im) + qlr.add_raster_data(im, cores) qlr.add_print() if __name__ == "__main__": diff --git a/brother_ql/raster.py b/brother_ql/raster.py index 086afbd..5c8a73b 100644 --- a/brother_ql/raster.py +++ b/brother_ql/raster.py @@ -6,6 +6,7 @@ import logging import packbits from PIL import Image +import io from .devicedependent import models, \ min_max_feed, \ @@ -19,6 +20,12 @@ from .devicedependent import models, \ from . import BrotherQLError, BrotherQLUnsupportedCmd, BrotherQLUnknownModel, BrotherQLRasterError +import multiprocessing, ctypes + +from multiprocessing import Process, Manager, Array + +from cStringIO import StringIO + logger = logging.getLogger(__name__) class BrotherQLRaster(object): @@ -168,7 +175,7 @@ class BrotherQLRaster(object): nbpr = number_bytes_per_row['default'] return nbpr*8 - def add_raster_data(self, image): + def add_raster_data(self, image, cores): """ image: Pillow Image() """ logger.info("raster_image_size: {0}x{1}".format(*image.size)) image = image.transpose(Image.FLIP_LEFT_RIGHT) @@ -177,23 +184,94 @@ class BrotherQLRaster(object): fmt = 'Wrong pixel width: {}, expected {}' raise BrotherQLRasterError(fmt.format(image.size[0], self.get_pixel_width())) frame = bytes(image.tobytes(encoder_name='raw')) - # The above command directly returns the 1-bit image packed - # into bits. (The cast to bytes is needed for Py2 compatibility.) - frame = bytes([2**8 + ~byte for byte in frame]) # invert b/w + frame_len = len(frame) row_len = image.size[0]//8 start = 0 - while start + row_len <= frame_len: - row = frame[start:start+row_len] - start += row_len - self.data += b'\x67\x00' # g 0x00 - if self._compression: - row = packbits.encode(row) - self.data += bytes([len(row)]) - self.data += row + + file_str = StringIO() + + logger.debug("Frame " + str(frame_len) + " Row " + str(row_len)) + + #If the rowLen to subframeLen prop isn't and int, data would be lost. + if cores > 1: + + lCheck = float(float(frame_len) / (float(row_len) * float(cores))).is_integer() + logger.debug("Using " + str(cores) + " cores in add_raster_data.") + processes = {} + manager = Manager() + gData = manager.list(['']*cores) + + if lCheck: + subFrameLen = int(frame_len/cores) + for i in range(0, cores): + + subFrameStart =int(subFrameLen * i) + subframeLimit = int(subFrameLen * (i+1)) + subframe = frame[subFrameStart:subframeLimit] + processes[i] = Process(target=self.processFrame, args=(0, row_len, subFrameLen, subframe, i, gData,)) + processes[i].start() + else: + numRows = int(float(frame_len) / (float(row_len) * float(cores))) + lastNum = 0 + subFrameLen = int(row_len * numRows) + for i in range(0, cores - 1): + + subFrameStart =int(subFrameLen * i) + subframeLimit = int(subFrameLen * (i+1)) + lastNum = subframeLimit + subframe = frame[subFrameStart:subframeLimit] + processes[i] = Process(target=self.processFrame, args=(0, row_len, subFrameLen, subframe, i, gData,)) + processes[i].start() + + subframe = frame[lastNum:frame_len] + processes[cores - 1] = Process(target=self.processFrame, args=(0, row_len, frame_len - lastNum, subframe, cores - 1, gData,)) + processes[cores-1].start() + + for i in range(0, cores): + processes[i].join() + + for i in range(0, cores): + self.data += gData[i] + + else: + + logger.debug("Using 1 core in add_raster_data (" + str(cores) + " given).") + + while start + row_len <= frame_len: + row = frame[start:start+row_len] + start += row_len + #self.data += b'\x67\x00' # g 0x00 + file_str.write(b'\x67\x00') + if self._compression: + row = packbits.encode(row) + #self.data += bytes([len(row)]) + #self.data += row + file_str.write(bytes([len(row)])) + file_str.write(row) + + self.data += file_str.getvalue() def add_print(self, last_page=True): if last_page: self.data += b'\x1A' # 0x1A = ^Z = SUB; here: EOF = End of File else: self.data += b'\x0C' # 0x0C = FF = Form Feed + + + def processFrame(self, start, row_len, frame_len, frame, index, gData): + + file_str = StringIO() + while start + row_len <= frame_len: + row = frame[start:start+row_len] + start += row_len + #self.data += b'\x67\x00' # g 0x00 + file_str.write(b'\x67\x00') + if self._compression: + row = packbits.encode(row) + #self.data += bytes([len(row)]) + #self.data += row + file_str.write(bytes([len(row)])) + file_str.write(row) + + gData[index] = file_str.getvalue() From 9e495b813f20d3dc5b4c602e4556a7ac780ca11e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ignacio=20G=C3=B3mez?= Date: Mon, 20 Feb 2017 12:49:07 -0300 Subject: [PATCH 2/6] Code case fix. --- brother_ql/raster.py | 47 ++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/brother_ql/raster.py b/brother_ql/raster.py index 5c8a73b..86a1820 100644 --- a/brother_ql/raster.py +++ b/brother_ql/raster.py @@ -192,47 +192,48 @@ class BrotherQLRaster(object): file_str = StringIO() logger.debug("Frame " + str(frame_len) + " Row " + str(row_len)) - - #If the rowLen to subframeLen prop isn't and int, data would be lost. + if cores > 1: - lCheck = float(float(frame_len) / (float(row_len) * float(cores))).is_integer() + len_prop = float(float(frame_len) / (float(row_len) * float(cores))) + len_check = len_prop.is_integer() logger.debug("Using " + str(cores) + " cores in add_raster_data.") processes = {} manager = Manager() - gData = manager.list(['']*cores) + g_data = manager.list(['']*cores) - if lCheck: - subFrameLen = int(frame_len/cores) + #Check if we can equally assign subframes to processes, or adjust their length to fit. + if len_check: + subframe_len = int(frame_len/cores) for i in range(0, cores): - subFrameStart =int(subFrameLen * i) - subframeLimit = int(subFrameLen * (i+1)) - subframe = frame[subFrameStart:subframeLimit] - processes[i] = Process(target=self.processFrame, args=(0, row_len, subFrameLen, subframe, i, gData,)) + subframe_start =int(subframe_len * i) + subframe_limit = int(subframe_len * (i+1)) + subframe = frame[subframe_start:subframe_limit] + processes[i] = Process(target=self.processFrame, args=(0, row_len, subframe_len, subframe, i, g_data,)) processes[i].start() else: - numRows = int(float(frame_len) / (float(row_len) * float(cores))) - lastNum = 0 - subFrameLen = int(row_len * numRows) + num_rows = int(float(frame_len) / (float(row_len) * float(cores))) + last_limit = 0 + subframe_len = int(row_len * num_rows) for i in range(0, cores - 1): - subFrameStart =int(subFrameLen * i) - subframeLimit = int(subFrameLen * (i+1)) - lastNum = subframeLimit - subframe = frame[subFrameStart:subframeLimit] - processes[i] = Process(target=self.processFrame, args=(0, row_len, subFrameLen, subframe, i, gData,)) + subframe_start =int(subframe_len * i) + subframe_limit = int(subframe_len * (i+1)) + last_limit = subframe_limit + subframe = frame[subframe_start:subframe_limit] + processes[i] = Process(target=self.processFrame, args=(0, row_len, subframe_len, subframe, i, g_data,)) processes[i].start() - subframe = frame[lastNum:frame_len] - processes[cores - 1] = Process(target=self.processFrame, args=(0, row_len, frame_len - lastNum, subframe, cores - 1, gData,)) + subframe = frame[last_limit:frame_len] + processes[cores - 1] = Process(target=self.processFrame, args=(0, row_len, frame_len - last_limit, subframe, cores - 1, g_data,)) processes[cores-1].start() for i in range(0, cores): processes[i].join() for i in range(0, cores): - self.data += gData[i] + self.data += g_data[i] else: @@ -259,7 +260,7 @@ class BrotherQLRaster(object): self.data += b'\x0C' # 0x0C = FF = Form Feed - def processFrame(self, start, row_len, frame_len, frame, index, gData): + def processFrame(self, start, row_len, frame_len, frame, index, g_data): file_str = StringIO() while start + row_len <= frame_len: @@ -274,4 +275,4 @@ class BrotherQLRaster(object): file_str.write(bytes([len(row)])) file_str.write(row) - gData[index] = file_str.getvalue() + g_data[index] = file_str.getvalue() From af41f52aa9dd10f67a8f1604ff9e0e9e66e16950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ignacio=20G=C3=B3mez?= Date: Mon, 20 Feb 2017 12:54:23 -0300 Subject: [PATCH 3/6] Threshold changed. --- brother_ql/brother_ql_create.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/brother_ql/brother_ql_create.py b/brother_ql/brother_ql_create.py index 4bd71f7..d5c1516 100755 --- a/brother_ql/brother_ql_create.py +++ b/brother_ql/brother_ql_create.py @@ -35,7 +35,7 @@ def main(): parser.add_argument('--model', '-m', default='QL-500', help='The printer model to use. Check available ones with `brother_ql_info list-models`.') parser.add_argument('--label-size', '-s', default='62', help='The label size (and kind) to use. Check available ones with `brother_ql_info list-label-sizes`.') parser.add_argument('--rotate', '-r', choices=('0', '90', '180', '270'), default='auto', help='Rotate the image (counterclock-wise) by this amount of degrees.') - parser.add_argument('--threshold', '-t', type=float, default=70.0, help='The threshold value (in percent) to discriminate between black and white pixels.') + parser.add_argument('--threshold', '-t', type=float, default=30.0, help='The threshold value (in percent) to discriminate between black and white pixels.') parser.add_argument('--no-cut', dest='cut', action='store_false', help="Don't cut the tape after printing the label.") parser.add_argument('--loglevel', type=lambda x: getattr(logging, x), default=logging.WARNING, help='Set to DEBUG for verbose debugging output to stderr.') parser.add_argument('--cores', '-c', type=int, default=defaultCores, help='The number of cores to use on creating the bin file.') @@ -65,7 +65,7 @@ def main(): args.outfile.write(qlr.data) -def create_label(qlr, image, label_size, cores, threshold=70, cut=True, **kwargs): +def create_label(qlr, image, label_size, cores, threshold=30, cut=True, **kwargs): label_specs = label_type_specs[label_size] dots_printable = label_specs['dots_printable'] From 0cc7d1febfff8316ee43b3fccaabb8b93fc5fec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ignacio=20G=C3=B3mez?= Date: Tue, 21 Feb 2017 10:40:48 -0300 Subject: [PATCH 4/6] Cores optional param, change to BytesIO and code cleanup. --- brother_ql/brother_ql_create.py | 6 ++++-- brother_ql/raster.py | 17 ++++++----------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/brother_ql/brother_ql_create.py b/brother_ql/brother_ql_create.py index d5c1516..631fd96 100755 --- a/brother_ql/brother_ql_create.py +++ b/brother_ql/brother_ql_create.py @@ -35,7 +35,7 @@ def main(): parser.add_argument('--model', '-m', default='QL-500', help='The printer model to use. Check available ones with `brother_ql_info list-models`.') parser.add_argument('--label-size', '-s', default='62', help='The label size (and kind) to use. Check available ones with `brother_ql_info list-label-sizes`.') parser.add_argument('--rotate', '-r', choices=('0', '90', '180', '270'), default='auto', help='Rotate the image (counterclock-wise) by this amount of degrees.') - parser.add_argument('--threshold', '-t', type=float, default=30.0, help='The threshold value (in percent) to discriminate between black and white pixels.') + parser.add_argument('--threshold', '-t', type=float, default=70.0, help='The threshold value (in percent) to discriminate between black and white pixels.') parser.add_argument('--no-cut', dest='cut', action='store_false', help="Don't cut the tape after printing the label.") parser.add_argument('--loglevel', type=lambda x: getattr(logging, x), default=logging.WARNING, help='Set to DEBUG for verbose debugging output to stderr.') parser.add_argument('--cores', '-c', type=int, default=defaultCores, help='The number of cores to use on creating the bin file.') @@ -65,7 +65,7 @@ def main(): args.outfile.write(qlr.data) -def create_label(qlr, image, label_size, cores, threshold=30, cut=True, **kwargs): +def create_label(qlr, image, label_size, cores, threshold=70, cut=True, **kwargs): label_specs = label_type_specs[label_size] dots_printable = label_specs['dots_printable'] @@ -111,6 +111,8 @@ def create_label(qlr, image, label_size, cores, threshold=30, cut=True, **kwargs im = new_im im = PIL.ImageOps.invert(im) + + threshold = 100.0 - threshold threshold = min(255, max(0, int(threshold/100.0 * 255))) # from percent to pixel val im = im.point(lambda x: 0 if x < threshold else 255, mode="1") diff --git a/brother_ql/raster.py b/brother_ql/raster.py index 86a1820..da85f07 100644 --- a/brother_ql/raster.py +++ b/brother_ql/raster.py @@ -20,11 +20,11 @@ from .devicedependent import models, \ from . import BrotherQLError, BrotherQLUnsupportedCmd, BrotherQLUnknownModel, BrotherQLRasterError -import multiprocessing, ctypes +import multiprocessing -from multiprocessing import Process, Manager, Array +from multiprocessing import Process, Manager -from cStringIO import StringIO +from io import BytesIO logger = logging.getLogger(__name__) @@ -175,7 +175,7 @@ class BrotherQLRaster(object): nbpr = number_bytes_per_row['default'] return nbpr*8 - def add_raster_data(self, image, cores): + def add_raster_data(self, image, cores=1): """ image: Pillow Image() """ logger.info("raster_image_size: {0}x{1}".format(*image.size)) image = image.transpose(Image.FLIP_LEFT_RIGHT) @@ -189,9 +189,7 @@ class BrotherQLRaster(object): row_len = image.size[0]//8 start = 0 - file_str = StringIO() - - logger.debug("Frame " + str(frame_len) + " Row " + str(row_len)) + file_str = BytesIO() if cores > 1: @@ -242,12 +240,9 @@ class BrotherQLRaster(object): while start + row_len <= frame_len: row = frame[start:start+row_len] start += row_len - #self.data += b'\x67\x00' # g 0x00 file_str.write(b'\x67\x00') if self._compression: row = packbits.encode(row) - #self.data += bytes([len(row)]) - #self.data += row file_str.write(bytes([len(row)])) file_str.write(row) @@ -262,7 +257,7 @@ class BrotherQLRaster(object): def processFrame(self, start, row_len, frame_len, frame, index, g_data): - file_str = StringIO() + file_str = BytesIO() while start + row_len <= frame_len: row = frame[start:start+row_len] start += row_len From 670068ce9595718d4998fbf8e8a6c18bc338f1ad Mon Sep 17 00:00:00 2001 From: Philipp Klaus Date: Mon, 3 Jul 2017 09:45:56 +0200 Subject: [PATCH 5/6] removed multiprocessing for now --- brother_ql/brother_ql_create.py | 15 ++---- brother_ql/raster.py | 92 ++++----------------------------- 2 files changed, 13 insertions(+), 94 deletions(-) diff --git a/brother_ql/brother_ql_create.py b/brother_ql/brother_ql_create.py index 631fd96..cccc052 100755 --- a/brother_ql/brother_ql_create.py +++ b/brother_ql/brother_ql_create.py @@ -11,8 +11,6 @@ from brother_ql.raster import BrotherQLRaster from brother_ql.devicedependent import models, label_type_specs, ENDLESS_LABEL, DIE_CUT_LABEL, ROUND_DIE_CUT_LABEL from brother_ql import BrotherQLError, BrotherQLUnsupportedCmd, BrotherQLUnknownModel -import multiprocessing - try: stdout = sys.stdout.buffer except: @@ -26,9 +24,6 @@ except: logger = logging.getLogger(__name__) def main(): - - defaultCores = multiprocessing.cpu_count() - parser = argparse.ArgumentParser() parser.add_argument('image', help='The image file to create a label from.') parser.add_argument('outfile', nargs='?', type=argparse.FileType('wb'), default=stdout, help='The file to write the instructions to. Defaults to stdout.') @@ -38,7 +33,6 @@ def main(): parser.add_argument('--threshold', '-t', type=float, default=70.0, help='The threshold value (in percent) to discriminate between black and white pixels.') parser.add_argument('--no-cut', dest='cut', action='store_false', help="Don't cut the tape after printing the label.") parser.add_argument('--loglevel', type=lambda x: getattr(logging, x), default=logging.WARNING, help='Set to DEBUG for verbose debugging output to stderr.') - parser.add_argument('--cores', '-c', type=int, default=defaultCores, help='The number of cores to use on creating the bin file.') args = parser.parse_args() logging.basicConfig(level=args.loglevel) @@ -58,14 +52,11 @@ def main(): qlr.exception_on_warning = True - coresMessage = "Attempting to create using " + str(args.cores) + " cores." - logger.debug(coresMessage) - - create_label(qlr, args.image, args.label_size, cores=args.cores, threshold=args.threshold, cut=args.cut, rotate=args.rotate) + create_label(qlr, args.image, args.label_size, threshold=args.threshold, cut=args.cut, rotate=args.rotate) args.outfile.write(qlr.data) -def create_label(qlr, image, label_size, cores, threshold=70, cut=True, **kwargs): +def create_label(qlr, image, label_size, threshold=70, cut=True, **kwargs): label_specs = label_type_specs[label_size] dots_printable = label_specs['dots_printable'] @@ -155,7 +146,7 @@ def create_label(qlr, image, label_size, cores, threshold=70, cut=True, **kwargs qlr.add_compression(True) except BrotherQLUnsupportedCmd: pass - qlr.add_raster_data(im, cores) + qlr.add_raster_data(im) qlr.add_print() if __name__ == "__main__": diff --git a/brother_ql/raster.py b/brother_ql/raster.py index da85f07..e631027 100644 --- a/brother_ql/raster.py +++ b/brother_ql/raster.py @@ -20,10 +20,6 @@ from .devicedependent import models, \ from . import BrotherQLError, BrotherQLUnsupportedCmd, BrotherQLUnknownModel, BrotherQLRasterError -import multiprocessing - -from multiprocessing import Process, Manager - from io import BytesIO logger = logging.getLogger(__name__) @@ -175,7 +171,7 @@ class BrotherQLRaster(object): nbpr = number_bytes_per_row['default'] return nbpr*8 - def add_raster_data(self, image, cores=1): + def add_raster_data(self, image): """ image: Pillow Image() """ logger.info("raster_image_size: {0}x{1}".format(*image.size)) image = image.transpose(Image.FLIP_LEFT_RIGHT) @@ -184,90 +180,22 @@ class BrotherQLRaster(object): fmt = 'Wrong pixel width: {}, expected {}' raise BrotherQLRasterError(fmt.format(image.size[0], self.get_pixel_width())) frame = bytes(image.tobytes(encoder_name='raw')) - frame_len = len(frame) row_len = image.size[0]//8 start = 0 - file_str = BytesIO() - - if cores > 1: - - len_prop = float(float(frame_len) / (float(row_len) * float(cores))) - len_check = len_prop.is_integer() - logger.debug("Using " + str(cores) + " cores in add_raster_data.") - processes = {} - manager = Manager() - g_data = manager.list(['']*cores) - - #Check if we can equally assign subframes to processes, or adjust their length to fit. - if len_check: - subframe_len = int(frame_len/cores) - for i in range(0, cores): - - subframe_start =int(subframe_len * i) - subframe_limit = int(subframe_len * (i+1)) - subframe = frame[subframe_start:subframe_limit] - processes[i] = Process(target=self.processFrame, args=(0, row_len, subframe_len, subframe, i, g_data,)) - processes[i].start() - else: - num_rows = int(float(frame_len) / (float(row_len) * float(cores))) - last_limit = 0 - subframe_len = int(row_len * num_rows) - for i in range(0, cores - 1): - - subframe_start =int(subframe_len * i) - subframe_limit = int(subframe_len * (i+1)) - last_limit = subframe_limit - subframe = frame[subframe_start:subframe_limit] - processes[i] = Process(target=self.processFrame, args=(0, row_len, subframe_len, subframe, i, g_data,)) - processes[i].start() - - subframe = frame[last_limit:frame_len] - processes[cores - 1] = Process(target=self.processFrame, args=(0, row_len, frame_len - last_limit, subframe, cores - 1, g_data,)) - processes[cores-1].start() - - for i in range(0, cores): - processes[i].join() - - for i in range(0, cores): - self.data += g_data[i] - - else: - - logger.debug("Using 1 core in add_raster_data (" + str(cores) + " given).") - - while start + row_len <= frame_len: - row = frame[start:start+row_len] - start += row_len - file_str.write(b'\x67\x00') - if self._compression: - row = packbits.encode(row) - file_str.write(bytes([len(row)])) - file_str.write(row) - - self.data += file_str.getvalue() + while start + row_len <= frame_len: + row = frame[start:start+row_len] + start += row_len + file_str.write(b'\x67\x00') + if self._compression: + row = packbits.encode(row) + file_str.write(bytes([len(row)])) + file_str.write(row) + self.data += file_str.getvalue() def add_print(self, last_page=True): if last_page: self.data += b'\x1A' # 0x1A = ^Z = SUB; here: EOF = End of File else: self.data += b'\x0C' # 0x0C = FF = Form Feed - - - def processFrame(self, start, row_len, frame_len, frame, index, g_data): - - file_str = BytesIO() - while start + row_len <= frame_len: - row = frame[start:start+row_len] - start += row_len - #self.data += b'\x67\x00' # g 0x00 - file_str.write(b'\x67\x00') - if self._compression: - row = packbits.encode(row) - #self.data += bytes([len(row)]) - #self.data += row - file_str.write(bytes([len(row)])) - file_str.write(row) - - g_data[index] = file_str.getvalue() From 2c8620f94e4f2ca1f7af00a595230c994a9890cc Mon Sep 17 00:00:00 2001 From: Philipp Klaus Date: Mon, 3 Jul 2017 09:42:28 +0200 Subject: [PATCH 6/6] raster.py: Py2 compat --- brother_ql/raster.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/brother_ql/raster.py b/brother_ql/raster.py index e631027..7e90df1 100644 --- a/brother_ql/raster.py +++ b/brother_ql/raster.py @@ -20,7 +20,10 @@ from .devicedependent import models, \ from . import BrotherQLError, BrotherQLUnsupportedCmd, BrotherQLUnknownModel, BrotherQLRasterError -from io import BytesIO +try: + from io import BytesIO +except: # Py2 + from cStringIO import StringIO as BytesIO logger = logging.getLogger(__name__)