Skip to content

Instantly share code, notes, and snippets.

@hackolite
Last active June 12, 2025 10:04
Show Gist options
  • Save hackolite/64f5e4ac1d109bb0199ebc84d78d36b3 to your computer and use it in GitHub Desktop.
Save hackolite/64f5e4ac1d109bb0199ebc84d78d36b3 to your computer and use it in GitHub Desktop.
from PIL import Image, ImageDraw
import qrcode
def create_qr_with_black_center(data):
"""Crée un QR code avec centre noir (ou le plus proche), en image noir et blanc"""
# Paramètres
box_size = 10
border = 2
# QR brut
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=box_size,
border=border,
)
qr.add_data(data)
qr.make(fit=True)
modules = qr.modules
module_count = len(modules)
# Coordonnées du centre
center_module_x = module_count // 2
center_module_y = module_count // 2
# Si centre blanc, on prend le module noir le plus proche
if not modules[center_module_y][center_module_x]:
black_modules = [
(x, y, abs(x - center_module_x) + abs(y - center_module_y))
for y in range(module_count)
for x in range(module_count)
if modules[y][x]
]
black_modules.sort(key=lambda t: t[2])
center_module_x, center_module_y, _ = black_modules[0]
center_pixel_x = (center_module_x + border) * box_size
center_pixel_y = (center_module_y + border) * box_size
img_size = (module_count + 2 * border) * box_size
# Mode 'RGB' pour compatibilité maximale
img = Image.new('RGB', (img_size, img_size), 'white') # Fond blanc
draw = ImageDraw.Draw(img)
# Dessin des modules noirs
for row in range(module_count):
for col in range(module_count):
if modules[row][col]:
x0 = (col + border) * box_size
y0 = (row + border) * box_size
x1 = x0 + box_size
y1 = y0 + box_size
draw.rectangle([x0, y0, x1, y1], fill='black')
return img, box_size, (center_pixel_x, center_pixel_y)
def insert_qr_in_its_own_center(qr_img, box_size, center_pixel_x, center_pixel_y, scale_factor=5, output_path="qr_mise_en_abyme.png"):
"""
Agrandit le QR code, insère une version miniature dans son pixel central
"""
# Taille de l'image agrandie
new_size = (qr_img.width * scale_factor, qr_img.height * scale_factor)
enlarged_qr = qr_img.resize(new_size, Image.NEAREST)
# Nouveau box_size et coordonnées du centre
new_box_size = box_size * scale_factor
new_center_x = center_pixel_x * scale_factor
new_center_y = center_pixel_y * scale_factor
# Réduction du QR original à la taille d'un seul module
mini_qr = qr_img.resize((new_box_size, new_box_size), Image.LANCZOS)
# Insertion dans le centre de l'image agrandie
enlarged_qr.paste(mini_qr, (new_center_x, new_center_y))
# Sauvegarde en PNG optimisé (plus léger)
enlarged_qr.save(output_path, format='PNG', optimize=True)
print(f"✅ QR inséré dans son pixel central (agrandi ×{scale_factor}) : {output_path}")
return enlarged_qr, scale_factor, new_box_size, (new_center_x, new_center_y)
def main():
coordinates = "14.66778,-17.39722"
print("🎯 Génération QR Code Fractal")
print("=" * 40)
# 1. Création du QR de base
print("1️⃣ Création du QR de base...")
img, box_size, (px, py) = create_qr_with_black_center(coordinates)
img.save("qr_base.png", format='PNG', optimize=True)
print(f" ✅ QR de base sauvé (taille: {img.size})")
print(f" 📍 Centre: pixel ({px}, {py}), box_size: {box_size}")
# 2. Premier niveau d'imbrication
print("\n2️⃣ Premier niveau d'imbrication...")
result1, scale1, box1, (cx1, cy1) = insert_qr_in_its_own_center(
img, box_size, px, py, scale_factor=10, output_path="qr_level1.png"
)
print(f" 📊 Scale: {scale1}, Box size: {box1}, Center: ({cx1}, {cy1})")
# 3. Deuxième niveau d'imbrication
print("\n3️⃣ Deuxième niveau d'imbrication...")
result2, scale2, box2, (cx2, cy2) = insert_qr_in_its_own_center(
result1, box1, cx1, cy1, scale_factor=10, output_path="qr_level2.png"
)
print(f" 📊 Scale: {scale2}, Box size: {box2}, Center: ({cx2}, {cy2})")
# 4. Version ultra-légère en noir et blanc
print("\n4️⃣ Création version ultra-légère...")
# Convertir en noir et blanc pur pour réduire la taille
bw_img = result2.convert('1') # 1 bit par pixel
bw_img.save("qr_fractal_light.png", format='PNG', optimize=True)
print("\n🎉 Génération terminée!")
print("📁 Fichiers créés:")
print(" - qr_base.png (QR de base)")
print(" - qr_level1.png (Premier niveau)")
print(" - qr_level2.png (Deuxième niveau)")
print(" - qr_fractal_light.png (Version ultra-légère)")
# Afficher les tailles de fichiers
import os
files = ["qr_base.png", "qr_level1.png", "qr_level2.png", "qr_fractal_light.png"]
print("\n📊 Tailles des fichiers:")
for file in files:
if os.path.exists(file):
size = os.path.getsize(file)
print(f" {file}: {size} bytes ({size/1024:.1f} KB)")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment