pythonbarcodecode128

How to include barcode value with actual barcode Python `code128` module


I just built a quick Python Azure Function that generates a barcode. The response is ONLY the rendered barcode in .png format. I also need the barcode VALUE to be displayed below it.

Example:

import logging
import azure.functions as func
import code128
import io
from PIL import Image


barcode_param = '1234'
barcode_bytes = io.BytesIO()

logging.info('##### Generating barcode... #####')
barcode = code128.image(barcode_param, height=100).save(barcode_bytes, "PNG")
barcode_bytes.seek(0)
logging.info('##### Barcode successfully generated #####')
return func.HttpResponse(
    barcode_bytes.getvalue(),
    status_code=200,
    mimetype='image/png'
    )
    barcode_bytes.close()

Generates: enter image description here

Need: enter image description here theseahawksarewinning

How can I add the barcode value to the barcode with the code128 library?

There are no options shown in the docs.

EDIT 1: After @Furas great example, I now have:

enter image description here

Code to produce:

import code128
import io
from PIL import Image, ImageDraw, ImageFont

# Get barcode value
barcode_param = 'SUFFERINSUCCOTASH'

# Create barcode image
barcode_image = code128.image(barcode_param, height=100)

# Create empty image for barcode + text
top_bott_margin = 70
l_r_margin = 10
new_height = barcode_image.height + (2 * top_bott_margin)
new_width = barcode_image.width + (2 * l_r_margin)
new_image = Image.new( 'RGB', (new_width, new_height), (255, 255, 255))

# put barcode on new image
barcode_y = 100
new_image.paste(barcode_image, (0, barcode_y))

# object to draw text
draw = ImageDraw.Draw(new_image)

# Define custom text size and font
h1_size = 28
h2_size = 28
h3_size = 16
footer_size = 21

h1_font = ImageFont.truetype("DejaVuSans-Bold.ttf", h1_size)
h2_font = ImageFont.truetype("Ubuntu-Th.ttf", h2_size)
h3_font = ImageFont.truetype("Ubuntu-Th.ttf", h3_size)
footer_font = ImageFont.truetype("UbuntuMono-R.ttf", footer_size)

# Define custom text
company_name = 'YAY! CORP.'
id1 = '11-22-33-44'
license_num = 'WHY SOYNTENLY!'
product_type = 'GRADE A GREATNESS'
center_product_type = (barcode_image.width / 2) - len(product_type) * 5
center_barcode_value = (barcode_image.width / 2) - len(barcode_param) * 8

# Draw text on picture
draw.text( (l_r_margin, 0), company_name, fill=(0, 0, 0), font=h1_font)
draw.text( (l_r_margin, h1_size), id1, fill=(0, 0, 0), font=h2_font)
draw.text( (l_r_margin + 2, (h1_size + h2_size + 5)), license_num, fill=(0, 0, 0), font=h3_font)
draw.text( (center_product_type, (h1_size + h2_size + h3_size)), product_type, fill=(0, 0, 0), font=footer_font)
draw.text( (center_barcode_value, (new_height - footer_size - 15)), barcode_param, fill=(0, 0, 0), font=h2_font)

# save in file 
new_image.save('barcode_image.png', 'PNG')

# show in default viewer
import webbrowser
webbrowser.open('barcode_image.png')

Thanks mate!


Solution

  • You get code as Pillow image so you can use Pillow to add margin for text and to draw this text.

    You can get original size

    w, h = barcode_image.size
    

    calculate new size

    new_w = w  # the same 
    
    margin = 20
    new_h = h + (2*margin) 
    

    create empty image with white background

    new_image = Image.new('RGB', (new_w, new_h), (255, 255, 255))
    

    put original barcode in the middle of height

    new_image.paste(barcode_image, (0, margin))
    

    Next you can use ImageDraw to create object which can draw objects or put text on image

    draw = ImageDraw.Draw(new_image)
    

    and you can put some text using text(). You may need to use ImageFont to load font and set size. I use default font and size.

    #fnt = ImageFont.truetype("arial.ttf", 40)
    draw.text( (10, new_h - 10), barcode_text, fill=(0, 0, 0))#, font=fnt) 
    

    and you have image with text in new_image. And you can save it in file and check directly in web browser or you can convert to bytes and send to client.

    In example I use standard module webbrowser only to check image.

    enter image description here


    EDIT

    As @RufusVS noted in comment I could use image_new.show() instead of webbrowser


    import code128
    import io
    from PIL import Image, ImageDraw, ImageFont
    
    barcode_param = '1234'
    barcode_text = 'theseahawksarewinning'
    
    # original image
    barcode_image = code128.image(barcode_param, height=100)
    
    # empty image for code and text - it needs margins for text
    w, h = barcode_image.size
    margin = 20
    new_h = h +(2*margin) 
    
    new_image = Image.new( 'RGB', (w, new_h), (255, 255, 255))
    
    # put barcode on new image
    new_image.paste(barcode_image, (0, margin))
    
    # object to draw text
    draw = ImageDraw.Draw(new_image)
    
    # draw text
    #fnt = ImageFont.truetype("arial.ttf", 40)
    draw.text( (10, new_h - 10), barcode_text, fill=(0, 0, 0))#, font=fnt)  # 
    
    # save in file 
    new_image.save('barcode_image.png', 'PNG')
    
    # show in default viewer
    import webbrowser
    webbrowser.open('barcode_image.png')
    
    # --- later send it---
    
    barcode_bytes = io.BytesIO()
    new_image.save(barcode_bytes, "PNG")
    barcode_bytes.seek(0)
    data = barcode_bytes.getvalue()
    

    Doc: Image Image.new(), ImageDraw, ImageDraw.text() ImageFont