Python Barcode Generation — Core Concepts

What barcode generation does

Barcode generation converts data (numbers, text) into standardized visual patterns that optical scanners can read. Python libraries handle symbology rules, check digit computation, and image rendering — you supply data, they produce print-ready images.

The main library is python-barcode (install with pip install python-barcode[images]). The [images] extra pulls in Pillow for PNG output; without it, only SVG is available.

Supported symbologies

python-barcode supports the most common 1D barcode formats:

SymbologyCharactersLengthCommon Use
EAN-13Digits13Retail products worldwide
EAN-8Digits8Small retail items
UPC-ADigits12US/Canada retail
ISBN-13Digits13Books
ISSNDigits8Periodicals
Code 128Full ASCIIVariableShipping, logistics
Code 39A-Z, 0-9, symbolsVariableIndustrial, military
PZNDigits7German pharmaceuticals
ITFDigits (even count)VariableDistribution

Basic generation

Generate a barcode in three lines:

import barcode
from barcode.writer import ImageWriter

ean = barcode.get('ean13', '5901234123457', writer=ImageWriter())
filename = ean.save('product_barcode')  # saves product_barcode.png

Without ImageWriter, the default output is SVG:

ean = barcode.get('ean13', '5901234123457')
filename = ean.save('product_barcode')  # saves product_barcode.svg

Check digits

Most barcode symbologies include a check digit — a calculated digit appended to the data to detect scanning errors. The library computes this automatically:

# Pass 12 digits; the 13th (check digit) is calculated
ean = barcode.get('ean13', '590123412345')
print(ean.get_fullcode())  # '5901234123457'

For EAN-13, the check digit uses a weighted sum modulo 10. If you pass all 13 digits, the library validates the check digit and raises an error if it is wrong.

Image customization

The ImageWriter accepts options for sizing and appearance:

writer = ImageWriter()
ean = barcode.get('ean13', '5901234123457', writer=writer)
ean.save('custom', options={
    'module_width': 0.2,      # mm per bar unit
    'module_height': 15.0,    # mm bar height
    'font_size': 10,          # text size in points
    'text_distance': 5.0,     # mm between bars and text
    'quiet_zone': 6.5,        # mm of white space on sides
    'dpi': 300,               # output resolution
})

For SVG output, similar options control the vector dimensions.

Code 128 for variable-length data

When you need to encode arbitrary text (not just digits), use Code 128:

code128 = barcode.get('code128', 'SHIP-2024-ABC-1234', writer=ImageWriter())
code128.save('shipping_label')

Code 128 automatically selects between its sub-encodings (A, B, C) to produce the shortest possible barcode. Sub-encoding C is particularly efficient for long numeric strings, packing two digits per symbol.

Batch generation

Generate barcodes from a data source:

import csv
import barcode
from barcode.writer import ImageWriter
from pathlib import Path

output_dir = Path('barcodes')
output_dir.mkdir(exist_ok=True)

with open('inventory.csv') as f:
    for row in csv.DictReader(f):
        code = barcode.get('ean13', row['ean'], writer=ImageWriter())
        code.save(str(output_dir / row['sku']))

Alternative: reportlab for label sheets

For printing barcode labels on standard label sheets (Avery, etc.), combine barcode generation with reportlab:

from reportlab.graphics.barcode import code128
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas

c = canvas.Canvas("labels.pdf", pagesize=letter)
barcode_obj = code128.Code128("ITEM-001", barWidth=0.02*72, barHeight=0.5*72)
barcode_obj.drawOn(c, 72, 700)  # position in points from bottom-left
c.save()

This approach generates print-ready PDFs with barcodes positioned precisely on the page.

Scanning and validation

Verify generated barcodes by scanning programmatically with pyzbar:

from pyzbar.pyzbar import decode
from PIL import Image

results = decode(Image.open('product_barcode.png'))
for r in results:
    print(r.type, r.data.decode())  # 'EAN13', '5901234123457'

Always validate generated barcodes before printing — especially in batch workflows where a single misconfiguration could produce thousands of unscannable labels.

The one thing to remember: Barcode generation in Python means choosing the right symbology for your data, letting the library handle check digits and bar widths, and always validating the output by scanning before printing at scale.

pythonbarcodegenerationretail

See Also

  • Python Arcade Library Think of a magical art table that draws your game characters, listens when you press buttons, and cleans up the mess — that's Python Arcade.
  • Python Audio Fingerprinting Ever wonder how Shazam identifies a song from just a few seconds of noisy audio? Audio fingerprinting is the magic behind it, and Python can do it too.
  • Python Cellular Automata Imagine a checkerboard where each square follows simple rules to turn on or off — and suddenly complex patterns emerge like magic.
  • Python Godot Gdscript Bridge Imagine speaking English to a friend who speaks French, with a translator in the middle — that's how Python talks to the Godot game engine.
  • Python Librosa Audio Analysis Picture a music detective that can look at any song and tell you exactly what notes, beats, and moods are hiding inside — that's what Librosa does for Python.