fix: recentrage incorrect si loin du centre d origine
This commit is contained in:
@@ -389,19 +389,24 @@ class _CropScreenState extends State<CropScreen> {
|
||||
Future<void> _onCropConfirm() async {
|
||||
setState(() => _isLoading = true);
|
||||
try {
|
||||
// La zone de découpe doit refléter le DÉPLACEMENT (pan) et la ROTATION,
|
||||
// mais PAS le ZOOM. On neutralise donc temporairement _scale à 1.0 pour
|
||||
// le calcul, tout en conservant _offset. La rotation est appliquée à part
|
||||
// par cropToSquare(rotationDegrees: _rotation).
|
||||
final savedScale = _scale;
|
||||
_scale = 1.0;
|
||||
final cropRect = _calculateCropRect();
|
||||
_scale = savedScale; // on restaure pour l'affichage (retour arrière)
|
||||
// Facteur d'échelle affichage/source (BoxFit.contain) — identique à
|
||||
// celui utilisé pour afficher l'image dans l'aperçu.
|
||||
final imageAspect = _imageSize!.width / _imageSize!.height;
|
||||
final viewportAspect = _viewportSize.width / _viewportSize.height;
|
||||
final double displayWidth = imageAspect > viewportAspect
|
||||
? _viewportSize.width
|
||||
: _viewportSize.height * imageAspect;
|
||||
final double displayPerSourcePx = displayWidth / _imageSize!.width;
|
||||
|
||||
// AJOUT DE LA DECOUPE ET DU REDRESSEMENT GÉOMÉTRIQUE PHYSIQUE
|
||||
final croppedImagePath = await _cropService.cropToSquare(
|
||||
widget.imagePath,
|
||||
cropRect,
|
||||
// Découpe calée sur la fenêtre de visée : le DÉPLACEMENT (pan) et la
|
||||
// ROTATION sont pris en compte, le ZOOM est ignoré, et les débordements
|
||||
// sont remplis en noir → la position choisie est respectée à l'identique.
|
||||
final croppedImagePath = await _cropService.cropViewport(
|
||||
sourcePath: widget.imagePath,
|
||||
offsetDx: _offset.dx,
|
||||
offsetDy: _offset.dy,
|
||||
displayPerSourcePx: displayPerSourcePx,
|
||||
cropSizeDisplay: _cropSize,
|
||||
rotationDegrees: _rotation,
|
||||
);
|
||||
|
||||
@@ -438,43 +443,4 @@ class _CropScreenState extends State<CropScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
CropRect _calculateCropRect() {
|
||||
if (_imageSize == null) return const CropRect(x: 0, y: 0, width: 1, height: 1);
|
||||
|
||||
final imageAspect = _imageSize!.width / _imageSize!.height;
|
||||
final viewportAspect = _viewportSize.width / _viewportSize.height;
|
||||
|
||||
double displayWidth, displayHeight;
|
||||
if (imageAspect > viewportAspect) {
|
||||
displayWidth = _viewportSize.width;
|
||||
displayHeight = _viewportSize.width / imageAspect;
|
||||
} else {
|
||||
displayHeight = _viewportSize.height;
|
||||
displayWidth = _viewportSize.height * imageAspect;
|
||||
}
|
||||
|
||||
final scaledWidth = displayWidth * _scale;
|
||||
final scaledHeight = displayHeight * _scale;
|
||||
|
||||
final imageCenterX = _viewportSize.width / 2 + _offset.dx;
|
||||
final imageCenterY = _viewportSize.height / 2 + _offset.dy;
|
||||
|
||||
final imageLeft = imageCenterX - scaledWidth / 2;
|
||||
final imageTop = imageCenterY - scaledHeight / 2;
|
||||
|
||||
final cropLeft = (_viewportSize.width - _cropSize) / 2;
|
||||
final cropTop = (_viewportSize.height - _cropSize) / 2;
|
||||
|
||||
final relCropLeft = (cropLeft - imageLeft) / scaledWidth;
|
||||
final relCropTop = (cropTop - imageTop) / scaledHeight;
|
||||
final relCropWidth = _cropSize / scaledWidth;
|
||||
final relCropHeight = _cropSize / scaledHeight;
|
||||
|
||||
return CropRect(
|
||||
x: relCropLeft.clamp(0.0, 1.0),
|
||||
y: relCropTop.clamp(0.0, 1.0),
|
||||
width: relCropWidth.clamp(0.0, 1.0),
|
||||
height: relCropHeight.clamp(0.0, 1.0),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user