fix(analysis): appliquer la rotation du crop sur l'image en modes calibration et plotting

This commit is contained in:
qguillaume
2026-05-27 12:11:00 +02:00
parent 04c1204116
commit 95e62abe47
2 changed files with 47 additions and 26 deletions

View File

@@ -23,11 +23,8 @@ import '../crop/crop_screen.dart';
import '../capture/capture_screen.dart';
import 'widgets/target_overlay.dart';
import 'widgets/target_calibration.dart';
import 'widgets/target_overlay.dart';
import 'widgets/score_card.dart';
import 'widgets/grouping_stats.dart';
import '../capture/capture_screen.dart'; // Si ton écran principal s'appelle comme ça
import '../crop/crop_screen.dart';
class AnalysisScreen extends StatelessWidget {
final String imagePath;
@@ -57,12 +54,20 @@ class AnalysisScreen extends StatelessWidget {
: null;
return ChangeNotifierProvider(
create: (context) => AnalysisProvider(
detectionService: context.read<TargetDetectionService>(),
scoreCalculatorService: context.read<ScoreCalculatorService>(),
groupingAnalyzerService: context.read<GroupingAnalyzerService>(),
sessionRepository: context.read<SessionRepository>(),
)..analyzeImage(imagePath, targetType, autoAnalyze: false, manualCenter: manualCenterOffset),
create: (context) {
final p = AnalysisProvider(
detectionService: context.read<TargetDetectionService>(),
scoreCalculatorService: context.read<ScoreCalculatorService>(),
groupingAnalyzerService: context.read<GroupingAnalyzerService>(),
sessionRepository: context.read<SessionRepository>(),
);
// Sauvegarde de l'angle de rotation d'origine directement dans l'état global
if (cropRotation != null) {
p.setCropRotation(cropRotation!);
}
p.analyzeImage(imagePath, targetType, autoAnalyze: false, manualCenter: manualCenterOffset);
return p;
},
child: _AnalysisScreenContent(
cropScale: cropScale,
cropOffset: cropOffset,
@@ -207,7 +212,7 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
),
),
// SECTION CORRIGÉE : Utilise maintenant widget.cropRotation sans aucune erreur !
// SECTION CORRIGÉE : Utilise maintenant la réactivité du provider globale
AspectRatio(
aspectRatio: provider.imageAspectRatio,
child: _isCalibrating
@@ -217,19 +222,15 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
ClipRect(
child: Builder(
builder: (context) {
final double rotationAngle = widget.cropRotation ?? 0.0;
return Transform(
transform: Matrix4.identity()
..translate(widget.cropOffset?.dx ?? 0.0, widget.cropOffset?.dy ?? 0.0)
..scale(1.0, 1.0), // Zoom ignoré au plotting pour rester en vue globale
..setTranslationRaw(widget.cropOffset?.dx ?? 0.0, widget.cropOffset?.dy ?? 0.0, 0.0)
..scale(1.0, 1.0) // Zoom ignoré au plotting pour rester en vue globale
..rotateZ((provider.cropRotation) * (math.pi / 180)), // FIX : Utilisation du provider dynamique
alignment: Alignment.center,
child: Transform.rotate(
angle: rotationAngle * (math.pi / 180),
child: Image.file(
File(provider.imagePath!),
fit: BoxFit.contain,
),
child: Image.file(
File(provider.imagePath!),
fit: BoxFit.contain,
),
);
}
@@ -486,10 +487,18 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
},
child: Stack(
children: [
Image.file(
File(provider.imagePath!),
key: _imageKey,
fit: BoxFit.fill,
// FIX CRITIQUE PLOTTING : L'image de fond doit appliquer exactement le même angle de rotation qu'en calibration !
Transform(
transform: Matrix4.identity()
..setTranslationRaw(widget.cropOffset?.dx ?? 0.0, widget.cropOffset?.dy ?? 0.0, 0.0)
..scale(1.0, 1.0)
..rotateZ((provider.cropRotation) * (math.pi / 180)),
alignment: Alignment.center,
child: Image.file(
File(provider.imagePath!),
key: _imageKey,
fit: BoxFit.contain, // Remplace BoxFit.fill pour s'aligner sur la Calibration
),
),
TargetOverlay(
targetCenterX: provider.targetCenterX,
@@ -568,6 +577,7 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
),
);
}
void _showSaveSessionDialog(BuildContext context, AnalysisProvider provider) {
showDialog(
context: context,
@@ -645,7 +655,7 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
weaponName: sessionProvider.currentWeapon,
weaponId: sessionProvider.currentWeaponId,
distance: sessionProvider.distance,
date: sessionProvider.sessionDate, // <-- CORRECTION : Prise en compte de la date ici aussi !
date: sessionProvider.sessionDate,
);
if (context.mounted) {
@@ -667,4 +677,4 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
),
);
}
}
}