make scanner nullable to prevent leak; use early returns in process image callback; format
Showing
1 changed file
with
48 additions
and
50 deletions
| @@ -20,12 +20,12 @@ import androidx.camera.core.ImageAnalysis | @@ -20,12 +20,12 @@ import androidx.camera.core.ImageAnalysis | ||
| 20 | import androidx.camera.core.ImageProxy | 20 | import androidx.camera.core.ImageProxy |
| 21 | import androidx.camera.core.Preview | 21 | import androidx.camera.core.Preview |
| 22 | import androidx.camera.core.TorchState | 22 | import androidx.camera.core.TorchState |
| 23 | -import androidx.camera.core.resolutionselector.AspectRatioStrategy | ||
| 24 | import androidx.camera.core.resolutionselector.ResolutionSelector | 23 | import androidx.camera.core.resolutionselector.ResolutionSelector |
| 25 | import androidx.camera.core.resolutionselector.ResolutionStrategy | 24 | import androidx.camera.core.resolutionselector.ResolutionStrategy |
| 26 | import androidx.camera.lifecycle.ProcessCameraProvider | 25 | import androidx.camera.lifecycle.ProcessCameraProvider |
| 27 | import androidx.core.content.ContextCompat | 26 | import androidx.core.content.ContextCompat |
| 28 | import androidx.lifecycle.LifecycleOwner | 27 | import androidx.lifecycle.LifecycleOwner |
| 28 | +import com.google.mlkit.vision.barcode.BarcodeScanner | ||
| 29 | import com.google.mlkit.vision.barcode.BarcodeScannerOptions | 29 | import com.google.mlkit.vision.barcode.BarcodeScannerOptions |
| 30 | import com.google.mlkit.vision.barcode.BarcodeScanning | 30 | import com.google.mlkit.vision.barcode.BarcodeScanning |
| 31 | import com.google.mlkit.vision.barcode.common.Barcode | 31 | import com.google.mlkit.vision.barcode.common.Barcode |
| @@ -37,7 +37,6 @@ import io.flutter.view.TextureRegistry | @@ -37,7 +37,6 @@ import io.flutter.view.TextureRegistry | ||
| 37 | import java.io.ByteArrayOutputStream | 37 | import java.io.ByteArrayOutputStream |
| 38 | import kotlin.math.roundToInt | 38 | import kotlin.math.roundToInt |
| 39 | 39 | ||
| 40 | - | ||
| 41 | class MobileScanner( | 40 | class MobileScanner( |
| 42 | private val activity: Activity, | 41 | private val activity: Activity, |
| 43 | private val textureRegistry: TextureRegistry, | 42 | private val textureRegistry: TextureRegistry, |
| @@ -50,7 +49,7 @@ class MobileScanner( | @@ -50,7 +49,7 @@ class MobileScanner( | ||
| 50 | private var camera: Camera? = null | 49 | private var camera: Camera? = null |
| 51 | private var preview: Preview? = null | 50 | private var preview: Preview? = null |
| 52 | private var textureEntry: TextureRegistry.SurfaceTextureEntry? = null | 51 | private var textureEntry: TextureRegistry.SurfaceTextureEntry? = null |
| 53 | - private var scanner = BarcodeScanning.getClient() | 52 | + private var scanner: BarcodeScanner? = null |
| 54 | private var lastScanned: List<String?>? = null | 53 | private var lastScanned: List<String?>? = null |
| 55 | private var scannerTimeout = false | 54 | private var scannerTimeout = false |
| 56 | private var displayListener: DisplayManager.DisplayListener? = null | 55 | private var displayListener: DisplayManager.DisplayListener? = null |
| @@ -76,76 +75,75 @@ class MobileScanner( | @@ -76,76 +75,75 @@ class MobileScanner( | ||
| 76 | scannerTimeout = true | 75 | scannerTimeout = true |
| 77 | } | 76 | } |
| 78 | 77 | ||
| 79 | - scanner.process(inputImage) | ||
| 80 | - .addOnSuccessListener { barcodes -> | 78 | + scanner?.let { |
| 79 | + it.process(inputImage).addOnSuccessListener { barcodes -> | ||
| 81 | if (detectionSpeed == DetectionSpeed.NO_DUPLICATES) { | 80 | if (detectionSpeed == DetectionSpeed.NO_DUPLICATES) { |
| 82 | - val newScannedBarcodes = barcodes.mapNotNull { barcode -> barcode.rawValue }.sorted() | 81 | + val newScannedBarcodes = barcodes.mapNotNull { |
| 82 | + barcode -> barcode.rawValue | ||
| 83 | + }.sorted() | ||
| 84 | + | ||
| 83 | if (newScannedBarcodes == lastScanned) { | 85 | if (newScannedBarcodes == lastScanned) { |
| 84 | // New scanned is duplicate, returning | 86 | // New scanned is duplicate, returning |
| 85 | return@addOnSuccessListener | 87 | return@addOnSuccessListener |
| 86 | } | 88 | } |
| 87 | - if (newScannedBarcodes.isNotEmpty()) lastScanned = newScannedBarcodes | 89 | + if (newScannedBarcodes.isNotEmpty()) { |
| 90 | + lastScanned = newScannedBarcodes | ||
| 91 | + } | ||
| 88 | } | 92 | } |
| 89 | 93 | ||
| 90 | val barcodeMap: MutableList<Map<String, Any?>> = mutableListOf() | 94 | val barcodeMap: MutableList<Map<String, Any?>> = mutableListOf() |
| 91 | 95 | ||
| 92 | for (barcode in barcodes) { | 96 | for (barcode in barcodes) { |
| 93 | - if (scanWindow != null) { | ||
| 94 | - val match = isBarcodeInScanWindow(scanWindow!!, barcode, imageProxy) | ||
| 95 | - if (!match) { | ||
| 96 | - continue | ||
| 97 | - } else { | ||
| 98 | - barcodeMap.add(barcode.data) | ||
| 99 | - } | ||
| 100 | - } else { | 97 | + if (scanWindow == null) { |
| 101 | barcodeMap.add(barcode.data) | 98 | barcodeMap.add(barcode.data) |
| 99 | + continue | ||
| 102 | } | 100 | } |
| 103 | - } | ||
| 104 | 101 | ||
| 102 | + if (isBarcodeInScanWindow(scanWindow!!, barcode, imageProxy)) { | ||
| 103 | + barcodeMap.add(barcode.data) | ||
| 104 | + } | ||
| 105 | + } | ||
| 105 | 106 | ||
| 106 | - if (barcodeMap.isNotEmpty()) { | ||
| 107 | - if (returnImage) { | ||
| 108 | - | ||
| 109 | - val bitmap = Bitmap.createBitmap(mediaImage.width, mediaImage.height, Bitmap.Config.ARGB_8888) | ||
| 110 | - | ||
| 111 | - val imageFormat = YuvToRgbConverter(activity.applicationContext) | ||
| 112 | - | ||
| 113 | - imageFormat.yuvToRgb(mediaImage, bitmap) | 107 | + if (barcodeMap.isEmpty()) { |
| 108 | + return@addOnSuccessListener | ||
| 109 | + } | ||
| 114 | 110 | ||
| 115 | - val bmResult = rotateBitmap(bitmap, camera?.cameraInfo?.sensorRotationDegrees?.toFloat() ?: 90f) | 111 | + if (!returnImage) { |
| 112 | + mobileScannerCallback( | ||
| 113 | + barcodeMap, | ||
| 114 | + null, | ||
| 115 | + null, | ||
| 116 | + null | ||
| 117 | + ) | ||
| 118 | + return@addOnSuccessListener | ||
| 119 | + } | ||
| 116 | 120 | ||
| 117 | - val stream = ByteArrayOutputStream() | ||
| 118 | - bmResult.compress(Bitmap.CompressFormat.PNG, 100, stream) | ||
| 119 | - val byteArray = stream.toByteArray() | ||
| 120 | - val bmWidth = bmResult.width | ||
| 121 | - val bmHeight = bmResult.height | ||
| 122 | - bmResult.recycle() | 121 | + val bitmap = Bitmap.createBitmap(mediaImage.width, mediaImage.height, Bitmap.Config.ARGB_8888) |
| 122 | + val imageFormat = YuvToRgbConverter(activity.applicationContext) | ||
| 123 | 123 | ||
| 124 | + imageFormat.yuvToRgb(mediaImage, bitmap) | ||
| 124 | 125 | ||
| 125 | - mobileScannerCallback( | ||
| 126 | - barcodeMap, | ||
| 127 | - byteArray, | ||
| 128 | - bmWidth, | ||
| 129 | - bmHeight | ||
| 130 | - ) | 126 | + val bmResult = rotateBitmap(bitmap, camera?.cameraInfo?.sensorRotationDegrees?.toFloat() ?: 90f) |
| 131 | 127 | ||
| 132 | - } else { | 128 | + val stream = ByteArrayOutputStream() |
| 129 | + bmResult.compress(Bitmap.CompressFormat.PNG, 100, stream) | ||
| 130 | + val byteArray = stream.toByteArray() | ||
| 131 | + val bmWidth = bmResult.width | ||
| 132 | + val bmHeight = bmResult.height | ||
| 133 | + bmResult.recycle() | ||
| 133 | 134 | ||
| 134 | - mobileScannerCallback( | ||
| 135 | - barcodeMap, | ||
| 136 | - null, | ||
| 137 | - null, | ||
| 138 | - null | ||
| 139 | - ) | ||
| 140 | - } | ||
| 141 | - } | ||
| 142 | - } | ||
| 143 | - .addOnFailureListener { e -> | 135 | + mobileScannerCallback( |
| 136 | + barcodeMap, | ||
| 137 | + byteArray, | ||
| 138 | + bmWidth, | ||
| 139 | + bmHeight | ||
| 140 | + ) | ||
| 141 | + }.addOnFailureListener { e -> | ||
| 144 | mobileScannerErrorCallback( | 142 | mobileScannerErrorCallback( |
| 145 | e.localizedMessage ?: e.toString() | 143 | e.localizedMessage ?: e.toString() |
| 146 | ) | 144 | ) |
| 147 | - } | ||
| 148 | - .addOnCompleteListener { imageProxy.close() } | 145 | + }.addOnCompleteListener { imageProxy.close() } |
| 146 | + } | ||
| 149 | 147 | ||
| 150 | if (detectionSpeed == DetectionSpeed.NORMAL) { | 148 | if (detectionSpeed == DetectionSpeed.NORMAL) { |
| 151 | // Set timer and continue | 149 | // Set timer and continue |
-
Please register or login to post a comment