QR code for VCard using Python

A friend asked me if I knew of any free alternatives to create a QR code to share his business contact details. He said that all online solutions claimed to be free but eventually charged some hidden charges.

Instead of doing some research and eventually realize that a free version for what he wanted exists already I suggested he installed python and tried to create one himself.

Weirdly enough, he said yes.

What is a VCard

According to wikipedia, a VCard is a file format standard for electronic business cards. It has a set of properties that one should follow and since, in the end, it's all just a bunch of text, we can easily embed it into a QR code. Here's an example:

BEGIN:VCARD
VERSION:3.0
FN;CHARSET=UTF-8:John Smith
N;CHARSET=UTF-8:smith;john;;mr;
EMAIL;CHARSET=UTF-8;type=HOME,INTERNET:home@textilecompany.com
TEL;TYPE=HOME,VOICE:912990092
ROLE;CHARSET=UTF-8:ceo
ORG;CHARSET=UTF-8:Textile Company
REV:2023-07-05T15:03:18.704Z
END:VCARD

Simple solution: just another QR code

Now, we just need to create a qr code with that VCard content. Using the first qrcode python library that showed up on google:

import os
import qrcode


VCARD = """
BEGIN:VCARD
VERSION:3.0
FN;CHARSET=UTF-8:John Smith
N;CHARSET=UTF-8:smith;john;;mr;
EMAIL;CHARSET=UTF-8;type=HOME,INTERNET:home@textilecompany.com
TEL;TYPE=HOME,VOICE:912990092
ROLE;CHARSET=UTF-8:ceo
ORG;CHARSET=UTF-8:Textile Company
REV:2023-07-05T15:03:18.704Z
END:VCARD
"""

def create_qr_code(content: str, output_path: str):
    # create qrcode
    img = qrcode.make(content)

    # save image
    img.save(output_path)


if __name__ == "__main__":
    create_qr_code(VCARD, "qrcode.png")

The real deal: a QR code with a fancy logo

This is great, but my friend also wanted to include his company logo in the middle of the QR code. Of course! We just need the Pillow library and we are good to go:

import os
import qrcode
from PIL import Image


VCARD = """
BEGIN:VCARD
VERSION:3.0
FN;CHARSET=UTF-8:John Smith
N;CHARSET=UTF-8:smith;john;;mr;
EMAIL;CHARSET=UTF-8;type=HOME,INTERNET:home@textilecompany.com
TEL;TYPE=HOME,VOICE:+4472928372
ROLE;CHARSET=UTF-8:ceo
ORG;CHARSET=UTF-8:Textile Company
REV:2023-07-05T15:03:18.704Z
END:VCARD
"""

def create_qr_code(content: str, logo_path: str, output_path: str):
    # create qrcode image
    qr = qrcode.QRCode(
    version=1,
    error_correction=qrcode.ERROR_CORRECT_H,
    box_size=10,
    border=4,
    )
    qr.add_data(content)
    qr.make(fit=True)

    img = qr.make_image(fill_color="black", back_color="white").convert("RGBA")

    # resize logo
    logo = Image.open(logo_path).convert("RGBA")
    logo_width, logo_height = logo.size
    img_width, img_height = img.size
    scale_factor = min(img_width // 3, img_height // 3, logo_width, logo_height)
    logo.thumbnail((scale_factor, scale_factor))
    logo_pos = ((img_width - logo.width) // 2, (img_height - logo.height) // 2)

    logo_no_alpha = Image.new("RGB", logo.size, (255, 255, 255))
    logo_no_alpha.paste(logo, mask=logo.split()[3])

    # position logo
    img.paste(logo_no_alpha, logo_pos, mask=logo.split()[3])

    # save image
    img.save(output_path)


if __name__ == "__main__":
    create_qr_code(VCARD, "logo.png", "qrcode_with_logo.png")

Simple. Of course we could make this work interactively, but since this was his first time working with Python, I thought this was enough for a beginner. Here's an example output with a generic random logo:


Click here to share this article with your friends on X if you liked it.