Rick Roll

I am in a position where I frequently see student presentations and have found that they frequently use online solutions when creating QR codes. Many of those “free” solutions add additional data inside the provided QR code or route traffic in a undesired manner. Using qrcode allows you to control exactly what is getting created.

In this post, I will walk through how to use the qrcode package in Python to generate QR codes, customize them, and save them as images.

Getting Started

Before writing any code, you need to install the required package. The qrcode library is lightweight and easy to install using pip:

$ pip install qrcode

As an alternative install, you may need to use to ensure the Pillow library is installed, which is used for image processing.

$ pip install qrcode[pil]

Once installed, you are ready to start generating QR codes.

Creating a Basic QR Code

At its simplest, generating a QR code requires only a few lines of code. The example below creates a QR code that points to a website.

import qrcode

img = qrcode.make("https://www.agilephd.com")
img.save("qrcode.png")

This code imports the library, generates a QR code from a string, in this case a URL, and saves it as an image file. If you open the saved file, you will see a fully functional QR code that can be scanned by any smartphone.

Customizing the QR Code

While the default QR code works fine, you will often want more control over its appearance and behavior. The qrcode package allows you to customize things like size, error correction, and colors.

Here is an example with more configuration:

import qrcode

qr = qrcode.QRCode(
    version=1,
    error_correction=qrcode.constants.ERROR_CORRECT_H,
    box_size=10,
    border=4,
)

qr.add_data("https://www.agilephd.com")
qr.make(fit=True)

img = qr.make_image(fill_color="black", back_color="white")
img.save("custom_qrcode.png")

In this example, several important parameters are introduced. The version controls the size of the QR code, while error_correction determines how much of the code can be damaged while still remaining readable. The box_size affects how large each square is, and the border sets the thickness of the white space around the code.

Adding Color and Styling

You are not limited to black and white QR codes. You can easily adjust the colors to better match your branding or design preferences.

img = qr.make_image(fill_color="purple", back_color="yellow")
img.save("styled_qrcode.png")

Be careful when choosing colors. High contrast between the foreground and background is essential for scanners to read the code reliably.

Embedding QR Code Generation in Applications

The real power of this approach comes when you integrate QR code generation into larger systems. For example, you could generate unique QR codes for event tickets, student IDs, or product tracking. Since the input is simply a string, you can encode URLs, text, JSON data, or identifiers tied to a database.

A simple example using dynamic data might look like this:

user_id = 12345
url = f"https://www.agilephd.com/user/{user_id}"

img = qrcode.make(url)
img.save(f"user_{user_id}_qrcode.png")

This pattern is especially useful in web applications where each user or transaction needs a unique, scannable reference.

Final Thoughts

The qrcode package is a great example of Python’s strength: simple tools that solve real problems with minimal code. In just a few lines, you can generate production ready QR codes and integrate them into larger workflows.