Résolution : réduire à 2 MP max avant OCR (ML Kit ne gagne rien au-delà)
6. Pipeline OCR + extraction champs
val recognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)
val inputImage = InputImage.fromBitmap(enhancedBitmap, 0)
recognizer.process(inputImage)
.addOnSuccessListener { visionText ->
val cin = Regex("""[A-Z]\d{7}""").find(visionText.text)?.value
val rib = Regex("""\d{20}""").find(visionText.text)?.value
// Luhn check sur carte, MRZ parser pour passeport
}
Dépendance ML Kit Text Recognition (modèle latin bundled, OCR 100 % on-device) :
// app/build.gradle — bloc dependencies
implementation 'com.google.mlkit:text-recognition:16.0.1'
// Autres écritures via artefacts dédiés : text-recognition-chinese,
// -devanagari, -japanese, -korean (un par script à reconnaître).
7. Stockage temporaire sécurisé
// Fichier chiffré via EncryptedFile (Jetpack Security)val encryptedFile = EncryptedFile.Builder(
context, File(context.cacheDir, "img_${uuid}.tmp"),
MasterKey.Builder(context).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build(),
EncryptedFile.FileEncryptionScheme.AES256_GCM_HASHED_FILENAME
).build()
encryptedFile.openFileOutput().use { it.write(imageBytes) }
// Purge automatique via WorkManager après upload ou 24 h
8. Performance et gestion mémoire
// Processing asynchrone — toujours sur IO
viewModelScope.launch(Dispatchers.IO) {
val result = processImage(bitmap) // timeout : 5 s max
withContext(Dispatchers.Main) { updateUI(result) }
}
// Libérer les Mat OpenCV explicitementval mat = bitmap.toMat()
try { /* traitement */ } finally { mat.release() }
// Coil avec contrainte mémoire pour affichage
imageView.load(uri) { size(800, 600); allowHardware(false) }
Garde-fous / Anti-patterns / Pièges
Anti-pattern
Conséquence
Correction
Traiter le Bitmap sur le thread principal
ANR / freeze UI
Dispatchers.IO obligatoire
Ne pas appeler mat.release()
OOM natif non détecté par GC Java
Bloc try/finally systématique
Stocker images brutes non chiffrées dans le cache
Fuite données KYC
EncryptedFile + purge auto
Enhancement avant rectification perspective
Artefacts sur bords déformés
Toujours rectifier avant d'améliorer
Résolution 4K+ passée à ML Kit OCR
Lenteur sans gain qualité
Redimensionner à ≤ 2 MP avant OCR
Fallback silencieux en cas de qualité insuffisante
Données OCR corrompues
Rejet explicite + message utilisateur
Initialiser ML Kit dans le constructeur du ViewModel
Crash si contexte indisponible
Injection lazy ou Factory
Bonnes pratiques 2026
ML Kit Text Recognition v2 : scripts pris en charge = latin, chinois, devanagari, japonais, coréen (un artefact bundled par script). L'arabe n'est PAS supporté nativement — pour de l'OCR arabe, prévoir Tesseract (tessdata ara) ou un service cloud.
CameraX 1.4+ : utiliser ZoomState et TapToFocus via CameraControl plutôt que manipuler manuellement la mise au point.
Kotlin Multiplatform : factoriser processImage(ImageData) -> ProcessedResult dans :shared ; CameraX (Android) et AVFoundation (iOS) restent dans les modules platform via expect/actual.
Privacy by design : traitement 100 % on-device quand possible, pas de transfert d'image brute vers serveur, auto-delete après upload confirmé.
Profiling : utiliser Android Studio Profiler (Memory + CPU) sur un appareil physique mid-range (≤ 3 Go RAM) — les émulateurs masquent les fuites de mémoire native OpenCV.
Communication Rules — MANDATORY
Ultra-concise. No filler, no preamble, no pleasantries.
Never say "happy to help", "sure!", "great question", "let me", or similar.
Tool first, talk second. Act before explaining.
Result first. Lead with outcome, not process.
Stop when done. No summary, no recap, no trailing commentary.