From 10977b06e730262b7b64ca21fb0a480aa5d6fae6 Mon Sep 17 00:00:00 2001 From: Patrick Kanzler Date: Mon, 1 Aug 2016 14:02:49 +0200 Subject: [PATCH 1/6] doc add hint on image preprocessing --- doc/user/usage.rst | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/doc/user/usage.rst b/doc/user/usage.rst index 1d848a1..91629cd 100644 --- a/doc/user/usage.rst +++ b/doc/user/usage.rst @@ -204,6 +204,37 @@ Here you can download an example, that will print a set of common barcodes: * :download:`barcode.bin ` by `@mike42 `_ +Hint: preprocess printing +------------------------- + +Printing images directly to the printer is rather slow. +One factor that slows down the process is the transmission over e.g. serial port. + +Apart from configuring your printer to use the maximum baudrate (in the case of serial-printers), there is not much +that you can do. +However you could use the :py:class:`escpos.printer.Dummy`-printer to preprocess your image. +This is probably best explained by an example: + +.. code-block:: Python + + from escpos.printer import Serial, Dummy + + p = Serial() + d = Dummy() + + # create ESC/POS for the print job, this should go really fast + d.text("This is my image:\n") + d.image("funny_cat.png") + d.cut() + + # send code to printer + p._raw(d.output) + +This way you could also store the code in a file and print later. +You could then for example print the code from another process than your main-program and thus reduce the waiting time. +(Of course this will not make the printer print faster.) + + How to update your code for USB printers ---------------------------------------- From 2ecf73074c166cea1da3249f521041f55b91b40c Mon Sep 17 00:00:00 2001 From: Patrick Kanzler Date: Mon, 1 Aug 2016 14:39:44 +0200 Subject: [PATCH 2/6] improve large image printing images longer than 1024 pixels will be split into multiple fragments. --- src/escpos/escpos.py | 14 +++++++++++++- src/escpos/image.py | 27 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/escpos/escpos.py b/src/escpos/escpos.py index 081130a..c0df537 100644 --- a/src/escpos/escpos.py +++ b/src/escpos/escpos.py @@ -56,7 +56,8 @@ class Escpos(object): """ pass - def image(self, img_source, high_density_vertical=True, high_density_horizontal=True, impl="bitImageRaster"): + def image(self, img_source, high_density_vertical=True, high_density_horizontal=True, impl="bitImageRaster", + fragment_height=1024): """ Print an image You can select whether the printer should print in high density or not. The default value is high density. @@ -76,9 +77,20 @@ class Escpos(object): :param high_density_vertical: print in high density in vertical direction *default:* True :param high_density_horizontal: print in high density in horizontal direction *default:* True :param impl: choose image printing mode between `bitImageRaster`, `graphics` or `bitImageColumn` + :param fragment_height: Images larger than this will be split into multiple fragments *default:* 1024 """ im = EscposImage(img_source) + + if im.height > fragment_height: + fragments = im.split(fragment_height) + for fragment in fragments: + self.image(fragment, + high_density_vertical=high_density_vertical, + high_density_horizontal=high_density_horizontal, + impl=impl, + fragment_height=fragment_height) + return if impl == "bitImageRaster": # GS v 0, raster format bit image diff --git a/src/escpos/image.py b/src/escpos/image.py index 1180614..abf2e22 100644 --- a/src/escpos/image.py +++ b/src/escpos/image.py @@ -8,6 +8,12 @@ This module contains the image format handler :py:class:`EscposImage`. :license: GNU GPL v3 """ +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +from __future__ import unicode_literals + +import math from PIL import Image, ImageOps @@ -30,6 +36,9 @@ class EscposImage(object): else: img_original = Image.open(img_source) + # store image for eventual further processing (splitting) + self.img_original = img_original + # Convert to white RGB background, paste over white background # to strip alpha. img_original = img_original.convert('RGBA') @@ -88,3 +97,21 @@ class EscposImage(object): Convert image to raster-format binary """ return self._im.tobytes() + + def split(self, fragment_height): + """ + Split an image into multiple fragments after fragment_height pixels + + :param fragment_height: height of fragment + :return: list of PIL objects + """ + passes = int(math.ceil(self.height/fragment_height)) + fragments = [] + for n in range(0, passes): + left = 0 + right = self.width + upper = n * fragment_height + lower = min((n + 1) * fragment_height, self.height) + box = (left, upper, right, lower) + fragments.append(self.img_original.crop(box)) + return fragments From eea2a6f9c01fb7f03f607e2fb9d10bc1e4ba8b47 Mon Sep 17 00:00:00 2001 From: Patrick Kanzler Date: Tue, 2 Aug 2016 16:41:47 +0200 Subject: [PATCH 3/6] travis: configure email-notifications --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 76794ac..cce6180 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,3 +34,7 @@ before_install: script: - tox - codecov +notifications: + email: + on_success: never + on_failure: change From dfe2cdbff8446affb53c42a557b1149422597de6 Mon Sep 17 00:00:00 2001 From: Patrick Kanzler Date: Tue, 2 Aug 2016 18:39:56 +0200 Subject: [PATCH 4/6] configure readthedocs with yml --- readthedocs.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 readthedocs.yml diff --git a/readthedocs.yml b/readthedocs.yml new file mode 100644 index 0000000..ecf365d --- /dev/null +++ b/readthedocs.yml @@ -0,0 +1,7 @@ +formats: + - pdf + - epub +requirements_file: doc/requirements.txt +python: + version: 2 + setup_py_install: true \ No newline at end of file From 603b34cadb5e0f4b1e7383db099331b84e75cba0 Mon Sep 17 00:00:00 2001 From: Patrick Kanzler Date: Sun, 7 Aug 2016 13:04:36 +0200 Subject: [PATCH 5/6] test add test for the fragment-splitting --- test/test_function_image.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/test_function_image.py b/test/test_function_image.py index f60aa76..b1762f6 100644 --- a/test/test_function_image.py +++ b/test/test_function_image.py @@ -130,3 +130,12 @@ def test_graphics_transparent(): instance = printer.Dummy() instance.image('test/resources/black_transparent.png', impl="graphics") assert(instance.output == b'\x1d(L\x0c\x000p0\x01\x011\x02\x00\x02\x00\xc0\x00\x1d(L\x02\x0002') + + +def test_large_graphics(): + """ + Test whether 'large' graphics that induce a fragmentation are handled correctly. + """ + instance = printer.Dummy() + instance.image('test/resources/black_white.png', impl="bitImageRaster", fragment_height=1) + assert(instance.output == b'\x1dv0\x00\x01\x00\x01\x00\xc0\x1dv0\x00\x01\x00\x01\x00\x00') From 59dccd79dac80e9e985a1ed90887e6deeb21761f Mon Sep 17 00:00:00 2001 From: Patrick Kanzler Date: Sun, 7 Aug 2016 14:39:58 +0200 Subject: [PATCH 6/6] test add test for image-splitting-method --- test/test_image.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/test_image.py b/test/test_image.py index dbfe5b0..6fda6dd 100644 --- a/test/test_image.py +++ b/test/test_image.py @@ -43,6 +43,20 @@ def test_image_white(): _load_and_check_img('canvas_white.' + img_format, 1, 1, b'\x00', [b'\x00']) +def test_split(): + """ + test whether the split-function works as expected + """ + im = EscposImage('test/resources/black_white.png') + (upper_part, lower_part) = im.split(1) + upper_part = EscposImage(upper_part) + lower_part = EscposImage(lower_part) + assert(upper_part.width == lower_part.width == 2) + assert(upper_part.height == lower_part.height == 1) + assert(upper_part.to_raster_format() == b'\xc0') + assert(lower_part.to_raster_format() == b'\x00') + + def _load_and_check_img(filename, width_expected, height_expected, raster_format_expected, column_format_expected): """ Load an image, and test whether raster & column formatted output, sizes, etc match expectations.