From d4ad1dec17196c4964aa4e8c17edae3cf4f00fdd Mon Sep 17 00:00:00 2001 From: Jules Date: Sat, 11 Apr 2026 17:49:46 +0200 Subject: [PATCH] =?UTF-8?q?Fix=20d=C3=A9formation=20photos=20+=20miroir=20?= =?UTF-8?q?Canon=20EOS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - _pfit() : helper scale+crop centré pygame sans déformer - ImageOps.fit() partout : vignettes, galerie, composite (recadrage centré au lieu de resize qui écrase) - eosremoterelease 'Immediate' : déclenche l'obturateur Canon en restant en LV, évite la levée/baisse de miroir à chaque prise Co-Authored-By: Claude Sonnet 4.6 --- photobooth_pygame.py | 55 +++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/photobooth_pygame.py b/photobooth_pygame.py index 9b0ce0e..08d3b17 100644 --- a/photobooth_pygame.py +++ b/photobooth_pygame.py @@ -91,6 +91,18 @@ THEMES = { }, } +# ── Helpers image ──────────────────────────────────────────────────────────── +def _pfit(surf, w, h): + """Scale + crop centré d'une surface pygame pour remplir (w, h) sans déformer.""" + sw, sh = surf.get_size() + if sw == w and sh == h: + return surf + scale = max(w / sw, h / sh) + nw, nh = max(w, int(sw * scale)), max(h, int(sh * scale)) + scaled = pygame.transform.scale(surf, (nw, nh)) + x, y = (nw - w) // 2, (nh - h) // 2 + return scaled.subsurface((x, y, w, h)).copy() + # ── Utilitaire USB ─────────────────────────────────────────────────────────── def _usb_reset_done(): """Reset USB des DSLR via unbind/bind sysfs pour libérer tout claim obsolète.""" @@ -764,9 +776,19 @@ class PB: if self.cam is None: raise RuntimeError("camera None") if self.cap_demande: - # Capture tethered LV : trigger_capture + wait_for_event - # → le miroir reste levé (déjà en liveview) - self.cam.trigger_capture() + # Déclenchement sans mouvement miroir : + # eosremoterelease garde le LV actif sur Canon EOS + triggered = False + try: + cfg_c = self.cam.get_config() + rl = cfg_c.get_child_by_name('eosremoterelease') + rl.set_value('Immediate') + self.cam.set_config(cfg_c) + triggered = True + except Exception: + pass + if not triggered: + self.cam.trigger_capture() ch = None deadline = time.time() + 15 while time.time() < deadline: @@ -776,6 +798,13 @@ class PB: self.cam.file_get(ev_data.folder, ev_data.name, gp.GP_FILE_TYPE_NORMAL, cf) nom = f"photo_{datetime.now().strftime('%Y%m%d_%H%M%S_%f')}.jpg" ch = str(PHOTOS_DIR/nom); cf.save(ch); break + # Réinitialise le remote release + try: + cfg_c = self.cam.get_config() + rl = cfg_c.get_child_by_name('eosremoterelease') + rl.set_value('None') + self.cam.set_config(cfg_c) + except: pass self.cap_result=ch; self.cap_demande=False; self.cap_done.set() errs = 0 else: @@ -846,7 +875,7 @@ class PB: if ch: self.photos.append(ch); self.compteur+=1; self._sav_cpt() try: - img = ImageOps.exif_transpose(Image.open(ch).convert("RGB")).resize((strip_bw, thumb_h), Image.LANCZOS) + img = ImageOps.fit(ImageOps.exif_transpose(Image.open(ch).convert("RGB")), (strip_bw, thumb_h), Image.LANCZOS) self._prev_thumbs.append(pygame.image.fromstring(img.tobytes(), img.size, "RGB")) except: self._prev_thumbs.append(None) @@ -867,7 +896,7 @@ class PB: fw = (W - _PELL_GAP*(nb+1)) // nb for ch in self.photos[:nb]: try: - img=ImageOps.exif_transpose(Image.open(ch).convert("RGB")).resize((fw,_PELL_FH),Image.LANCZOS) + img=ImageOps.fit(ImageOps.exif_transpose(Image.open(ch).convert("RGB")),(fw,_PELL_FH),Image.LANCZOS) surfs.append(pygame.image.fromstring(img.tobytes(),img.size,"RGB")) except: surfs.append(None) elif self.format in ("bande3x2","bande4x2"): @@ -875,14 +904,14 @@ class PB: pw = W // nb; sh = (H - 150) // 2 for ch in self.photos[:nb]: try: - img=ImageOps.exif_transpose(Image.open(ch).convert("RGB")).resize((pw,sh),Image.LANCZOS) + img=ImageOps.fit(ImageOps.exif_transpose(Image.open(ch).convert("RGB")),(pw,sh),Image.LANCZOS) surfs.append(pygame.image.fromstring(img.tobytes(),img.size,"RGB")) except: surfs.append(None) else: # grille_4 gw,gh=W//2-15,H//2-75 for ch in self.photos[:4]: try: - img=Image.open(ch).convert("RGB").resize((gw,gh),Image.LANCZOS) + img=ImageOps.fit(Image.open(ch).convert("RGB"),(gw,gh),Image.LANCZOS) surfs.append(pygame.image.fromstring(img.tobytes(),img.size,"RGB")) except: surfs.append(None) self.gal_surfs=surfs; self.gal_ready=True @@ -907,7 +936,7 @@ class PB: top = 80 for i, ch in enumerate(photos[:nb]): try: - img = ImageOps.exif_transpose(Image.open(ch).convert("RGB")).resize((pw, sh), Image.LANCZOS) + img = ImageOps.fit(ImageOps.exif_transpose(Image.open(ch).convert("RGB")), (pw, sh), Image.LANCZOS) canvas.paste(img, (i * pw, top)) except Exception as e: print(f"composite pellicule: {e}") @@ -916,7 +945,7 @@ class PB: sh = (H - 150) // 2 for i, ch in enumerate(photos[:nb]): try: - img = ImageOps.exif_transpose(Image.open(ch).convert("RGB")).resize((pw, sh), Image.LANCZOS) + img = ImageOps.fit(ImageOps.exif_transpose(Image.open(ch).convert("RGB")), (pw, sh), Image.LANCZOS) canvas.paste(img, (i * pw, 5)) canvas.paste(img, (i * pw, sh + 10)) except Exception as e: @@ -927,7 +956,7 @@ class PB: pos = [(5, 5), (W // 2 + 5, 5), (5, H // 2 - 65), (W // 2 + 5, H // 2 - 65)] for i, ch in enumerate(photos[:4]): try: - img = Image.open(ch).convert("RGB").resize((gw, gh), Image.LANCZOS) + img = ImageOps.fit(Image.open(ch).convert("RGB"), (gw, gh), Image.LANCZOS) canvas.paste(img, pos[i]) except Exception as e: print(f"composite grille: {e}") @@ -1189,7 +1218,7 @@ class PB: # Photo prise th = self._prev_thumbs[i] if th: - ts = th if th.get_size() == (fw, fh) else pygame.transform.scale(th, (fw, fh)) + ts = _pfit(th, fw, fh) self.scr.blit(ts, (fx, fy)) # Léger grain/vignette pellicule vig = pygame.Surface((fw, fh), pygame.SRCALPHA) @@ -1259,7 +1288,7 @@ class PB: if i < len(self._prev_thumbs): th = self._prev_thumbs[i] if th: - ts = th if th.get_size() == (bw, bh) else pygame.transform.scale(th, (bw, bh)) + ts = _pfit(th, bw, bh) self.scr.blit(ts, (bx, by)) pygame.draw.rect(self.scr, T["prim"], (bx, by, bw, bh), 2) tick = self.F["xs"].render("✓", True, T["prim"]) @@ -1350,7 +1379,7 @@ class PB: fx=gap+i*(fw+gap); fy=frame_y surf=self.gal_surfs[i] if i