8x32 PI : interface web, matrice verticale, compatibilité Raspbian 11

- Interface web (serveur_web.py, Flask, gabarits dans web/) : dépôt de GIF,
  PNG animés et séquences de PNG, aperçus animés, ordre de lecture,
  activer / désactiver, corbeille, « jouer maintenant » et « suivante ».
  Service systemd vitrine-web, activé par installer.sh.
- Lecteur : réagit aux demandes de la page web (post-it dans
  /run/vitrine-pixels), écrit l'animation en cours, éteint la matrice
  proprement sur SIGTERM.
- Matrice posée debout : réglage ROTATION (90 = image 8 × 32) dans
  matrice.py ; images couchées tournées automatiquement ; exemples,
  animations codées, aperçus et page web adaptés au format vertical.
- Compatibilité Raspbian 11 Bullseye : partition /boot, Pillow 8.1, Flask 1.1.
- Doc : nouveau guide INTERFACE_WEB.md ; README, GUIDE_KRITA, MODE_VITRINE,
  CODER_EN_PYTHON mis à jour (format 8 × 32, adresses Wi-Fi / câble du Pi).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
bach
2026-10-08 16:08:18 +02:00
co-authored by Claude Opus 5.5
parent 98fca33142
commit 2d4b0d5a5f
63 changed files with 1592 additions and 156 deletions
+15 -7
View File
@@ -39,7 +39,7 @@ from matrice import LARGEUR, HAUTEUR, TABLE_GAMMA, LUMINOSITE, courant_estime_ma
DOSSIER_APERCUS = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "apercus")
TAILLE_LED = 14 # taille d'un pixel dans l'aperçu, en points
MAX_PLANCHE = 48 # nombre maximum d'images sur la planche
MAX_PLANCHE = 24 # nombre maximum d'images sur la planche
def pixel_eteint_sur_matrice(r, v, b):
@@ -137,14 +137,22 @@ def verifier(chemin):
base = os.path.join(DOSSIER_APERCUS, os.path.splitext(nom)[0] + "_apercu")
images = [dessiner_leds(image) for image, _ in etapes]
# Planche : les images les unes sous les autres, numérotées.
# Planche : toutes les images, numérotées. Matrice couchée : les unes sous
# les autres ; matrice debout : côte à côte, comme une bande dessinée.
montrees = images[:MAX_PLANCHE]
l, h = images[0].size
planche = Image.new("RGB", (l + 50, len(montrees) * (h + 6)), (255, 255, 255))
crayon = ImageDraw.Draw(planche)
for i, im in enumerate(montrees):
planche.paste(im, (50, i * (h + 6)))
crayon.text((6, i * (h + 6) + h // 2 - 6), str(i + 1), fill=(0, 0, 0))
if h > l:
planche = Image.new("RGB", (len(montrees) * (l + 8), h + 24), (255, 255, 255))
crayon = ImageDraw.Draw(planche)
for i, im in enumerate(montrees):
planche.paste(im, (i * (l + 8), 24))
crayon.text((i * (l + 8) + l // 2 - 6, 6), str(i + 1), fill=(0, 0, 0))
else:
planche = Image.new("RGB", (l + 50, len(montrees) * (h + 6)), (255, 255, 255))
crayon = ImageDraw.Draw(planche)
for i, im in enumerate(montrees):
planche.paste(im, (50, i * (h + 6)))
crayon.text((6, i * (h + 6) + h // 2 - 6), str(i + 1), fill=(0, 0, 0))
planche.save(base + ".png")
print(f" Aperçu : {base}.png", end="")