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
).