pipeline/axo : extraction du Rhino, recalage sur la planche (1:640), maisons, arbres (positions réelles des blocs, couleurs de la planche), scène en mètres, sols depuis le PDF Illustrator vectoriel (calques pilotés), bulles de la page 15, planche de l'eau nettoyée. prototypes/axo-test : la page de test et son assembleur. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
27 lines
1.5 KiB
Python
27 lines
1.5 KiB
Python
"""07 — Les bulles d'icônes de la planche « le quartier en 2030 » (TMIP 2024, p. 15).
|
|
|
|
La carte de cette page est une image de 1 190 px (72 dpi) ; les bulles, elles, sont vectorielles.
|
|
On retire l'image de la page (rédaction PDF, images seules), on rend à 300 dpi et on découpe
|
|
chaque bulle en rond sur fond blanc. Les centres sont relevés sur la page, alignée au pixel
|
|
près sur la planche du concours (décalage mesuré : 1 px).
|
|
|
|
Usage : python 07_bulles.py <presentation_TMIP_2024.pdf> (lit bulles_px.json, écrit bulles/*.png)
|
|
"""
|
|
import sys, os, json
|
|
import pymupdf
|
|
from PIL import Image, ImageDraw, ImageFilter
|
|
|
|
doc = pymupdf.open(sys.argv[1]); page = doc[14]
|
|
page.add_redact_annot(page.rect)
|
|
page.apply_redactions(images=pymupdf.PDF_REDACT_IMAGE_REMOVE, graphics=pymupdf.PDF_REDACT_LINE_ART_NONE, text=pymupdf.PDF_REDACT_TEXT_NONE)
|
|
page.get_pixmap(dpi=300).save("p15_sans_carte.png")
|
|
p = Image.open("p15_sans_carte.png").convert("RGBA")
|
|
os.makedirs("bulles", exist_ok=True)
|
|
for b in json.load(open("bulles_px.json")):
|
|
cx, cy, r = b["x"] * 3, b["y"] * 3, b["r"] * 3 + 6
|
|
c = p.crop((int(cx - r), int(cy - r), int(cx + r), int(cy + r)))
|
|
m = Image.new("L", c.size, 0); ImageDraw.Draw(m).ellipse([2, 2, c.size[0] - 3, c.size[1] - 3], fill=255)
|
|
fond = Image.new("RGBA", c.size, (255, 255, 255, 255)); fond.alpha_composite(c); fond.putalpha(m.filter(ImageFilter.GaussianBlur(1)))
|
|
fond.resize((112, 112), Image.LANCZOS).save("bulles/%s.png" % b["id"], optimize=True)
|
|
print(len(os.listdir("bulles")), "bulles")
|