Fix caméra : gvfsd-gphoto2, race condition viewfinder, exif_transpose
- kiosk-session.sh : tue gvfsd-gphoto2 au démarrage (démon GNOME qui monopolisait le DSLR sur USB et bloquait gphoto2) - camera.py : viewfinder activé AVANT mode="gphoto2" → le thread preview ne peut plus appeler capture_preview() avant que LiveView soit prêt - _activer_viewfinder_init() sans lock pour l'init (thread pas encore actif) - exif_transpose sur les captures DSLR → corrige l'orientation et les bandes blanches dues aux photos mal orientées Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -82,10 +82,11 @@ class Camera:
|
|||||||
try:
|
try:
|
||||||
self.camera = gp.Camera()
|
self.camera = gp.Camera()
|
||||||
self.camera.init()
|
self.camera.init()
|
||||||
|
# Viewfinder activé AVANT de rendre la caméra visible au thread preview
|
||||||
|
self._activer_viewfinder_init()
|
||||||
self.connectee = True
|
self.connectee = True
|
||||||
self.mode = "gphoto2"
|
self.mode = "gphoto2"
|
||||||
log.info("Camera DSLR connectee")
|
log.info("Camera DSLR connectee (LiveView actif)")
|
||||||
self.activer_viewfinder()
|
|
||||||
return True
|
return True
|
||||||
except gp.GPhoto2Error as e:
|
except gp.GPhoto2Error as e:
|
||||||
log.warning(f"Pas de DSLR : {e}")
|
log.warning(f"Pas de DSLR : {e}")
|
||||||
@@ -159,7 +160,8 @@ class Camera:
|
|||||||
tmp_path = str(chemin_dest) + ".tmp"
|
tmp_path = str(chemin_dest) + ".tmp"
|
||||||
fichier_camera.save(tmp_path)
|
fichier_camera.save(tmp_path)
|
||||||
self.activer_viewfinder() # Miroir relevé immédiatement après la prise
|
self.activer_viewfinder() # Miroir relevé immédiatement après la prise
|
||||||
img = PILImage.open(tmp_path)
|
from PIL import ImageOps as PILImageOps
|
||||||
|
img = PILImageOps.exif_transpose(PILImage.open(tmp_path))
|
||||||
if img.width > 4000:
|
if img.width > 4000:
|
||||||
ratio = 4000 / img.width
|
ratio = 4000 / img.width
|
||||||
img = img.resize((4000, int(img.height * ratio)), PILImage.LANCZOS)
|
img = img.resize((4000, int(img.height * ratio)), PILImage.LANCZOS)
|
||||||
@@ -200,8 +202,19 @@ class Camera:
|
|||||||
else:
|
else:
|
||||||
return None # Pas de simulation ni webcam en dehors du mode dedie
|
return None # Pas de simulation ni webcam en dehors du mode dedie
|
||||||
|
|
||||||
|
def _activer_viewfinder_init(self):
|
||||||
|
"""Active le LiveView pendant l'init (pas de lock, appelé avant que le thread démarre)."""
|
||||||
|
try:
|
||||||
|
cfg = self.camera.get_config()
|
||||||
|
vf = cfg.get_child_by_name("viewfinder")
|
||||||
|
vf.set_value(1)
|
||||||
|
self.camera.set_config(cfg)
|
||||||
|
log.info("Viewfinder activé (init)")
|
||||||
|
except Exception as e:
|
||||||
|
log.warning(f"Viewfinder non supporté : {e}")
|
||||||
|
|
||||||
def activer_viewfinder(self):
|
def activer_viewfinder(self):
|
||||||
"""Active le LiveView (miroir levé en permanence) sur les Canon."""
|
"""Active le LiveView (miroir levé) depuis le thread — thread-safe."""
|
||||||
if self.mode != "gphoto2" or not self.connectee:
|
if self.mode != "gphoto2" or not self.connectee:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ xset s noblank
|
|||||||
# Automount USB (pour la photostation)
|
# Automount USB (pour la photostation)
|
||||||
udiskie --no-notify --no-appindicator &
|
udiskie --no-notify --no-appindicator &
|
||||||
|
|
||||||
|
# Libérer le DSLR : gvfsd-gphoto2 (GNOME) le monopolise sinon
|
||||||
|
pkill -f gvfsd-gphoto2 2>/dev/null || true
|
||||||
|
pkill -f gvfs-gphoto2-volume-monitor 2>/dev/null || true
|
||||||
|
sleep 1
|
||||||
|
|
||||||
# Backend en boucle : redémarre automatiquement s'il plante
|
# Backend en boucle : redémarre automatiquement s'il plante
|
||||||
_backend_loop() {
|
_backend_loop() {
|
||||||
while true; do
|
while true; do
|
||||||
|
|||||||
Reference in New Issue
Block a user