QR code for VCard using Python

2 min read

|

Jul 25 2023

https://images.fmacedo.com/turnstile_htmx.png

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:[email protected]
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:[email protected]
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")

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:[email protected]
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:

Published: Jul 25 2023
Updated: Jul 25 2023