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:
| Symbology | Characters | Length | Common Use |
|---|---|---|---|
| EAN-13 | Digits | 13 | Retail products worldwide |
| EAN-8 | Digits | 8 | Small retail items |
| UPC-A | Digits | 12 | US/Canada retail |
| ISBN-13 | Digits | 13 | Books |
| ISSN | Digits | 8 | Periodicals |
| Code 128 | Full ASCII | Variable | Shipping, logistics |
| Code 39 | A-Z, 0-9, symbols | Variable | Industrial, military |
| PZN | Digits | 7 | German pharmaceuticals |
| ITF | Digits (even count) | Variable | Distribution |
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.
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.