Skip to content

Commit

Permalink
Merge pull request #69 from ssj9685/android_mlkit_update
Browse files Browse the repository at this point in the history
Android mlkit update
  • Loading branch information
nateshmbhat authored Aug 22, 2024
2 parents cca0823 + 7bd0963 commit 55dbc37
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 49 deletions.
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.gms:play-services-mlkit-text-recognition:16.1.3'
implementation 'com.google.android.gms:play-services-mlkit-text-recognition:18.0.2'

// CameraX core library using camera2 implementation
implementation "androidx.camera:camera-camera2:1.1.0-alpha01"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,19 @@ import com.nateshmbhat.card_scanner.scanner_core.models.CardDetails
import com.nateshmbhat.card_scanner.scanner_core.models.CardScannerOptions
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import com.google.mlkit.vision.text.latin.TextRecognizerOptions


typealias onCardScanned = (cardDetails: CardDetails?) -> Unit
typealias onCardScanFailed = () -> Unit

class CardScannerCameraActivity : AppCompatActivity() {
private var previewUseCase: Preview? = null;
private var previewUseCase: Preview? = null
private var cameraProvider: ProcessCameraProvider? = null
private var cameraSelector: CameraSelector? = null
private var textRecognizer: TextRecognizer? = null
private var analysisUseCase: ImageAnalysis? = null
private lateinit var cardScannerOptions: CardScannerOptions
private var cardScannerOptions: CardScannerOptions? = null
private lateinit var cameraExecutor: ExecutorService
lateinit var animator: ObjectAnimator
lateinit var scannerLayout: View
Expand All @@ -49,12 +50,12 @@ class CardScannerCameraActivity : AppCompatActivity() {
setContentView(R.layout.card_scanner_camera_activity)
cardScannerOptions = intent.getParcelableExtra<CardScannerOptions>(CARD_SCAN_OPTIONS)

scannerLayout = findViewById(R.id.scannerLayout);
scannerBar = findViewById(R.id.scannerBar);
scannerLayout = findViewById(R.id.scannerLayout)
scannerBar = findViewById(R.id.scannerBar)
backButton = findViewById(R.id.backButton)
supportActionBar?.hide();
supportActionBar?.hide()

val vto = scannerLayout.viewTreeObserver;
val vto = scannerLayout.viewTreeObserver
backButton.setOnClickListener {
finish()
}
Expand Down Expand Up @@ -86,15 +87,10 @@ class CardScannerCameraActivity : AppCompatActivity() {

private fun startCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener(Runnable {
this.cameraProvider = cameraProviderFuture.get()
this.cameraSelector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build()

try {
bindAllCameraUseCases()
} catch (exc: Exception) {
debugLog("Use case binding failed : $exc", cardScannerOptions)
}
cameraProviderFuture.addListener({
cameraProvider = cameraProviderFuture.get()
cameraSelector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build()
bindAllCameraUseCases()
}, ContextCompat.getMainExecutor(this))
}

Expand Down Expand Up @@ -125,24 +121,35 @@ class CardScannerCameraActivity : AppCompatActivity() {
}

private fun bindPreviewUseCase() {
if(cameraProvider == null){
return
}

if (previewUseCase != null) {
cameraProvider?.unbind(previewUseCase)
cameraProvider!!.unbind(previewUseCase)
}

previewUseCase = Preview.Builder().build()
val previewView = findViewById<PreviewView>(R.id.cameraView)

previewUseCase!!.setSurfaceProvider(previewView.surfaceProvider)
cameraProvider?.bindToLifecycle( /* lifecycleOwner= */this, cameraSelector!!, previewUseCase)
cameraProvider!!.bindToLifecycle( /* lifecycleOwner= */this, cameraSelector!!, previewUseCase)
}

private fun bindAnalysisUseCase() {
if (cameraProvider == null) {
return
}

if (analysisUseCase != null) {
cameraProvider?.unbind(analysisUseCase)
cameraProvider!!.unbind(analysisUseCase)
}
textRecognizer?.close()
textRecognizer = TextRecognition.getClient()

if(textRecognizer != null){
textRecognizer!!.close()
}

textRecognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)

debugLog("card scanner options : $cardScannerOptions", cardScannerOptions)
val analysisUseCase = ImageAnalysis.Builder().build()
Expand All @@ -153,7 +160,7 @@ class CardScannerCameraActivity : AppCompatActivity() {
val returnIntent: Intent = Intent()
returnIntent.putExtra(SCAN_RESULT, cardDetails)
setResult(Activity.RESULT_OK, returnIntent)
this.finish()
finish()
}, onCardScanFailed = {
onBackPressed()
}))
Expand All @@ -176,12 +183,12 @@ class CardScannerCameraActivity : AppCompatActivity() {

override fun onPause() {
super.onPause()
textRecognizer?.close()
textRecognizer!!.close()
}

override fun onDestroy() {
super.onDestroy()
textRecognizer?.close()
textRecognizer!!.close()
}

override fun onBackPressed() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ package com.nateshmbhat.card_scanner.logger
import android.util.Log
import com.nateshmbhat.card_scanner.scanner_core.models.CardScannerOptions

fun debugLog(message: String, scannerOptions: CardScannerOptions, tag: String = "card_scanner_debug_log") {
fun debugLog(message: String, scannerOptions: CardScannerOptions?, tag: String = "card_scanner_debug_log") {
if(scannerOptions == null) {
return
}

if (scannerOptions.enableDebugLogs) {
Log.d(tag, message)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,33 @@ import com.nateshmbhat.card_scanner.onCardScanned
import com.nateshmbhat.card_scanner.scanner_core.models.CardDetails
import com.nateshmbhat.card_scanner.scanner_core.models.CardScannerOptions
import com.nateshmbhat.card_scanner.scanner_core.optimizer.CardDetailsScanOptimizer
import com.google.mlkit.vision.text.latin.TextRecognizerOptions


class CardScanner(private val scannerOptions: CardScannerOptions, private val onCardScanned: onCardScanned, private val onCardScanFailed: onCardScanFailed) : ImageAnalysis.Analyzer {
val singleFrameCardScanner: SingleFrameCardScanner = SingleFrameCardScanner(scannerOptions)
val cardDetailsScanOptimizer: CardDetailsScanOptimizer = CardDetailsScanOptimizer(scannerOptions)
class CardScanner(private val scannerOptions: CardScannerOptions?, private val onCardScanned: onCardScanned, private val onCardScanFailed: onCardScanFailed) : ImageAnalysis.Analyzer {
val singleFrameCardScanner: SingleFrameCardScanner = SingleFrameCardScanner(scannerOptions!!)
val cardDetailsScanOptimizer: CardDetailsScanOptimizer = CardDetailsScanOptimizer(scannerOptions!!)
var scanCompleted: Boolean = false

init {
if (scannerOptions.cardScannerTimeOut > 0) {
val timer = object : CountDownTimer((scannerOptions.cardScannerTimeOut * 1000).toLong(), 1000) {
override fun onTick(millisUntilFinished: Long) {}
if (scannerOptions != null) {
if (scannerOptions.cardScannerTimeOut > 0) {
val timer = object : CountDownTimer((scannerOptions.cardScannerTimeOut!! * 1000).toLong(), 1000) {
override fun onTick(millisUntilFinished: Long) {}

override fun onFinish() {
debugLog("Card scanner timeout reached", scannerOptions);
val cardDetails = cardDetailsScanOptimizer.getOptimalCardDetails()
if (cardDetails != null) {
finishCardScanning(cardDetails)
} else {
onCardScanFailed()
override fun onFinish() {
debugLog("Card scanner timeout reached", scannerOptions);
val cardDetails = cardDetailsScanOptimizer.getOptimalCardDetails()
if (cardDetails != null) {
finishCardScanning(cardDetails)
} else {
onCardScanFailed()
}
debugLog("Finishing card scan with card details : ${cardDetails}", scannerOptions);
}
debugLog("Finishing card scan with card details : ${cardDetails}", scannerOptions);
}
timer.start()
}
timer.start()
}
}

Expand All @@ -50,23 +53,25 @@ class CardScanner(private val scannerOptions: CardScannerOptions, private val on
if (mediaImage != null) {
val image = InputImage.fromMediaImage(mediaImage, 90)

val recognizer = TextRecognition.getClient()
val recognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)

val result = recognizer.process(image)
.addOnSuccessListener { visionText ->
if (scanCompleted) return@addOnSuccessListener
val cardDetails = singleFrameCardScanner.scanSingleFrame(visionText)
?: return@addOnSuccessListener;

if (scannerOptions.enableDebugLogs) {
debugLog("----------------------------------------------------", scannerOptions)
for (block in visionText.textBlocks) {
debugLog("visionText: TextBlock ============================", scannerOptions)
debugLog("visionText : ${block.text}", scannerOptions)
}
debugLog("----------------------------------------------------", scannerOptions)
if (scannerOptions != null) {
if (scannerOptions.enableDebugLogs) {
debugLog("----------------------------------------------------", scannerOptions)
for (block in visionText.textBlocks) {
debugLog("visionText: TextBlock ============================", scannerOptions)
debugLog("visionText : ${block.text}", scannerOptions)
}
debugLog("----------------------------------------------------", scannerOptions)

debugLog("Card details : $cardDetails", scannerOptions)
debugLog("Card details : $cardDetails", scannerOptions)
}
}
cardDetailsScanOptimizer.processCardDetails(cardDetails)
if (cardDetailsScanOptimizer.isReadyToFinishScan()) {
Expand Down

0 comments on commit 55dbc37

Please sign in to comment.