NoiseQR

From Noisebridge
Jump to navigation Jump to search
Noiseqr example.png

This is a utility by User:Wolf for creating neat Noisebridge-branded QR codes.

Quick start: (note that you will need python-qrcode >= 7.3.1 to avoid formatting problems).

$ python3 -m venv venv3
$ source venv3/bin/activate
$ pip install wheel
$ pip install qrcode[pil]
  • Edit noiseqr.py with the URLs you want
  • Run noiseqr.py
$ python3 ./noiseqr.py

The output will be various some_file_0.png files which are intended to be printed at 8.5x11 (no scaling, no extra margins) and cut out. (Note that they may appear slightly fuzzy when zoomed in, this will not be noticeable when printed.)

The Source[edit]

import qrcode
import qrcode.image.svg
from qrcode.image.styledpil import StyledPilImage
from qrcode.image.styles.moduledrawers import GappedSquareModuleDrawer, RoundedModuleDrawer, CircleModuleDrawer

from PIL import Image, ImageFont, ImageDraw

DPI=600
INCH=DPI
POINT=int(1/72*INCH)

LABEL_SIZE=2*INCH
PAGE_MARGIN=int(1/4*INCH)

PAGE_WIDTH=int(8.5*INCH)
PAGE_HEIGHT=int(11*INCH)

PIL_MODE="1" # 1 BPP
WHITE=255
BLACK=0

LOGO=Image.open("Noisebridge-Logo_circuit-only_forqr.png")

def getqr(url):
	qr = qrcode.QRCode(box_size=30)
	qr.add_data(url)
	img = qr.make_image(
		image_factory=StyledPilImage,
		module_drawer=GappedSquareModuleDrawer() if ("Flaschen" not in url) else CircleModuleDrawer(),
		eye_drawer=RoundedModuleDrawer(),
		embeded_image=LOGO,
		embeded_image_resample=Image.NEAREST,
	)

	return img

pages = []
def positions():
	for y in range(5):
			for x in range(4):
				yield (PAGE_MARGIN+x*LABEL_SIZE, PAGE_MARGIN+y*LABEL_SIZE)
def pagepositions():
	while True:
		page = Image.new(mode=PIL_MODE, size=(PAGE_WIDTH, PAGE_HEIGHT), color=WHITE)
		pages.append(page)
		for pos in positions():
			yield (page, pos)

urls = [
	'https://noisebridge.net/wiki/Noisebridge',
	'https://noisebridge.net/wiki/Getting_In',
	'https://noisebridge.net/wiki/272',
	'https://noisebridge.net/wiki/Access_Control',
]

liberation_sans_8 = ImageFont.truetype("/usr/share/fonts/truetype/liberation2/LiberationSans-Regular.ttf", 8*POINT)

for url, (page, pos) in zip(urls, pagepositions()):
	qr = getqr(url).resize((LABEL_SIZE, LABEL_SIZE), Image.NEAREST)
	
	draw = ImageDraw.Draw(qr)
	draw.text(
		xy=(LABEL_SIZE/2, LABEL_SIZE-2*POINT),
		anchor="mb",
		text=url.replace('https://', ''),
		fill=BLACK,
		font=liberation_sans_8,
	)
	
	page.paste(qr, pos)

for i, page in enumerate(pages):
	draw = ImageDraw.Draw(page)
	for pos in positions():
		draw.rectangle((pos, (pos[0]+LABEL_SIZE, pos[1]+LABEL_SIZE)), outline=BLACK)

	page.save(f"some_file_{i}.png")