fix: recentrage incorrect si loin du centre d origine
This commit is contained in:
@@ -407,6 +407,9 @@ class _CropScreenState extends State<CropScreen> {
|
|||||||
offsetDy: _offset.dy,
|
offsetDy: _offset.dy,
|
||||||
displayPerSourcePx: displayPerSourcePx,
|
displayPerSourcePx: displayPerSourcePx,
|
||||||
cropSizeDisplay: _cropSize,
|
cropSizeDisplay: _cropSize,
|
||||||
|
// Le zoom sert UNIQUEMENT à viser le bon point (mapping du décalage) ;
|
||||||
|
// il n'agrandit pas le rendu de sortie.
|
||||||
|
zoomScale: _scale,
|
||||||
rotationDegrees: _rotation,
|
rotationDegrees: _rotation,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ class _ViewportCropParams {
|
|||||||
final double offsetDy;
|
final double offsetDy;
|
||||||
final double displayPerSourcePx; // facteur affichage/source (BoxFit.contain)
|
final double displayPerSourcePx; // facteur affichage/source (BoxFit.contain)
|
||||||
final double cropSizeDisplay; // côté de la fenêtre de visée, en pixels écran
|
final double cropSizeDisplay; // côté de la fenêtre de visée, en pixels écran
|
||||||
|
final double zoomScale; // zoom utilisateur : sert UNIQUEMENT au pointage
|
||||||
final double rotationDegrees;
|
final double rotationDegrees;
|
||||||
final int outputSize;
|
final int outputSize;
|
||||||
final String outputPath;
|
final String outputPath;
|
||||||
@@ -115,6 +116,7 @@ class _ViewportCropParams {
|
|||||||
required this.offsetDy,
|
required this.offsetDy,
|
||||||
required this.displayPerSourcePx,
|
required this.displayPerSourcePx,
|
||||||
required this.cropSizeDisplay,
|
required this.cropSizeDisplay,
|
||||||
|
required this.zoomScale,
|
||||||
required this.rotationDegrees,
|
required this.rotationDegrees,
|
||||||
required this.outputSize,
|
required this.outputSize,
|
||||||
required this.outputPath,
|
required this.outputPath,
|
||||||
@@ -143,14 +145,19 @@ void _viewportCropIsolateEntry(_ViewportCropParams p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final double f = p.displayPerSourcePx;
|
final double f = p.displayPerSourcePx;
|
||||||
// Côté de la fenêtre de visée, exprimé en pixels source (rotation = même échelle)
|
// Côté de la fenêtre de visée en pixels source. On utilise f SEUL (pas le
|
||||||
|
// zoom) → le champ de vision capturé est toujours celui de l'image non
|
||||||
|
// zoomée : le zoom n'est donc PAS pris en compte dans le rendu de sortie.
|
||||||
final int side = math.max(1, (p.cropSizeDisplay / f).round());
|
final int side = math.max(1, (p.cropSizeDisplay / f).round());
|
||||||
|
|
||||||
// Centre de la fenêtre de visée, en pixels de l'image (rotated) :
|
// Centre de la fenêtre de visée, en pixels de l'image (rotated).
|
||||||
// le centre de l'image est affiché à (centre_viewport + offset), la fenêtre
|
// La translation écran s'applique APRÈS le zoom, donc un déplacement écran
|
||||||
// est centrée sur le viewport → décalage de -offset/f par rapport au centre.
|
// `offset` vaut `offset / (f * zoom)` pixels source. On inclut donc le zoom
|
||||||
final double cropCenterX = rotated.width / 2 - p.offsetDx / f;
|
// ICI (uniquement pour le pointage) afin que la croix vise le même point
|
||||||
final double cropCenterY = rotated.height / 2 - p.offsetDy / f;
|
// quel que soit le niveau de zoom.
|
||||||
|
final double fz = f * p.zoomScale;
|
||||||
|
final double cropCenterX = rotated.width / 2 - p.offsetDx / fz;
|
||||||
|
final double cropCenterY = rotated.height / 2 - p.offsetDy / fz;
|
||||||
|
|
||||||
final int srcX = (cropCenterX - side / 2).round();
|
final int srcX = (cropCenterX - side / 2).round();
|
||||||
final int srcY = (cropCenterY - side / 2).round();
|
final int srcY = (cropCenterY - side / 2).round();
|
||||||
@@ -212,6 +219,7 @@ class ImageCropService {
|
|||||||
required double offsetDy,
|
required double offsetDy,
|
||||||
required double displayPerSourcePx,
|
required double displayPerSourcePx,
|
||||||
required double cropSizeDisplay,
|
required double cropSizeDisplay,
|
||||||
|
double zoomScale = 1.0,
|
||||||
double rotationDegrees = 0.0,
|
double rotationDegrees = 0.0,
|
||||||
int outputSize = maxOutputSize,
|
int outputSize = maxOutputSize,
|
||||||
}) async {
|
}) async {
|
||||||
@@ -224,6 +232,7 @@ class ImageCropService {
|
|||||||
offsetDy: offsetDy,
|
offsetDy: offsetDy,
|
||||||
displayPerSourcePx: displayPerSourcePx,
|
displayPerSourcePx: displayPerSourcePx,
|
||||||
cropSizeDisplay: cropSizeDisplay,
|
cropSizeDisplay: cropSizeDisplay,
|
||||||
|
zoomScale: zoomScale <= 0 ? 1.0 : zoomScale,
|
||||||
rotationDegrees: rotationDegrees,
|
rotationDegrees: rotationDegrees,
|
||||||
outputSize: outputSize,
|
outputSize: outputSize,
|
||||||
outputPath: outputPath,
|
outputPath: outputPath,
|
||||||
|
|||||||
Reference in New Issue
Block a user