How to Generate QR Codes Using Python

QR Codes · Python · Tutorial

How to Generate QR Codes in Python Using qrcode

A concise, production-ready guide to creating QR codes with Python's free qrcode library. Includes install steps, examples, and notes about permanence and dynamic alternatives.

What is the qrcode library?

The qrcode library is a free, open-source Python module that converts text (including URLs) into QR code images (PNG, SVG, etc.). The QR image encodes the data you provide — the image itself does not "expire".

Install

Install qrcode with Pillow for image support:

pip install qrcode[pil] pillow

Quick example — generate a simple QR code

This example writes qrcode.png to the current directory. It encodes a URL, but you can encode any string (text, vCard data, Wi-Fi credentials, etc.).

import qrcode

# Data to encode (can be any string)
data = "https://www.linkedin.com/in/atul-kushwaha-9b0290381/"

# Generate the QR code image
qr = qrcode.make(data)

# Save as PNG
qr.save("qrcode.png")

After running that script, qrcode.png will contain the QR image. The image is permanent — it will always encode data exactly as you generated it.

Customize size, error correction, and color

For more control use the QRCode class:


import qrcode
from qrcode.constants import ERROR_CORRECT_H

# Create a QRCode object with custom settings
qr = qrcode.QRCode(
    version=2,    
# QR Code "version" (1 to 40). 
# Higher number = larger grid that holds more data.
# Here version=2 means 25x25 modules (small but more than version 1).

    error_correction=ERROR_CORRECT_H,   
# Error correction level:
# L = 7% data recovery
# M = 15% (default)
# Q = 25%
# H = 30% (best for damaged codes or adding logos).
# We’re using H = maximum protection.

    box_size=10,               
# Size of each QR code "box" in pixels.                           
# Larger value = higher resolution image.

    border=4,                
# Thickness of the white border (quiet zone) around the QR code.
# The standard requires at least 4 modules.

)

# Add the data you want to encode into the QR code
qr.add_data("https://www.linkedin.com/in/atul-kushwaha-9b0290381")

# Optimize the QR code to fit the data (overrides version if needed)
qr.make(fit=True)

# Generate the QR code image
img = qr.make_image(fill_color="black", back_color="white")

# Save the QR code as an image file
img.save("custom_qr.png")

QR code with a logo in the center

You can also place your brand logo inside the QR code. This works because we use ERROR_CORRECT_H (30% error correction), allowing scanners to read even with part of the code covered.


import qrcode
from qrcode.constants import ERROR_CORRECT_H
from PIL import Image

# Create QRCode with high error correction
qr = qrcode.QRCode(
    version=4,
    error_correction=ERROR_CORRECT_H,
    box_size=10,
    border=4,
)
qr.add_data("https://www.linkedin.com/in/atul-kushwaha-9b0290381/")
qr.make(fit=True)

# Generate QR code image
img = qr.make_image(fill_color="black", back_color="white").convert("RGB")

# Load logo image
logo = Image.open("logo.png")

# Resize logo to fit inside the QR (20-25% of QR size is ideal)
qr_width, qr_height = img.size
logo_size = qr_width // 4
logo = logo.resize((logo_size, logo_size))

# Calculate position (center)
pos = ((qr_width - logo_size) // 2, (qr_height - logo_size) // 2)

# Paste logo (with transparency if available)
if logo.mode in ("RGBA", "LA"):
    img.paste(logo, pos, mask=logo)
else:
    img.paste(logo, pos)

# Save QR code with logo
img.save("qr_with_logo.png")

Do QR codes expire?

Short answer: No — a QR code image encodes static data and does not expire.

  • If the QR contains plain text (e.g., "Hello") — it always returns that text.
  • If the QR contains a URL — the QR itself never expires, but the URL destination may change, return an error, or be removed.

Dynamic QR codes: If you want to keep the QR image the same while changing the destination later, use a dynamic QR service (redirect). These services typically host a short redirect URL encoded in the QR and let you update the target in their dashboard.

Best practices

  • Use ERROR_CORRECT_M or higher for printed materials to tolerate damage.
  • Keep a margin (quiet zone) of at least 4 modules (use border=4).
  • Test scans with multiple devices and apps before publishing.
  • If you need future flexibility, consider using your own short redirect endpoint (e.g., https://yourdomain.com/r/abc123).
Previous Post Next Post

Contact Form