fix(crop): stabiliser le rectangle géométrique de découpe et l'enchaînement des zooms
This commit is contained in:
@@ -156,7 +156,7 @@ class _CropScreenState extends State<CropScreen> {
|
||||
style: TextStyle(color: Colors.white70, fontSize: 13, fontWeight: FontWeight.w600),
|
||||
),
|
||||
Text(
|
||||
'${_rotation.toStringAsFixed(1)}°', // Affiche désormais le dixième de degré pour la précision
|
||||
'${_rotation.toStringAsFixed(1)}°',
|
||||
style: const TextStyle(color: Color(0xFF00FF00), fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
@@ -167,9 +167,9 @@ class _CropScreenState extends State<CropScreen> {
|
||||
Expanded(
|
||||
child: Slider(
|
||||
value: _rotation,
|
||||
min: -15.0, // Pivot maximum à gauche bridé à 15°
|
||||
max: 15.0, // Pivot maximum à droite bridé à 15°
|
||||
divisions: 300, // 300 divisions pour obtenir un cran ultra-précis tous les 0,1°
|
||||
min: -15.0,
|
||||
max: 15.0,
|
||||
divisions: 300,
|
||||
label: '${_rotation.toStringAsFixed(1)}°',
|
||||
activeColor: const Color(0xFF1A73E8),
|
||||
inactiveColor: Colors.white12,
|
||||
@@ -182,7 +182,6 @@ class _CropScreenState extends State<CropScreen> {
|
||||
),
|
||||
const Icon(Icons.rotate_right, color: Colors.white38, size: 20),
|
||||
const SizedBox(width: 4),
|
||||
// Petit bouton Reset rapide pour cette jauge
|
||||
IconButton(
|
||||
icon: const Icon(Icons.restart_alt, color: Colors.white54, size: 20),
|
||||
onPressed: () {
|
||||
@@ -249,7 +248,7 @@ class _CropScreenState extends State<CropScreen> {
|
||||
onScaleUpdate: _onScaleUpdate,
|
||||
child: Stack(
|
||||
children: [
|
||||
// 1. L'image brute avec ses transformations
|
||||
// 1. L'image brute avec ses transformations (Reste calé sur BoxFit.contain d'origine)
|
||||
Positioned.fill(
|
||||
child: Center(
|
||||
child: Transform(
|
||||
@@ -302,7 +301,6 @@ class _CropScreenState extends State<CropScreen> {
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
// Zone visible : Rectangle parfait sans aucun BorderRadius
|
||||
Center(
|
||||
child: Container(
|
||||
width: _cropSize,
|
||||
@@ -372,8 +370,18 @@ class _CropScreenState extends State<CropScreen> {
|
||||
setState(() => _isLoading = true);
|
||||
try {
|
||||
final cropRect = _calculateCropRect();
|
||||
final targetCenterX = cropRect.x + cropRect.width / 2;
|
||||
final targetCenterY = cropRect.y + cropRect.height / 2;
|
||||
|
||||
// AJOUT DE LA DECOUPE ET DU REDRESSEMENT GÉOMÉTRIQUE PHYSIQUE
|
||||
final croppedImagePath = await _cropService.cropToSquare(
|
||||
widget.imagePath,
|
||||
cropRect,
|
||||
rotationDegrees: _rotation, // On transmet la rotation à la jauge haute précision
|
||||
);
|
||||
|
||||
// L'image sortant du service étant désormais un carré physique parfait (1:1),
|
||||
// le centre de la cible se trouve précisément au milieu (0.5, 0.5)
|
||||
const targetCenterX = 0.5;
|
||||
const targetCenterY = 0.5;
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
@@ -381,13 +389,13 @@ class _CropScreenState extends State<CropScreen> {
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) => AnalysisScreen(
|
||||
imagePath: widget.imagePath,
|
||||
imagePath: croppedImagePath, // On injecte le fichier carré nettoyé
|
||||
targetType: widget.targetType,
|
||||
initialCenterX: targetCenterX,
|
||||
initialCenterY: targetCenterY,
|
||||
cropScale: _scale,
|
||||
cropOffset: _offset,
|
||||
cropRotation: _rotation,
|
||||
cropScale: 1.0, // Réinitialisé car la texture est déjà recadrée à la bonne échelle
|
||||
cropOffset: Offset.zero, // Réinitialisé car le fichier est déjà parfaitement centré
|
||||
cropRotation: 0.0, // Réinitialisé car les pixels ont déjà subi la rotation matricielle
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -395,7 +403,7 @@ class _CropScreenState extends State<CropScreen> {
|
||||
if (mounted) {
|
||||
setState(() => _isLoading = false);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Erreur: $e'), backgroundColor: AppTheme.errorColor),
|
||||
SnackBar(content: Text('Erreur de découpe : $e'), backgroundColor: AppTheme.errorColor),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -434,10 +442,10 @@ class _CropScreenState extends State<CropScreen> {
|
||||
final relCropHeight = _cropSize / scaledHeight;
|
||||
|
||||
return CropRect(
|
||||
x: relCropLeft,
|
||||
y: relCropTop,
|
||||
width: relCropWidth,
|
||||
height: relCropHeight,
|
||||
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