[IMP] point_of_sale, hw_escpos: hopefully much faster printing on the posbox by caching logo conversion
bzr revid: fva@openerp.com-20140130182109-11njt0khmylp0r7p
This commit is contained in:
parent
62aad0c4b8
commit
ba2d4c9030
|
@ -8,6 +8,7 @@ import openerp
|
||||||
import time
|
import time
|
||||||
import random
|
import random
|
||||||
import math
|
import math
|
||||||
|
import md5
|
||||||
import openerp.addons.hw_proxy.controllers.main as hw_proxy
|
import openerp.addons.hw_proxy.controllers.main as hw_proxy
|
||||||
import subprocess
|
import subprocess
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
@ -150,25 +151,9 @@ class EscposDriver(Thread):
|
||||||
for tax in taxes:
|
for tax in taxes:
|
||||||
eprint.text(printline(tax['tax']['name'],price(tax['amount']), width=40,ratio=0.6))
|
eprint.text(printline(tax['tax']['name'],price(tax['amount']), width=40,ratio=0.6))
|
||||||
|
|
||||||
logo = None
|
|
||||||
|
|
||||||
if receipt['company']['logo']:
|
|
||||||
img = receipt['company']['logo']
|
|
||||||
img = img[img.find(',')+1:]
|
|
||||||
f = io.BytesIO('img')
|
|
||||||
f.write(base64.decodestring(img))
|
|
||||||
f.seek(0)
|
|
||||||
logo_rgba = Image.open(f)
|
|
||||||
logo = Image.new('RGB', logo_rgba.size, (255,255,255))
|
|
||||||
logo.paste(logo_rgba, mask=logo_rgba.split()[3])
|
|
||||||
width = 300
|
|
||||||
wfac = width/float(logo_rgba.size[0])
|
|
||||||
height = int(logo_rgba.size[1]*wfac)
|
|
||||||
logo = logo.resize((width,height), Image.ANTIALIAS)
|
|
||||||
|
|
||||||
# Receipt Header
|
# Receipt Header
|
||||||
if logo:
|
if receipt['company']['logo']:
|
||||||
eprint._convert_image(logo)
|
eprint.print_base64_image(receipt['company']['logo'])
|
||||||
eprint.text('\n')
|
eprint.text('\n')
|
||||||
else:
|
else:
|
||||||
eprint.set(align='center',type='b',height=2,width=2)
|
eprint.set(align='center',type='b',height=2,width=2)
|
||||||
|
|
|
@ -13,6 +13,10 @@ except ImportError:
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import copy
|
import copy
|
||||||
|
import io
|
||||||
|
import base64
|
||||||
|
import math
|
||||||
|
import md5
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
|
@ -30,6 +34,7 @@ class Escpos:
|
||||||
""" ESC/POS Printer object """
|
""" ESC/POS Printer object """
|
||||||
device = None
|
device = None
|
||||||
encoding = None
|
encoding = None
|
||||||
|
img_cache = {}
|
||||||
|
|
||||||
|
|
||||||
def _check_image_size(self, size):
|
def _check_image_size(self, size):
|
||||||
|
@ -49,6 +54,7 @@ class Escpos:
|
||||||
i = 0
|
i = 0
|
||||||
cont = 0
|
cont = 0
|
||||||
buffer = ""
|
buffer = ""
|
||||||
|
|
||||||
|
|
||||||
self._raw(S_RASTER_N)
|
self._raw(S_RASTER_N)
|
||||||
buffer = "%02X%02X%02X%02X" % (((size[0]/size[1])/8), 0, size[1], 0)
|
buffer = "%02X%02X%02X%02X" % (((size[0]/size[1])/8), 0, size[1], 0)
|
||||||
|
@ -65,6 +71,36 @@ class Escpos:
|
||||||
buffer = ""
|
buffer = ""
|
||||||
cont = 0
|
cont = 0
|
||||||
|
|
||||||
|
def _raw_print_image(self, line, size, output=None ):
|
||||||
|
""" Print formatted image """
|
||||||
|
i = 0
|
||||||
|
cont = 0
|
||||||
|
buffer = ""
|
||||||
|
raw = ""
|
||||||
|
|
||||||
|
def __raw(string):
|
||||||
|
if output:
|
||||||
|
output(string)
|
||||||
|
else:
|
||||||
|
self._raw(string)
|
||||||
|
|
||||||
|
raw += S_RASTER_N
|
||||||
|
buffer = "%02X%02X%02X%02X" % (((size[0]/size[1])/8), 0, size[1], 0)
|
||||||
|
raw += buffer.decode('hex')
|
||||||
|
buffer = ""
|
||||||
|
|
||||||
|
while i < len(line):
|
||||||
|
hex_string = int(line[i:i+8],2)
|
||||||
|
buffer += "%02X" % hex_string
|
||||||
|
i += 8
|
||||||
|
cont += 1
|
||||||
|
if cont % 4 == 0:
|
||||||
|
raw += buffer.decode("hex")
|
||||||
|
buffer = ""
|
||||||
|
cont = 0
|
||||||
|
|
||||||
|
return raw
|
||||||
|
|
||||||
|
|
||||||
def _convert_image(self, im):
|
def _convert_image(self, im):
|
||||||
""" Parse image and prepare it to a printable format """
|
""" Parse image and prepare it to a printable format """
|
||||||
|
@ -111,16 +147,45 @@ class Escpos:
|
||||||
pix_line += im_right
|
pix_line += im_right
|
||||||
img_size[0] += im_border[1]
|
img_size[0] += im_border[1]
|
||||||
|
|
||||||
self._print_image(pix_line, img_size)
|
return (pix_line, img_size)
|
||||||
|
|
||||||
|
|
||||||
def image(self,path_img):
|
def image(self,path_img):
|
||||||
""" Open image file """
|
""" Open image file """
|
||||||
im_open = Image.open(path_img)
|
im_open = Image.open(path_img)
|
||||||
im = im_open.convert("RGB")
|
im = im_open.convert("RGB")
|
||||||
# Convert the RGB image in printable image
|
# Convert the RGB image in printable image
|
||||||
self._convert_image(im)
|
pix_line, img_size = self._convert_image(im)
|
||||||
|
self._print_image(pix_line, img_size)
|
||||||
|
|
||||||
|
def print_base64_image(self,img):
|
||||||
|
|
||||||
|
print 'print_b64_img'
|
||||||
|
|
||||||
|
id = md5.new(img).digest()
|
||||||
|
|
||||||
|
if id not in self.img_cache:
|
||||||
|
print 'not in cache'
|
||||||
|
|
||||||
|
img = img[img.find(',')+1:]
|
||||||
|
f = io.BytesIO('img')
|
||||||
|
f.write(base64.decodestring(img))
|
||||||
|
f.seek(0)
|
||||||
|
img_rgba = Image.open(f)
|
||||||
|
img = Image.new('RGB', img_rgba.size, (255,255,255))
|
||||||
|
img.paste(img_rgba, mask=img_rgba.split()[3])
|
||||||
|
|
||||||
|
print 'convert image'
|
||||||
|
|
||||||
|
pix_line, img_size = self._convert_image(img)
|
||||||
|
|
||||||
|
print 'print image'
|
||||||
|
|
||||||
|
buffer = self._raw_print_image(pix_line, img_size)
|
||||||
|
self.img_cache[id] = buffer
|
||||||
|
|
||||||
|
print 'raw image'
|
||||||
|
|
||||||
|
self._raw(self.img_cache[id])
|
||||||
|
|
||||||
def qr(self,text):
|
def qr(self,text):
|
||||||
""" Print QR Code for the provided string """
|
""" Print QR Code for the provided string """
|
||||||
|
|
|
@ -190,7 +190,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
||||||
if(!this.keptalive){
|
if(!this.keptalive){
|
||||||
this.keptalive = true;
|
this.keptalive = true;
|
||||||
function status(){
|
function status(){
|
||||||
self.connection.rpc('/hw_proxy/status_json',{},{timeout:500})
|
self.connection.rpc('/hw_proxy/status_json',{},{timeout:2500})
|
||||||
.then(function(driver_status){
|
.then(function(driver_status){
|
||||||
self.set_connection_status('connected',driver_status);
|
self.set_connection_status('connected',driver_status);
|
||||||
},function(){
|
},function(){
|
||||||
|
|
|
@ -263,12 +263,26 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
||||||
self.company_logo.crossOrigin = 'anonymous';
|
self.company_logo.crossOrigin = 'anonymous';
|
||||||
var logo_loaded = new $.Deferred();
|
var logo_loaded = new $.Deferred();
|
||||||
self.company_logo.onload = function(){
|
self.company_logo.onload = function(){
|
||||||
|
var img = self.company_logo;
|
||||||
|
var ratio = 1;
|
||||||
|
var targetwidth = 200;
|
||||||
|
var maxheight = 100;
|
||||||
|
if( img.width !== targetwidth ){
|
||||||
|
ratio = targetwidth / img.width;
|
||||||
|
}
|
||||||
|
if( img.height * ratio > maxheight ){
|
||||||
|
ratio = maxheight / img.height;
|
||||||
|
}
|
||||||
|
var width = Math.floor(img.width * ratio);
|
||||||
|
var height = Math.floor(img.height * ratio);
|
||||||
var c = document.createElement('canvas');
|
var c = document.createElement('canvas');
|
||||||
c.width = self.company_logo.width;
|
c.width = width;
|
||||||
c.height = self.company_logo.height;
|
c.height = height
|
||||||
var ctx = c.getContext('2d');
|
var ctx = c.getContext('2d');
|
||||||
ctx.drawImage(self.company_logo,0,0);
|
ctx.drawImage(self.company_logo,0,0, width, height);
|
||||||
|
|
||||||
self.company_logo_base64 = c.toDataURL();
|
self.company_logo_base64 = c.toDataURL();
|
||||||
|
window.logo64 = self.company_logo_base64;
|
||||||
logo_loaded.resolve();
|
logo_loaded.resolve();
|
||||||
};
|
};
|
||||||
self.company_logo.onerror = function(){
|
self.company_logo.onerror = function(){
|
||||||
|
|
Loading…
Reference in New Issue