"""Utilities for label generation. stolen from: https://github.com/Edinburgh-Genome-Foundry/blabel """ import base64 from io import BytesIO import datetime import textwrap from math import floor import barcode as python_barcode from PIL import Image, ImageDraw, ImageFont def now(fmt="%Y-%m-%d %H:%M"): """Display the current time. Default format is "year-month-day hour:minute" but another format can be provided (see ``datetime`` docs for date formatting). """ now = datetime.datetime.now() if fmt is not None: now = now.strftime(fmt) return now def pil_to_html_imgdata(img, fmt='PNG'): """Convert a PIL image into HTML-displayable data. The result is a string ``data:image/FMT;base64,xxxxxxxxx`` which you can provide as a "src" parameter to a ```` tag. Examples: --------- >>> data = pil_to_html_imgdata(my_pil_img) >>> html_data = '' % data """ buffered = BytesIO() img.save(buffered, format=fmt) img_str = base64.b64encode(buffered.getvalue()) prefix = 'data:image/%s;charset=utf-8;base64,' % fmt.lower() return prefix + img_str.decode() def wrap(text, col_width): """Breaks the text into lines with at maximum 'col_width' characters.""" 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): """Return a barcode's image data. Powered by the Python library ``python-barcode``. See this library's documentation for more details. Parameters ---------- data Data to be encoded in the datamatrix. barcode_class Class/standard to use to encode the data. Different standards have different constraints. fmt The format to be used when rendering the resulting image png -> png image svg -> embeddable code for html img tag logo_file File path to logo file to be included writer_options Various options for the writer to tune the appearance of the barcode (see python-barcode documentation). Returns ------- image_base64_data A string ``data:image/png;base64,xxxxxxxxx`` which you can provide as a "src" parameter to a ```` tag. Examples: --------- >>> data = barcode('EGF12134', barcode_class='code128') >>> html_data = '' % data Examples of writer options: >>> { 'background': 'white', >>> 'font_size': 10, >>> 'foreground': 'black', >>> 'module_height': 15.0, >>> 'module_width': 0.2, >>> 'quiet_zone': 6.5, >>> 'text': '', >>> 'text_distance': 5.0, >>> 'write_text': True >>> } """ with Image.open(logo_file) as logo_img: font_size = 16 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) logo_img = logo_img.convert('1') constructor = python_barcode.get_barcode_class(barcode_class) data = str(data).zfill(constructor.digits) writer = { 'svg': python_barcode.writer.ImageWriter, 'png': python_barcode.writer.ImageWriter }[fmt] barcode_img = constructor(data, writer=writer()) img = barcode_img.render(writer_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))) 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) 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) if 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()