Label creation and print
This commit is contained in:
parent
734598a379
commit
8b48741816
|
@ -4,17 +4,33 @@
|
|||
{% block title %}Container: {{ container.named_id }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
===== Print Label Content =====
|
||||
|
||||
<h1>Print Container Label</h1>
|
||||
<!-- Action buttons -->
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-12">
|
||||
Label created for container {{ container.named_id }} of type {{ container.container_type.named_id }}
|
||||
Label created for container {{ container.named_id }} of type {{ container.container_type.named_id }}:
|
||||
<br />
|
||||
<img class="img-fluid shadow p-3 mb-5 bg-body rounded" src="{{ barcode_img }}">
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12">
|
||||
<form method="gest">
|
||||
{% csrf_token %}
|
||||
<label for="num_copies">Number of copies:</label><input type="number" id="num_copies" size="2" min="1" max="8" name="num_copies" value="1">
|
||||
<input type="submit" class="btn btn-primary" value="Print">
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<!--
|
||||
{% if logs %}
|
||||
{% for msg in logs %}
|
||||
{{ msg }}<br />
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
no messages
|
||||
{% endif %}
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Action buttons -->
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
from django.views import generic
|
||||
from .models import Container, ContainerType
|
||||
from labelprinter.labels import container_label
|
||||
import logging, json
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ContainerListView(generic.ListView):
|
||||
|
@ -62,22 +64,81 @@ class ContainerPrintLabelView(generic.DetailView):
|
|||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
from labelprinter.labels import container_label
|
||||
num_copies = int(self.request.GET['num_copies']) if 'num_copies' in self.request.GET else 0
|
||||
context['num_copies'] = num_copies
|
||||
context['logs'] = ['creating label for container ' + self.object.named_id]
|
||||
from labelprinter.labels import container_label, pil_to_html_imgdata
|
||||
container_description = self.object.container_type.named_id
|
||||
if len(self.object.container_type.description) > 0:
|
||||
container_description += ': ' + self.object.container_type.description
|
||||
if len(self.object.description) > 0:
|
||||
container_description += ' / ' + self.object.description
|
||||
context['barcode_img'] = container_label(self.object.named_id, description=container_description, writer_options={'background': 'white',
|
||||
'font_size': 10,
|
||||
'foreground': 'black',
|
||||
'module_height': 10.0,
|
||||
'module_width': 0.2,
|
||||
'quiet_zone': 2.5,
|
||||
'text': 'This is the text',
|
||||
'text_distance': 3.0,
|
||||
'write_text': True
|
||||
})
|
||||
container_description_line2 = self.object.description
|
||||
label_image = container_label(
|
||||
self.object.named_id,
|
||||
fmt='image',
|
||||
description=container_description,
|
||||
description_line2=container_description_line2,
|
||||
writer_options={'font_size': 14,
|
||||
'module_height': 10.0,
|
||||
'quiet_zone': 4.5,
|
||||
'text': 'This is the text',
|
||||
'text_distance': 1.0
|
||||
})
|
||||
context['barcode_img'] = pil_to_html_imgdata(label_image, fmt='PNG')
|
||||
context['logs'].append('Image created')
|
||||
if num_copies > 0:
|
||||
#from brother_ql.devicedependent import models, label_type_specs, label_sizes
|
||||
#from brother_ql.devicedependent import ENDLESS_LABEL, DIE_CUT_LABEL, ROUND_DIE_CUT_LABEL
|
||||
from brother_ql import BrotherQLRaster, create_label
|
||||
from brother_ql.backends import backend_factory, guess_backend
|
||||
|
||||
try:
|
||||
with open('config.json', encoding='utf-8') as fh:
|
||||
config = json.load(fh)
|
||||
except FileNotFoundError as e:
|
||||
with open('config.example.json', encoding='utf-8') as fh:
|
||||
config = json.load(fh)
|
||||
|
||||
# LABEL_SIZES = [(name, label_type_specs[name]['name']) for name in label_sizes]
|
||||
|
||||
'''
|
||||
if context['kind'] == ENDLESS_LABEL:
|
||||
rotate = 0 if context['orientation'] == 'standard' else 90
|
||||
elif context['kind'] in (ROUND_DIE_CUT_LABEL, DIE_CUT_LABEL):
|
||||
rotate = 'auto'
|
||||
red = False
|
||||
if 'red' in context['label_size']:
|
||||
red = True
|
||||
'''
|
||||
|
||||
qlr = BrotherQLRaster(config['PRINTER']['MODEL'])
|
||||
context['logs'].append('Connected to printer')
|
||||
create_label(qlr, image=label_image, label_size='62', red=False, threshold=1,
|
||||
cut=True, rotate='auto')
|
||||
context['logs'].append('Created raster information')
|
||||
|
||||
try:
|
||||
selected_backend = guess_backend(config['PRINTER']['PRINTER'])
|
||||
except ValueError:
|
||||
context['messages'].append(
|
||||
"Could't guess the backend to use from the printer string descriptor (config PRINTER.PRINTER)")
|
||||
context['logs'].append('Backend found: ' + selected_backend)
|
||||
try:
|
||||
be_class = backend_factory(selected_backend)['backend_class']
|
||||
be = be_class(config['PRINTER']['PRINTER'])
|
||||
context['logs'].append('Got backend driver')
|
||||
for i in range(1,num_copies):
|
||||
be.write(qlr.data)
|
||||
|
||||
context['logs'].append('Data sent to printer')
|
||||
be.dispose()
|
||||
del be
|
||||
except Exception as e:
|
||||
context['logs'].append('Exception: ' + str(e))
|
||||
logger.warning('Exception happened: %s', e)
|
||||
|
||||
context['logs'].append('Finished printing label')
|
||||
|
||||
return context
|
||||
|
||||
|
||||
|
|
|
@ -6,8 +6,11 @@ from io import BytesIO
|
|||
import datetime
|
||||
import textwrap
|
||||
from math import floor
|
||||
|
||||
import PIL.Image
|
||||
import barcode as python_barcode
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
import labelprinter
|
||||
|
||||
|
||||
def now(fmt="%Y-%m-%d %H:%M"):
|
||||
|
@ -43,7 +46,8 @@ def wrap(text, col_width):
|
|||
return "\n".join(textwrap.wrap(text, col_width))
|
||||
|
||||
|
||||
def container_label(data, barcode_class='code128', fmt='png', logo_file='./static/images/djlogo256.png',owner_name='Dirk Jahnke', description='', **writer_options):
|
||||
def container_label(data, barcode_class='code128', fmt='png', logo_file='./static/images/djlogo256.png',
|
||||
owner_name='Dirk Jahnke', description='', description_line2='', **options):
|
||||
"""Return a barcode's image data.
|
||||
Powered by the Python library ``python-barcode``. See this library's
|
||||
documentation for more details.
|
||||
|
@ -60,6 +64,10 @@ def container_label(data, barcode_class='code128', fmt='png', logo_file='./stati
|
|||
svg -> embeddable code for html img tag
|
||||
logo_file
|
||||
File path to logo file to be included
|
||||
owner_name
|
||||
Name of owner printed underneath the logo
|
||||
description
|
||||
Text to be printed on bottom of the label
|
||||
writer_options
|
||||
Various options for the writer to tune the appearance of the barcode
|
||||
(see python-barcode documentation).
|
||||
|
@ -86,8 +94,10 @@ def container_label(data, barcode_class='code128', fmt='png', logo_file='./stati
|
|||
"""
|
||||
|
||||
with Image.open(logo_file) as logo_img:
|
||||
font_size = 16
|
||||
logo_img = logo_img.resize((128,128))
|
||||
font_size = 22
|
||||
font_size_small = 16
|
||||
owner_name_font_size = 26
|
||||
logo_img = logo_img.resize((128, 128))
|
||||
logo_img = logo_img.convert('L')
|
||||
threshold = 20
|
||||
logo_img = logo_img.point(lambda p: 255 if p < threshold else 0)
|
||||
|
@ -96,26 +106,47 @@ def container_label(data, barcode_class='code128', fmt='png', logo_file='./stati
|
|||
data = str(data).zfill(constructor.digits)
|
||||
writer = {
|
||||
'svg': python_barcode.writer.ImageWriter,
|
||||
'png': python_barcode.writer.ImageWriter
|
||||
'png': python_barcode.writer.ImageWriter,
|
||||
'image': python_barcode.writer.ImageWriter
|
||||
}[fmt]
|
||||
barcode_img = constructor(data, writer=writer())
|
||||
img = barcode_img.render(writer_options=writer_options)
|
||||
img = barcode_img.render(writer_options=options['writer_options'])
|
||||
barcode_xsize, barcode_ysize = img.size
|
||||
logo_xsize, logo_ysize = logo_img.size
|
||||
result_img = Image.new('1', (696, barcode_ysize+20), 1)
|
||||
result_img.paste(logo_img, (0, floor(barcode_ysize/3)-floor(logo_ysize/2)))
|
||||
label_xsize = 696
|
||||
label_ysize = barcode_ysize + font_size if description_line2 == '' else barcode_ysize + 2 * font_size
|
||||
result_img = Image.new('1', (label_xsize, label_ysize), 1)
|
||||
result_img.paste(logo_img, (owner_name_font_size + 10, floor(barcode_ysize / 2) - 20 - floor(logo_ysize / 2)))
|
||||
start_x_for_barcode = logo_xsize + 10
|
||||
max_x_for_barcode = 696 - start_x_for_barcode
|
||||
result_img.paste(img, (start_x_for_barcode + floor((max_x_for_barcode-barcode_xsize)/2), 5))
|
||||
# fnt = ImageFont.truetype("Pillow/Tests/fonts/FreeMono.ttf", 40)
|
||||
result_img.paste(img, (start_x_for_barcode + floor((max_x_for_barcode - barcode_xsize) / 2), 5))
|
||||
fnt = ImageFont.truetype("./static/fonts/DejaVuSerif.ttf", font_size)
|
||||
|
||||
d = ImageDraw.Draw(result_img)
|
||||
d.text((20,logo_ysize+40), owner_name, font=fnt)
|
||||
d.text((30+floor((660-fnt.getlength(description))/2),barcode_ysize), description, font=fnt)
|
||||
owner_name_fnt = ImageFont.truetype("./static/fonts/DejaVuSerif.ttf", owner_name_font_size)
|
||||
owner_text_img = Image.new('1', (floor(owner_name_fnt.getlength(owner_name)+1), owner_name_font_size+5), 1)
|
||||
d = ImageDraw.Draw(owner_text_img)
|
||||
d.text((0,0), owner_name, font=owner_name_fnt)
|
||||
owner_text_img = owner_text_img.transpose(PIL.Image.ROTATE_90)
|
||||
result_img.paste(owner_text_img, (0, 10))
|
||||
|
||||
if fmt == 'png':
|
||||
d = ImageDraw.Draw(result_img)
|
||||
#d.text((20, logo_ysize), owner_name, font=fnt)
|
||||
if fnt.getlength(description) > 660:
|
||||
fnt_small = ImageFont.truetype("./static/fonts/DejaVuSerif.ttf", font_size_small)
|
||||
d.text((0, barcode_ysize), description, font=fnt_small)
|
||||
if description_line2 != '':
|
||||
d.text((0, barcode_ysize + font_size), description_line2, font=fnt_small)
|
||||
else:
|
||||
#d.text((30 + floor((660 - fnt.getlength(description)) / 2), barcode_ysize), description, font=fnt)
|
||||
d.text((0, barcode_ysize), description, font=fnt)
|
||||
if description_line2 != '':
|
||||
d.text((0, barcode_ysize + font_size), description_line2, font=fnt)
|
||||
|
||||
if fmt == 'image':
|
||||
return result_img
|
||||
elif fmt == 'png':
|
||||
return pil_to_html_imgdata(result_img, fmt='PNG')
|
||||
else:
|
||||
prefix = "data:image/svg+xml;charset=utf-8;base64,"
|
||||
return prefix + base64.b64encode(result_img).decode()
|
||||
|
||||
|
|
Loading…
Reference in New Issue