fix: lenteur de l appli capture screen
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user