perf: reduce scanner OCR workload
This commit is contained in:
parent
abf1b9d788
commit
07b1df3369
1 changed files with 13 additions and 2 deletions
|
|
@ -31,6 +31,11 @@ class ScannerScreen extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ScannerScreenState extends State<ScannerScreen> {
|
class _ScannerScreenState extends State<ScannerScreen> {
|
||||||
|
static const _autoScanTickInterval = Duration(milliseconds: 700);
|
||||||
|
static const _scanCooldownSuccess = Duration(milliseconds: 1500);
|
||||||
|
static const _scanCooldownNoMatch = Duration(milliseconds: 2200);
|
||||||
|
static const _scanCooldownError = Duration(milliseconds: 2600);
|
||||||
|
|
||||||
CameraController? _cameraController;
|
CameraController? _cameraController;
|
||||||
late final TextRecognizer _textRecognizer;
|
late final TextRecognizer _textRecognizer;
|
||||||
bool _isBusy = false;
|
bool _isBusy = false;
|
||||||
|
|
@ -42,6 +47,7 @@ class _ScannerScreenState extends State<ScannerScreen> {
|
||||||
String? _activeCollectionId;
|
String? _activeCollectionId;
|
||||||
bool _autoScanEnabled = false;
|
bool _autoScanEnabled = false;
|
||||||
Timer? _autoScanTimer;
|
Timer? _autoScanTimer;
|
||||||
|
DateTime _nextScanAllowedAt = DateTime.fromMillisecondsSinceEpoch(0);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -76,7 +82,7 @@ class _ScannerScreenState extends State<ScannerScreen> {
|
||||||
|
|
||||||
_cameraController = CameraController(
|
_cameraController = CameraController(
|
||||||
backCamera,
|
backCamera,
|
||||||
ResolutionPreset.high,
|
ResolutionPreset.medium,
|
||||||
enableAudio: false,
|
enableAudio: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -88,8 +94,9 @@ class _ScannerScreenState extends State<ScannerScreen> {
|
||||||
|
|
||||||
void _startAutoScanLoop() {
|
void _startAutoScanLoop() {
|
||||||
_autoScanTimer?.cancel();
|
_autoScanTimer?.cancel();
|
||||||
_autoScanTimer = Timer.periodic(const Duration(milliseconds: 1400), (_) {
|
_autoScanTimer = Timer.periodic(_autoScanTickInterval, (_) {
|
||||||
if (!_autoScanEnabled || _isBusy || !_cameraReady || !mounted) return;
|
if (!_autoScanEnabled || _isBusy || !_cameraReady || !mounted) return;
|
||||||
|
if (DateTime.now().isBefore(_nextScanAllowedAt)) return;
|
||||||
_captureAndScan();
|
_captureAndScan();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -105,6 +112,7 @@ class _ScannerScreenState extends State<ScannerScreen> {
|
||||||
/// Capture a photo, run OCR, and look for a Hot Wheels ID.
|
/// Capture a photo, run OCR, and look for a Hot Wheels ID.
|
||||||
Future<void> _captureAndScan() async {
|
Future<void> _captureAndScan() async {
|
||||||
if (_isBusy || _cameraController == null || !_cameraController!.value.isInitialized) return;
|
if (_isBusy || _cameraController == null || !_cameraController!.value.isInitialized) return;
|
||||||
|
if (_cameraController!.value.isTakingPicture) return;
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_isBusy = true;
|
_isBusy = true;
|
||||||
|
|
@ -131,11 +139,13 @@ class _ScannerScreenState extends State<ScannerScreen> {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|
||||||
if (found != null) {
|
if (found != null) {
|
||||||
|
_nextScanAllowedAt = DateTime.now().add(_scanCooldownSuccess);
|
||||||
setState(() => _lastDetected = found);
|
setState(() => _lastDetected = found);
|
||||||
if (widget.onDetected != null) {
|
if (widget.onDetected != null) {
|
||||||
await _submitDetected(found);
|
await _submitDetected(found);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
_nextScanAllowedAt = DateTime.now().add(_scanCooldownNoMatch);
|
||||||
setState(() {
|
setState(() {
|
||||||
_scanAccepted = false;
|
_scanAccepted = false;
|
||||||
_scanNotFound = true;
|
_scanNotFound = true;
|
||||||
|
|
@ -143,6 +153,7 @@ class _ScannerScreenState extends State<ScannerScreen> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
_nextScanAllowedAt = DateTime.now().add(_scanCooldownError);
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('Scan error: $e'), backgroundColor: Colors.red),
|
SnackBar(content: Text('Scan error: $e'), backgroundColor: Colors.red),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue