Merge github.com:python-escpos/python-escpos-1 into davisgoglin-merge

This commit is contained in:
Davis Goglin 2015-12-30 13:49:19 -08:00
commit 2fb27eabe2
3 changed files with 88 additions and 90 deletions

View File

@ -6,15 +6,14 @@
@license: GNU GPL v3 @license: GNU GPL v3
""" """
try: from PIL import Image, ImageOps
import Image
except ImportError:
from PIL import Image
import struct
import qrcode import qrcode
import time import time
import textwrap import textwrap
import binascii import binascii
import operator
from .constants import * from .constants import *
from .exceptions import * from .exceptions import *
@ -59,37 +58,59 @@ class Escpos(object):
else: else:
return (round(image_border / 2), round((image_border / 2) + 1)) return (round(image_border / 2), round((image_border / 2) + 1))
def _print_image(self, line, size): def _print_image(self, imagedata, n_rows, col_bytes):
""" Print formatted image """ Print formatted image
:param line: :param line:
:param size: :param size:
""" """
i = 0
cont = 0
pbuffer = ""
self._raw(S_RASTER_N) self._raw(S_RASTER_N)
pbuffer = "%02X%02X%02X%02X" % (((size[0]/size[1])/8), 0, size[1] & 0xff, size[1] >> 8) pbuffer = struct.pack('<HH', col_bytes, n_rows)
self._raw(binascii.unhexlify(pbuffer)) self._raw(pbuffer)
self._raw(imagedata)
pbuffer = "" pbuffer = ""
while i < len(line): def fullimage(self, img, max_height=860, width=512, histeq=True, bandsize=255):
hex_string = int(line[i:i+8], 2) """ Resizes and prints an arbitrarily sized image """
pbuffer += "%02X" % hex_string if isinstance(img, Image.Image):
i += 8 im = img.convert("RGB")
cont += 1 else:
if cont % 4 == 0: im = Image.open(img).convert("RGB")
self._raw(binascii.unhexlify(pbuffer))
pbuffer = ""
cont = 0
def _convert_image(self, im): if histeq:
""" Parse image and prepare it to a printable format # Histogram equaliztion
h = im.histogram()
lut = []
for b in range(0, len(h), 256):
# step size
step = reduce(operator.add, h[b:b+256]) // 255
# create equalization lookup table
n = 0
for i in range(256):
lut.append(n // step)
n = n + h[i+b]
im = im.point(lut)
:param im: image data if width:
:raises: ImageSizeError ratio = float(width) / im.size[0]
""" newheight = int(ratio * im.size[1])
# Resize the image
im = im.resize((width, newheight), Image.ANTIALIAS)
if max_height and im.size[1] > max_height:
im = im.crop((0, 0, im.size[0], max_height))
# Divide into bands
current = 0
while current < im.size[1]:
self.image(im.crop((0, current, width or im.size[0],
min(im.size[1], current + bandsize))))
current += bandsize
def image(self, im):
""" Parse image and prepare it to a printable format """
pixels = [] pixels = []
pix_line = "" pix_line = ""
im_left = "" im_left = ""
@ -97,61 +118,25 @@ class Escpos(object):
switch = 0 switch = 0
img_size = [ 0, 0 ] img_size = [ 0, 0 ]
if im.size[0] > 512: if not isinstance(im, Image.Image):
print ("WARNING: Image is wider than 512 and could be truncated at print time ") im = Image.open(im)
if im.size[1] > 0xffff:
im = im.convert("L")
im = ImageOps.invert(im)
im = im.convert("1")
if im.size[0] > 640:
print("WARNING: Image is wider than 640 and could be truncated at print time ")
if im.size[1] > 640:
raise ImageSizeError() raise ImageSizeError()
im_border = self._check_image_size(im.size[0]) orig_width, height = im.size
for i in range(im_border[0]): width = ((orig_width + 31) // 32) * 32
im_left += "0" new_image = Image.new("1", (width, height))
for i in range(im_border[1]): new_image.paste(im, (0, 0, orig_width, height))
im_right += "0"
for y in range(im.size[1]): the_bytes = new_image.tobytes()
img_size[1] += 1 self._print_image(the_bytes, n_rows=height, col_bytes=width//8)
pix_line += im_left
img_size[0] += im_border[0]
for x in range(im.size[0]):
img_size[0] += 1
RGB = im.getpixel((x, y))
im_color = (RGB[0] + RGB[1] + RGB[2])
im_pattern = "1X0"
pattern_len = len(im_pattern)
switch = (switch - 1) * (-1)
for x in range(pattern_len):
if im_color <= (255 * 3 / pattern_len * (x+1)):
if im_pattern[x] == "X":
pix_line += "%d" % switch
else:
pix_line += im_pattern[x]
break
elif (255 * 3 / pattern_len * pattern_len) < im_color <= (255 * 3):
pix_line += im_pattern[-1]
break
pix_line += im_right
img_size[0] += im_border[1]
self._print_image(pix_line, img_size)
<<<<<<< HEAD
def image(self, path_img):
""" Open image file
:param path_img: path to image
"""
im_open = Image.open(path_img)
# Remove the alpha channel on transparent images
if im_open.mode == 'RGBA':
im_open.load()
im = Image.new("RGB", im_open.size, (255, 255, 255))
im.paste(im_open, mask=im_open.split()[3])
else:
im = im_open.convert("RGB")
# Convert the RGB image in printable image
self._convert_image(im)
def direct_image(self, image): def direct_image(self, image):
""" Send image to printer""" """ Send image to printer"""
@ -186,19 +171,26 @@ class Escpos(object):
self._raw(binascii.unhexlify(bytes(buf, "ascii"))) self._raw(binascii.unhexlify(bytes(buf, "ascii")))
self._raw('\n') self._raw('\n')
def qr(self, text, error_correct=qrcode.constants.ERROR_CORRECT_M): def qr(self, text, error_correction=qrcode.constants.ERROR_CORRECT_M):
""" Print QR Code for the provided string """ Print QR Code for the provided string
:param text: text to generate a QR-Code from :param text: text to generate a QR-Code from
""" """
qr_code = qrcode.QRCode(version=4, box_size=4, border=1, error_correction=qrcode.constants.ERROR_CORRECT_H) qr_code = qrcode.QRCode(version=4, box_size=4, border=1, error_correction=error_correction)
qr_code.add_data(text) qr_code.add_data(text)
qr_code.make(fit=True) qr_code.make(fit=True)
qr_img = qr_code.make_image() qr_img = qr_code.make_image()
im = qr_img._img.convert("RGB")
# Convert the RGB image in printable image # Convert the RGB image in printable image
self._convert_image(im) im = qr_img._img.convert("1")
width = im.size[0]
height = im.size[1]
while width * 2 <= 640:
width *= 2
height *= 2
im = im.resize((width, height))
self.image(im)
self.text('\n')
def charcode(self, code): def charcode(self, code):
""" Set Character Code Table """ Set Character Code Table

View File

@ -177,9 +177,6 @@ class File(Escpos):
def _raw(self, msg): def _raw(self, msg):
""" Print any command sent in raw format """ """ Print any command sent in raw format """
if type(msg) is str:
self.device.write(msg.encode());
else:
self.device.write(msg); self.device.write(msg);
def __del__(self): def __del__(self):

9
escpos/utils.py Normal file
View File

@ -0,0 +1,9 @@
try:
bytes.fromhex
def hex2bytes(hex_string):
return bytes.fromhex(hex_string)
except:
def hex2bytes(hex_string):
return hex_string.decode('hex')