Fix déformation photos + miroir Canon EOS
- _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 <noreply@anthropic.com>
This commit is contained in:
@@ -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,8 +776,18 @@ 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)
|
||||
# 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
|
||||
@@ -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<len(self.gal_surfs) else None
|
||||
if surf:
|
||||
ts=pygame.transform.scale(surf,(fw,fh))
|
||||
ts=_pfit(surf,fw,fh)
|
||||
self.scr.blit(ts,(fx,fy))
|
||||
pygame.draw.rect(self.scr,T["prim"],(fx,fy,fw,fh),2)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user