mirror of
				https://github.com/python-escpos/python-escpos
				synced 2025-10-23 09:30:00 +00:00 
			
		
		
		
	Merge branch 'master' of github.com:python-escpos/python-escpos
This commit is contained in:
		@@ -34,3 +34,7 @@ before_install:
 | 
				
			|||||||
script:
 | 
					script:
 | 
				
			||||||
    - tox
 | 
					    - tox
 | 
				
			||||||
    - codecov
 | 
					    - codecov
 | 
				
			||||||
 | 
					notifications:
 | 
				
			||||||
 | 
					  email:
 | 
				
			||||||
 | 
					    on_success: never
 | 
				
			||||||
 | 
					    on_failure: change
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -204,6 +204,37 @@ Here you can download an example, that will print a set of common barcodes:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    * :download:`barcode.bin </download/barcode.bin>` by `@mike42 <https://github.com/mike42>`_
 | 
					    * :download:`barcode.bin </download/barcode.bin>` by `@mike42 <https://github.com/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
 | 
					How to update your code for USB printers
 | 
				
			||||||
----------------------------------------
 | 
					----------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								readthedocs.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								readthedocs.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					formats:
 | 
				
			||||||
 | 
					  - pdf
 | 
				
			||||||
 | 
					  - epub
 | 
				
			||||||
 | 
					requirements_file: doc/requirements.txt
 | 
				
			||||||
 | 
					python:
 | 
				
			||||||
 | 
					  version: 2
 | 
				
			||||||
 | 
					  setup_py_install: true
 | 
				
			||||||
@@ -56,7 +56,8 @@ class Escpos(object):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        pass
 | 
					        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
 | 
					        """ Print an image
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        You can select whether the printer should print in high density or not. The default value is high density.
 | 
					        You can select whether the printer should print in high density or not. The default value is high density.
 | 
				
			||||||
@@ -76,10 +77,21 @@ class Escpos(object):
 | 
				
			|||||||
        :param high_density_vertical: print in high density in vertical direction *default:* True
 | 
					        :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 high_density_horizontal: print in high density in horizontal direction *default:* True
 | 
				
			||||||
        :param impl: choose image printing mode between `bitImageRaster`, `graphics` or `bitImageColumn`
 | 
					        :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)
 | 
					        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":
 | 
					        if impl == "bitImageRaster":
 | 
				
			||||||
            # GS v 0, raster format bit image
 | 
					            # GS v 0, raster format bit image
 | 
				
			||||||
            density_byte = (0 if high_density_horizontal else 1) + (0 if high_density_vertical else 2)
 | 
					            density_byte = (0 if high_density_horizontal else 1) + (0 if high_density_vertical else 2)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,12 @@ This module contains the image format handler :py:class:`EscposImage`.
 | 
				
			|||||||
:license: GNU GPL v3
 | 
					: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
 | 
					from PIL import Image, ImageOps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -30,6 +36,9 @@ class EscposImage(object):
 | 
				
			|||||||
        else:
 | 
					        else:
 | 
				
			||||||
            img_original = Image.open(img_source)
 | 
					            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
 | 
					        # Convert to white RGB background, paste over white background
 | 
				
			||||||
        # to strip alpha.
 | 
					        # to strip alpha.
 | 
				
			||||||
        img_original = img_original.convert('RGBA')
 | 
					        img_original = img_original.convert('RGBA')
 | 
				
			||||||
@@ -88,3 +97,21 @@ class EscposImage(object):
 | 
				
			|||||||
        Convert image to raster-format binary
 | 
					        Convert image to raster-format binary
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return self._im.tobytes()
 | 
					        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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -130,3 +130,12 @@ def test_graphics_transparent():
 | 
				
			|||||||
    instance = printer.Dummy()
 | 
					    instance = printer.Dummy()
 | 
				
			||||||
    instance.image('test/resources/black_transparent.png', impl="graphics")
 | 
					    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')
 | 
					    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')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,6 +43,20 @@ def test_image_white():
 | 
				
			|||||||
        _load_and_check_img('canvas_white.' + img_format, 1, 1, b'\x00', [b'\x00'])
 | 
					        _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):
 | 
					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.
 | 
					    Load an image, and test whether raster & column formatted output, sizes, etc match expectations.
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user