Skip to main content

Generating Barcodes in Python: A Step-by-Step Guide

· 5 min read
Serhii Hrekov
software engineer, creator, artist, programmer, projects founder

Generating barcodes is a surprisingly simple task in Python thanks to a few highly specialized libraries. Whether you're building an inventory system, a ticketing app, or a simple tracking tool, Python can generate industry-standard barcodes in just a few lines of code.

The most popular and robust library for this task is python-barcode.

1. The Core Toolkit: python-barcode

The python-barcode library is the standard choice because it is lightweight and supports a wide range of barcode formats, including EAN-13 (standard retail), Code 128 (alphanumeric), and UPC.

Installation

To generate barcodes as images (like PNG or JPEG) rather than just SVG vectors, you will also need the Pillow library.

pip install python-barcode Pillow


2. Choosing the Right Barcode Type

Before writing code, you need to know which barcode "symbology" your project requires.

Barcode TypeDescriptionBest Use Case
EAN-1312 digits + 1 check digit.International retail products.
Code 128Supports numbers, letters, and symbols.Shipping, logistics, and internal tracking.
UPC-A12 digits.Standard retail in North America.
ISBN-13Specifically for books.Publishing and libraries.

3. Basic Implementation: Generating a Code 128 Barcode

Code 128 is the most versatile format because it can encode any ASCII character. Here is how to generate one and save it as an SVG (the default format).

import barcode
from barcode.writer import ImageWriter

# 1. Define the barcode content
data = "PY-LOGISTICS-98765"

# 2. Select the barcode type (Code 128)
code128 = barcode.get_barcode_class('code128')

# 3. Create the barcode object
my_barcode = code128(data)

# 4. Save as SVG (Default)
filename = my_barcode.save("my_code128_barcode")
print(f"Barcode saved as: {filename}.svg")


4. Generating High-Resolution Image Files (PNG/JPEG)

While SVGs are great for web use because they are infinitely scalable, most printing systems prefer PNG or JPEG. To do this, you must pass the ImageWriter() class when initializing the barcode.

import barcode
from barcode.writer import ImageWriter

def generate_png_barcode(data, name):
# Select barcode type
CODE = barcode.get_barcode_class('code128')

# Initialize with ImageWriter to output PNG
my_barcode = CODE(data, writer=ImageWriter())

# Customize options (optional)
options = {
'module_width': 0.2, # Width of the thinnest bar (mm)
'module_height': 15.0, # Height of the bars (mm)
'font_size': 10, # Size of the text under the bars
'text_distance': 5.0, # Space between bars and text
'quiet_zone': 6.5, # Padding on sides
}

# Save the file (no extension needed in filename)
filename = my_barcode.save(name, options=options)
print(f"PNG Barcode saved: {filename}")

generate_png_barcode("ASSET-ID-001", "asset_tag")


5. Advanced: Generating "Retail Ready" EAN-13 Barcodes

EAN-13 is stricter than Code 128. It must be exactly 12 digits long. The 13th digit (the checksum) is automatically calculated by the library.

from barcode import EAN13
from barcode.writer import ImageWriter

def generate_ean13(number_string):
# EAN-13 requires a 12-digit string
if len(number_string) != 12 or not number_string.isdigit():
print("Error: EAN-13 requires exactly 12 digits.")
return

with open("retail_product.png", "wb") as f:
EAN13(number_string, writer=ImageWriter()).write(f)
print("EAN-13 Barcode generated successfully.")

generate_ean13("123456789012")


Summary and Best Practices

  • Format: Use SVG for digital displays and PNG (with high DPI) for physical printing.
  • Verification: Always test your generated barcode with a physical scanner or a smartphone app before mass-printing.
  • Quiet Zones: Never decrease the quiet_zone (the white space on the sides) too much, or scanners won't be able to find the start/end of the code.

Expert Tip: If you need to generate 2D codes (QR Codes), python-barcode is not the right tool. You should use the qrcode or segno libraries instead, as they handle the matrix-style encoding required for 2D symbols.