Skip to content

Commit

Permalink
Merge pull request #17 from benoitguigal/raspi2
Browse files Browse the repository at this point in the history
Raspi2
  • Loading branch information
benoitguigal committed Feb 17, 2015
2 parents 9bf9981 + 3753206 commit 4dce147
Showing 1 changed file with 66 additions and 46 deletions.
112 changes: 66 additions & 46 deletions epson_printer/epsonprinter.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from __future__ import division
import math
import usb.core
from PIL import Image
import itertools
from functools import wraps

from multiprocessing import Pool, cpu_count
from PIL import Image

ESC = 27
GS = 29
Expand Down Expand Up @@ -85,6 +86,55 @@ def set_print_speed(speed):
speed]
return byte_array

CPU_COUNT = cpu_count()


def marshall_stripe(stripe, w):
"""
Re-arrange a 24 bits height stripe of pixels into a top to bottom then left to right array
See http://nicholas.piasecki.name/blog/2009/12/sending-a-bit-image-to-an-epson-tm-t88iii-receipt-printer-using-c-and-escpos/
:param stripe: pixels of the stripe
:param w: width of the stripe
:return:
"""

# Calculate nL and nH
nh = int(w / 256)
nl = w % 256

data = []
data.extend([
ESC,
42, # *
33, # double density mode
nl,
nh])
for x in range(w):
for k in range(3):
slice = 0
for b in range(8):
y = (k * 8) + b
i = (y * w) + x
v = 0
if i < len(stripe):
if stripe[i] != 255:
v = 1
slice |= (v << (7 - b))

data.append(slice)

data.extend([
27, # ESC
74, # J
48])

return data


def marshall_stripe_star(stripe_w):
""" See http://stackoverflow.com/questions/5442910/python-multiprocessing-pool-map-for-multiple-arguments """
return marshall_stripe(*stripe_w)


class PrintableImage:
"""
Expand All @@ -105,54 +155,26 @@ def from_image(cls, image):
:return:
"""
(w, h) = image.size

# Thermal paper is 512 pixels wide
if w > 512:
ratio = 512. / w
h = int(h * ratio)
image = image.resize((512, h), Image.ANTIALIAS)
image = image.convert('1')
pixels = list(image.getdata())

data = []
nb_stripes = int(math.ceil(h / 24))
# account for double density and page mode approximate
height = int(math.ceil(h / 24) * 48)

# Calculate nL and nH
nh = int(w / 256)
nl = w % 256

offset = 0

while offset < h:
data.extend([
ESC,
42, # *
33, # double density mode
nl,
nh])
height = int(nb_stripes * 48)

for x in range(w):
for k in range(3):
slice = 0
for b in range(8):
y = offset + (k * 8) + b
i = (y * w) + x
v = 0
if i < len(pixels):
if pixels[i] != 255:
v = 1
slice |= (v << (7 - b))

data.append(slice)

offset += 24

data.extend([
27, # ESC
74, # J
48])

return cls(data, height)
# Balance the data processing between different cores (this is particularly useful on Raspberry Pi 2)
pool = Pool(processes=CPU_COUNT)
stripes = [pixels[24*w*i:24*w*(i+1)] for i in range(0, nb_stripes)]
marshalled_stripes = pool.map(marshall_stripe_star, itertools.izip(stripes, itertools.repeat(w)))
merged = list(itertools.chain.from_iterable(marshalled_stripes))

return cls(merged, height)

def append(self, other):
"""
Expand All @@ -165,23 +187,22 @@ def append(self, other):
return self



class EpsonPrinter:
""" An Epson thermal printer based on ESC/POS"""

printer = None

def __init__(self, id_vendor, id_product, interface=0, in_ep=0x82, out_ep=0x01):
"""
@param idVendor : Vendor ID
@param idProduct : Product ID
@param id_vendor : Vendor ID
@param id_product : Product ID
@param interface : USB device interface
@param in_ep : Input end point
@param out_ep : Output end point
"""
self.interface = interface
self.in_ep = in_ep
self.out_ep = out_ep
self.in_ep = in_ep
self.out_ep = out_ep

# Search device on USB tree and set is as printer
self.printer = usb.core.find(idVendor=id_vendor, idProduct=id_product)
Expand Down Expand Up @@ -210,7 +231,6 @@ def wrapper(self, *args, **kwargs):
self.write_bytes(byte_array)
return wrapper


def write_bytes(self, byte_array):
msg = ''.join([chr(b) for b in byte_array])
self.write(msg)
Expand Down

0 comments on commit 4dce147

Please sign in to comment.