Multi-pose : même photo dupliquée + crop to fill
- La photo en cours est dupliquée dans toutes les zones du template - Crop to fill : l'image remplit chaque zone au maximum (pas de bords) - Fonctionne avec l'image éditée (filtres, etc.) pas juste l'originale Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -313,79 +313,73 @@ class EditorScreen(QWidget):
|
||||
if not zones:
|
||||
return
|
||||
|
||||
# Utilise la photo en cours (ou l'image éditée du canvas)
|
||||
source_pixmap = None
|
||||
if self.pixmap_item:
|
||||
source_pixmap = self.pixmap_item.pixmap()
|
||||
elif self.current_image_path:
|
||||
source_pixmap = QPixmap(self.current_image_path)
|
||||
|
||||
if not source_pixmap or source_pixmap.isNull():
|
||||
return
|
||||
|
||||
self.multipose_zones = zones
|
||||
self.multipose_images = {}
|
||||
self.multipose_source = source_pixmap
|
||||
|
||||
# Demander les photos pour chaque zone
|
||||
sr = self.scene.sceneRect()
|
||||
canvas_w, canvas_h = int(sr.width()) or 1800, int(sr.height()) or 1200
|
||||
# Taille canvas = format d'impression (ex: 1800x1200 pour 15x10)
|
||||
canvas_w = 1800
|
||||
canvas_h = 1200
|
||||
|
||||
self._render_multipose(source_pixmap, zones, canvas_w, canvas_h)
|
||||
|
||||
def _crop_to_fill(self, pixmap, target_w, target_h):
|
||||
"""Crop centré pour remplir exactement target_w x target_h."""
|
||||
src_w = pixmap.width()
|
||||
src_h = pixmap.height()
|
||||
src_ratio = src_w / src_h
|
||||
target_ratio = target_w / target_h
|
||||
|
||||
if src_ratio > target_ratio:
|
||||
# Image trop large → crop horizontal
|
||||
new_w = int(src_h * target_ratio)
|
||||
x_offset = (src_w - new_w) // 2
|
||||
cropped = pixmap.copy(x_offset, 0, new_w, src_h)
|
||||
else:
|
||||
# Image trop haute → crop vertical
|
||||
new_h = int(src_w / target_ratio)
|
||||
y_offset = (src_h - new_h) // 2
|
||||
cropped = pixmap.copy(0, y_offset, src_w, new_h)
|
||||
|
||||
return cropped.scaled(target_w, target_h,
|
||||
Qt.AspectRatioMode.IgnoreAspectRatio,
|
||||
Qt.TransformationMode.SmoothTransformation)
|
||||
|
||||
def _render_multipose(self, source_pixmap, zones, canvas_w, canvas_h):
|
||||
"""Dessine le multi-pose : même image dupliquée, crop to fill."""
|
||||
self.scene.clear()
|
||||
self.pixmap_item = None
|
||||
|
||||
# Canvas blanc
|
||||
white = QImage(canvas_w, canvas_h, QImage.Format.Format_ARGB32)
|
||||
white.fill(QColor(255, 255, 255))
|
||||
bg = self.scene.addPixmap(QPixmap.fromImage(white))
|
||||
self.scene.setSceneRect(QRectF(0, 0, canvas_w, canvas_h))
|
||||
|
||||
# Dessiner les zones avec numéros
|
||||
for i, (zx, zy, zw, zh) in enumerate(zones):
|
||||
rx = int(zx * canvas_w)
|
||||
ry = int(zy * canvas_h)
|
||||
rw = int(zw * canvas_w)
|
||||
rh = int(zh * canvas_h)
|
||||
|
||||
# Bordure de zone
|
||||
from PyQt6.QtWidgets import QGraphicsRectItem
|
||||
from PyQt6.QtGui import QPen, QBrush
|
||||
rect = self.scene.addRect(rx + 2, ry + 2, rw - 4, rh - 4,
|
||||
QPen(QColor(100, 100, 100), 2),
|
||||
QBrush(QColor(240, 240, 240)))
|
||||
|
||||
# Numéro
|
||||
text = self.scene.addText(str(i + 1), QFont("", 40))
|
||||
text.setDefaultTextColor(QColor(150, 150, 150))
|
||||
text.setPos(rx + rw / 2 - 20, ry + rh / 2 - 30)
|
||||
|
||||
self.view.fitInView(self.scene.sceneRect(), Qt.AspectRatioMode.KeepAspectRatio)
|
||||
|
||||
# Charger les photos depuis la galerie d'import
|
||||
import_photos = self.main_window.import_screen.photos
|
||||
if import_photos:
|
||||
self._fill_multipose_from_list(import_photos, zones, canvas_w, canvas_h)
|
||||
|
||||
def _fill_multipose_from_list(self, photos, zones, canvas_w, canvas_h):
|
||||
"""Remplit les zones multi-pose avec les premières photos disponibles."""
|
||||
self.scene.clear()
|
||||
|
||||
# Canvas blanc
|
||||
white = QImage(canvas_w, canvas_h, QImage.Format.Format_ARGB32)
|
||||
white.fill(QColor(255, 255, 255))
|
||||
self.pixmap_item = self.scene.addPixmap(QPixmap.fromImage(white))
|
||||
self.scene.setSceneRect(QRectF(0, 0, canvas_w, canvas_h))
|
||||
|
||||
gap = 4 # espace entre les photos
|
||||
gap = 6 # espace entre les zones
|
||||
|
||||
for i, (zx, zy, zw, zh) in enumerate(zones):
|
||||
if i >= len(photos):
|
||||
break
|
||||
rx = int(zx * canvas_w) + gap
|
||||
ry = int(zy * canvas_h) + gap
|
||||
rw = int(zw * canvas_w) - gap * 2
|
||||
rh = int(zh * canvas_h) - gap * 2
|
||||
|
||||
pixmap = QPixmap(photos[i])
|
||||
if pixmap.isNull():
|
||||
if rw <= 0 or rh <= 0:
|
||||
continue
|
||||
scaled = pixmap.scaled(rw, rh,
|
||||
Qt.AspectRatioMode.KeepAspectRatio,
|
||||
Qt.TransformationMode.SmoothTransformation)
|
||||
item = self.scene.addPixmap(scaled)
|
||||
# Centrer dans la zone
|
||||
offset_x = rx + (rw - scaled.width()) / 2
|
||||
offset_y = ry + (rh - scaled.height()) / 2
|
||||
item.setPos(offset_x, offset_y)
|
||||
|
||||
# Crop to fill : l'image remplit toute la zone
|
||||
filled = self._crop_to_fill(source_pixmap, rw, rh)
|
||||
item = self.scene.addPixmap(filled)
|
||||
item.setPos(rx, ry)
|
||||
|
||||
self.view.fitInView(self.scene.sceneRect(), Qt.AspectRatioMode.KeepAspectRatio)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user