#!/usr/bin/env python3 from util import fprint from PIL import Image from PIL import ImageDraw from PIL import ImageFont #import cv2 import numpy as np from util import find_data_file import segno import io #import cairosvg #import math # Copied from http://en.wikipedia.org/wiki/Code_128 # Value Weights 128A 128B 128C CODE128_CHART = """ 0 212222 space space 00 1 222122 ! ! 01 2 222221 " " 02 3 121223 # # 03 4 121322 $ $ 04 5 131222 % % 05 6 122213 & & 06 7 122312 ' ' 07 8 132212 ( ( 08 9 221213 ) ) 09 10 221312 * * 10 11 231212 + + 11 12 112232 , , 12 13 122132 - - 13 14 122231 . . 14 15 113222 / / 15 16 123122 0 0 16 17 123221 1 1 17 18 223211 2 2 18 19 221132 3 3 19 20 221231 4 4 20 21 213212 5 5 21 22 223112 6 6 22 23 312131 7 7 23 24 311222 8 8 24 25 321122 9 9 25 26 321221 : : 26 27 312212 ; ; 27 28 322112 < < 28 29 322211 = = 29 30 212123 > > 30 31 212321 ? ? 31 32 232121 @ @ 32 33 111323 A A 33 34 131123 B B 34 35 131321 C C 35 36 112313 D D 36 37 132113 E E 37 38 132311 F F 38 39 211313 G G 39 40 231113 H H 40 41 231311 I I 41 42 112133 J J 42 43 112331 K K 43 44 132131 L L 44 45 113123 M M 45 46 113321 N N 46 47 133121 O O 47 48 313121 P P 48 49 211331 Q Q 49 50 231131 R R 50 51 213113 S S 51 52 213311 T T 52 53 213131 U U 53 54 311123 V V 54 55 311321 W W 55 56 331121 X X 56 57 312113 Y Y 57 58 312311 Z Z 58 59 332111 [ [ 59 60 314111 \ \ 60 61 221411 ] ] 61 62 431111 ^ ^ 62 63 111224 _ _ 63 64 111422 NUL ` 64 65 121124 SOH a 65 66 121421 STX b 66 67 141122 ETX c 67 68 141221 EOT d 68 69 112214 ENQ e 69 70 112412 ACK f 70 71 122114 BEL g 71 72 122411 BS h 72 73 142112 HT i 73 74 142211 LF j 74 75 241211 VT k 75 76 221114 FF l 76 77 413111 CR m 77 78 241112 SO n 78 79 134111 SI o 79 80 111242 DLE p 80 81 121142 DC1 q 81 82 121241 DC2 r 82 83 114212 DC3 s 83 84 124112 DC4 t 84 85 124211 NAK u 85 86 411212 SYN v 86 87 421112 ETB w 87 88 421211 CAN x 88 89 212141 EM y 89 90 214121 SUB z 90 91 412121 ESC { 91 92 111143 FS | 92 93 111341 GS } 93 94 131141 RS ~ 94 95 114113 US DEL 95 96 114311 FNC3 FNC3 96 97 411113 FNC2 FNC2 97 98 411311 ShiftB ShiftA 98 99 113141 CodeC CodeC 99 100 114131 CodeB FNC4 CodeB 101 311141 FNC4 CodeA CodeA 102 411131 FNC1 FNC1 FNC1 103 211412 StartA StartA StartA 104 211214 StartB StartB StartB 105 211232 StartC StartC StartC 106 2331112 Stop Stop Stop """.split() VALUES = [int(value) for value in CODE128_CHART[0::5]] WEIGHTS = dict(zip(VALUES, CODE128_CHART[1::5])) CODE128A = dict(zip(CODE128_CHART[2::5], VALUES)) CODE128B = dict(zip(CODE128_CHART[3::5], VALUES)) CODE128C = dict(zip(CODE128_CHART[4::5], VALUES)) for charset in (CODE128A, CODE128B): charset[' '] = charset.pop('space') def generate_code(data, show=False, check=False): #img = code128_image(data) img = qr_image(data) if show: img.show() #img.show() #print(data) if(check): from pyzbar.pyzbar import decode from pyzbar.pyzbar import ZBarSymbol print(decode(img, symbols=[ZBarSymbol.CODE128])[0].data.decode('ascii')) #if(decode(img, symbols=[ZBarSymbol.CODE128])[0].data.decode('ascii') == data): # return True #else: # return False return img def code128_format(data): """ Generate an optimal barcode from ASCII text """ text = str(data) pos = 0 length = len(text) # Start Code if text[:2].isdigit(): charset = CODE128C codes = [charset['StartC']] else: charset = CODE128B codes = [charset['StartB']] # Data while pos < length: if charset is CODE128C: if text[pos:pos+2].isdigit() and length - pos > 1: # Encode Code C two characters at a time codes.append(int(text[pos:pos+2])) pos += 2 else: # Switch to Code B codes.append(charset['CodeB']) charset = CODE128B elif text[pos:pos+4].isdigit() and length - pos >= 4: # Switch to Code C codes.append(charset['CodeC']) charset = CODE128C else: # Encode Code B one character at a time codes.append(charset[text[pos]]) pos += 1 # Checksum checksum = 0 for weight, code in enumerate(codes): checksum += max(weight, 1) * code codes.append(checksum % 103) # Stop Code codes.append(charset['Stop']) return codes def code128_image(data, height=100, thickness=3, quiet_zone=False): partnum = data if not data[-1] == CODE128B['Stop']: data = code128_format(data) barcode_widths = [] for code in data: for weight in WEIGHTS[code]: barcode_widths.append(int(weight) * thickness) width = sum(barcode_widths) x = 0 if quiet_zone: width += 20 * thickness x = 10 * thickness # Monochrome Image img = Image.new('RGB', (int(width * 10), int(width * 10)), 'white') draw = ImageDraw.Draw(img) draw_bar = True for bwidth in barcode_widths: bwidth *= 4 if draw_bar: draw.rectangle(((x + int(width * 3), width*6.25), (x + int(width * 3) + bwidth - 1, width*7)), fill='black') draw_bar = not draw_bar x += bwidth #draw.arc(((width - width/5, width - width/5), (width*9 + width/5, width*9 + width/5)),0,360,fill='blue', width = int(width/8)) draw.arc(((width+int(width / 1.4), width+int(width / 1.4)), (width*9-int(width / 1.4), width*9-int(width / 1.4))),0,360,fill='blue', width = int(width/8)) font_path = find_data_file("OCRAEXT.TTF") font_size = width/2 font = ImageFont.truetype(font_path, font_size) text_width = font.getlength(partnum) while text_width > width*4: font_size -= 1 font = ImageFont.truetype(font_path, font_size) text_width = font.getlength(partnum) txtx = (int(width * 10) - text_width) / 2 txty = (int(width * 10)) / 2 + width / 2 draw.text((txtx,txty),partnum, "black", font) return img def qr_image(data, width=600): partnum = data # Monochrome Image img = Image.new('RGB', (int(width * 10), int(width * 10)), 'white') draw = ImageDraw.Draw(img) #svg_path = find_data_file("belden-logo.svg") #with open(svg_path, 'rb') as svg_file: # png_image = cairosvg.svg2png(file_obj=svg_file,dpi=width*30, scale=30, background_color="white") #with open("output.png", 'wb') as file: # file.write(png_image) png_image_io = "belden-logo-superhires.png" png_image_pillow = Image.open(png_image_io) png_width, png_height = png_image_pillow.size png_image_pillow = png_image_pillow.resize((int(width*5.2), int(width*5.2/png_width*png_height))) png_width, png_height = png_image_pillow.size # paste belden logo first because it has a big border that would cover stuff up img.paste(png_image_pillow, (int(width*5-png_width/2), int(width*4.25 - png_height/2))) # draw circle border #draw.arc(((width - width/5, width - width/5), (width*9 + width/5, width*9 + width/5)),0,360,fill='blue', width = int(width/8)) draw.arc(((width+int(width / 1.4), width+int(width / 1.4)), (width*9-int(width / 1.4), width*9-int(width / 1.4))),0,360,fill=(0, 73,144), width = int(width/8)) font_path = find_data_file("GothamCond-Medium.otf") font_size = width/2 font = ImageFont.truetype(font_path, font_size) text_width = font.getlength(partnum[2:]) # shrink font dynamically if it's too long of a name while text_width > width*4: font_size -= 1 font = ImageFont.truetype(font_path, font_size) text_width = font.getlength(partnum[2:]) txtx = (int(width * 10) - text_width) / 2 txty = (int(width * 10)) / 2 # draw part number text draw.text((txtx,txty),partnum[2:], "black", font) # Draw QR code partnum = partnum.replace(" ", "%20") qrcode = segno.make('BLDN.APP/' + partnum,micro=False,boost_error=False,error="L",mask=3) out = io.BytesIO() qrx, _ = qrcode.symbol_size(1,0) qrcode.save(out, scale=width*2/qrx, kind="PNG", border=0) qrimg = Image.open(out) img.paste(qrimg, box=(int(width*4),int(width*5.75))) return img if __name__ == "__main__": #print(generate_code("BL10GXS13")) #print(generate_code("BL10GXgd35j35S13")) #print(generate_code("BL10GX54hS13")) #print(generate_code("BL10Gj34qXS13", False, False)) #print(generate_code("BL104w5545dp7bfwp43643534/4563G-XS13")) #adjust_image(cv2.imread('test_skew.jpg')) path = "labels" img = generate_code("BL10GXS13") import os os.makedirs(path, exist_ok=True) img.save(path + "/" + "BL10GXS13" + ".png")