fix: lenteur de l appli capture screen

This commit is contained in:
qguillaume
2026-06-05 17:38:25 +02:00
parent 251d4bb599
commit 3ae9ceebc1

View File

@@ -16,7 +16,8 @@ import '../session/session_provider.dart';
import 'widgets/image_source_button.dart';
import '../../services/image_crop_service.dart';
import '../../services/opencv_target_service.dart'; // AJOUT : Pour la détection périodique
import 'package:image/image.dart' as img;
import 'package:path_provider/path_provider.dart';
class CaptureScreen extends StatefulWidget {
const CaptureScreen({super.key});
@@ -120,11 +121,60 @@ class _CaptureScreenState extends State<CaptureScreen> with SingleTickerProvider
}
}
// AJOUT : Démarre la détection périodique du parallélisme toutes les 2 secondes
void _startAlignmentDetection() {
_detectionTimer?.cancel();
_detectionTimer = Timer.periodic(const Duration(seconds: 2), (_) {
_analyzeCurrentFrame();
_detectionTimer = null;
// OPTIMISATION : startImageStream au lieu de takePicture
// On analyse 1 frame toutes les 3 secondes via le stream natif
DateTime? _lastAnalysis;
_cameraController!.startImageStream((CameraImage cameraImage) async {
if (_isAnalyzingFrame) return;
final now = DateTime.now();
if (_lastAnalysis != null &&
now.difference(_lastAnalysis!).inSeconds < 3) return;
_lastAnalysis = now;
_isAnalyzingFrame = true;
try {
// Convertir la CameraImage en fichier temporaire pour OpenCV
final tempDir = await getTemporaryDirectory();
final tempPath =
'${tempDir.path}/frame_analysis.jpg';
// Conversion YUV420 → JPEG via le package image
final img.Image? converted = _convertCameraImage(cameraImage);
if (converted == null) {
_isAnalyzingFrame = false;
return;
}
await File(tempPath)
.writeAsBytes(img.encodeJpg(converted, quality: 60));
final result = await _opencvService.detectTarget(tempPath);
try { await File(tempPath).delete(); } catch (_) {}
if (mounted && _showLiveCamera) {
setState(() {
if (!result.success) {
_alignmentStatus = null;
} else {
final bool isCentered =
result.centerX > 0.25 && result.centerX < 0.75 &&
result.centerY > 0.25 && result.centerY < 0.75;
final bool isSizedCorrectly = result.radius > 0.15;
_alignmentStatus = isCentered && isSizedCorrectly;
}
});
}
} catch (e) {
debugPrint('Erreur analyse frame: $e');
} finally {
_isAnalyzingFrame = false;
}
});
}
@@ -132,11 +182,64 @@ class _CaptureScreenState extends State<CaptureScreen> with SingleTickerProvider
void _stopAlignmentDetection() {
_detectionTimer?.cancel();
_detectionTimer = null;
// AJOUT : Stopper le stream proprement
try {
if (_cameraController != null &&
_cameraController!.value.isStreamingImages) {
_cameraController!.stopImageStream();
}
} catch (_) {}
_alignmentStatus = null;
}
// AJOUT : Conversion CameraImage (YUV420) vers img.Image
img.Image? _convertCameraImage(CameraImage cameraImage) {
try {
final int width = cameraImage.width;
final int height = cameraImage.height;
// Réduction de résolution pour l'analyse : on prend 1 pixel sur 2
// (suffisant pour détecter les cercles, beaucoup plus rapide)
final int targetW = width ~/ 2;
final int targetH = height ~/ 2;
final yPlane = cameraImage.planes[0];
final uPlane = cameraImage.planes[1];
final vPlane = cameraImage.planes[2];
final image = img.Image(width: targetW, height: targetH);
for (int y = 0; y < targetH; y++) {
for (int x = 0; x < targetW; x++) {
final int srcX = x * 2;
final int srcY = y * 2;
final int yIndex = srcY * yPlane.bytesPerRow + srcX;
final int uvIndex =
(srcY ~/ 2) * uPlane.bytesPerRow + (srcX ~/ 2) * uPlane.bytesPerPixel!;
final int yVal = yPlane.bytes[yIndex];
final int uVal = uPlane.bytes[uvIndex] - 128;
final int vVal = vPlane.bytes[uvIndex] - 128;
// Conversion YUV → RGB
final int r = (yVal + 1.402 * vVal).clamp(0, 255).toInt();
final int g = (yVal - 0.344136 * uVal - 0.714136 * vVal).clamp(0, 255).toInt();
final int b = (yVal + 1.772 * uVal).clamp(0, 255).toInt();
image.setPixelRgb(x, y, r, g, b);
}
}
return image;
} catch (e) {
debugPrint('Erreur conversion frame: $e');
return null;
}
}
// AJOUT : Capture une frame et analyse le parallélisme via OpenCV
Future<void> _analyzeCurrentFrame() async {
Future<void> _analyzeCurrentFrame() async {/*
// Verrou : on n'analyse pas si une analyse est déjà en cours
if (_isAnalyzingFrame) return;
if (_cameraController == null || !_cameraController!.value.isInitialized) return;
@@ -177,7 +280,7 @@ class _CaptureScreenState extends State<CaptureScreen> with SingleTickerProvider
debugPrint('Erreur analyse frame: $e');
} finally {
_isAnalyzingFrame = false;
}
}*/
}
Future<void> _handleGallerySelection() async {