Showing
2 changed files
with
55 additions
and
49 deletions
| @@ -9,6 +9,7 @@ import android.graphics.RectF | @@ -9,6 +9,7 @@ import android.graphics.RectF | ||
| 9 | import android.net.Uri | 9 | import android.net.Uri |
| 10 | import android.util.Log | 10 | import android.util.Log |
| 11 | import android.util.Size | 11 | import android.util.Size |
| 12 | +import android.util.Rational | ||
| 12 | import android.media.Image | 13 | import android.media.Image |
| 13 | import android.view.Surface | 14 | import android.view.Surface |
| 14 | import androidx.annotation.NonNull | 15 | import androidx.annotation.NonNull |
| @@ -103,29 +104,30 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | @@ -103,29 +104,30 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | ||
| 103 | 104 | ||
| 104 | @ExperimentalGetImage | 105 | @ExperimentalGetImage |
| 105 | val analyzer = ImageAnalysis.Analyzer { imageProxy -> // YUV_420_888 format | 106 | val analyzer = ImageAnalysis.Analyzer { imageProxy -> // YUV_420_888 format |
| 106 | -// when (analyzeMode) { | ||
| 107 | -// AnalyzeMode.BARCODE -> { | ||
| 108 | - val mediaImage = imageProxy.image ?: return@Analyzer | ||
| 109 | - var inputImage = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees) | ||
| 110 | - | ||
| 111 | - scanner.process(inputImage) | ||
| 112 | - .addOnSuccessListener { barcodes -> | ||
| 113 | - for (barcode in barcodes) { | ||
| 114 | - | ||
| 115 | - if(scanWindow != null) { | ||
| 116 | - val match = isbarCodeInScanWindow(scanWindow!!, barcode, inputImage) | ||
| 117 | - if(!match) continue | ||
| 118 | - } | ||
| 119 | - | ||
| 120 | - val event = mapOf("name" to "barcode", "data" to barcode.data) | ||
| 121 | - sink?.success(event) | ||
| 122 | - } | ||
| 123 | - } | ||
| 124 | - .addOnFailureListener { e -> Log.e(TAG, e.message, e) } | ||
| 125 | - .addOnCompleteListener { imageProxy.close() } | ||
| 126 | -// } | ||
| 127 | -// else -> imageProxy.close() | ||
| 128 | -// } | 107 | + val mediaImage = imageProxy.image ?: return@Analyzer |
| 108 | + var inputImage = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees) | ||
| 109 | + | ||
| 110 | + scanner.process(inputImage) | ||
| 111 | + .addOnSuccessListener { barcodes -> | ||
| 112 | + for (barcode in barcodes) { | ||
| 113 | + print("image: ") | ||
| 114 | + println(inputImage.getWidth()); | ||
| 115 | + println(inputImage.getHeight()); | ||
| 116 | + | ||
| 117 | + print("barcode: ") | ||
| 118 | + println(barcode.getBoundingBox()); | ||
| 119 | + | ||
| 120 | + if(scanWindow != null) { | ||
| 121 | + val match = isbarCodeInScanWindow(scanWindow!!, barcode, imageProxy) | ||
| 122 | + if(!match) continue | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + val event = mapOf("name" to "barcode", "data" to barcode.data) | ||
| 126 | + sink?.success(event) | ||
| 127 | + } | ||
| 128 | + } | ||
| 129 | + .addOnFailureListener { e -> Log.e(TAG, e.message, e) } | ||
| 130 | + .addOnCompleteListener { imageProxy.close() } | ||
| 129 | } | 131 | } |
| 130 | 132 | ||
| 131 | private var scanner = BarcodeScanning.getClient() | 133 | private var scanner = BarcodeScanning.getClient() |
| @@ -136,19 +138,22 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | @@ -136,19 +138,22 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | ||
| 136 | 138 | ||
| 137 | // scales the scanWindow to the provided inputImage and checks if that scaled | 139 | // scales the scanWindow to the provided inputImage and checks if that scaled |
| 138 | // scanWindow contains the barcode | 140 | // scanWindow contains the barcode |
| 139 | - private fun isbarCodeInScanWindow(scanWindow: List<Float>, barcode: Barcode, inputImage: InputImage): Boolean { | 141 | + private fun isbarCodeInScanWindow(scanWindow: List<Float>, barcode: Barcode, inputImage: ImageProxy): Boolean { |
| 140 | val barcodeBoundingBox = barcode.getBoundingBox() | 142 | val barcodeBoundingBox = barcode.getBoundingBox() |
| 141 | if(barcodeBoundingBox == null) return false | 143 | if(barcodeBoundingBox == null) return false |
| 142 | 144 | ||
| 143 | - val imageWidth = inputImage.getWidth(); | ||
| 144 | - val imageHeight = inputImage.getHeight(); | 145 | + val imageWidth = inputImage.getHeight(); |
| 146 | + val imageHeight = inputImage.getWidth(); | ||
| 145 | 147 | ||
| 146 | val left = (scanWindow[0] * imageWidth).roundToInt() | 148 | val left = (scanWindow[0] * imageWidth).roundToInt() |
| 147 | val top = (scanWindow[1] * imageHeight).roundToInt() | 149 | val top = (scanWindow[1] * imageHeight).roundToInt() |
| 148 | val right = (scanWindow[2] * imageWidth).roundToInt() | 150 | val right = (scanWindow[2] * imageWidth).roundToInt() |
| 149 | val bottom = (scanWindow[3] * imageHeight).roundToInt() | 151 | val bottom = (scanWindow[3] * imageHeight).roundToInt() |
| 150 | 152 | ||
| 151 | - val scaledScanWindow = Rect(left, top, right, bottom) | 153 | + val scaledScanWindow = Rect(left, top, right, bottom) |
| 154 | + | ||
| 155 | + print("scanWindow: ") | ||
| 156 | + println(scaledScanWindow) | ||
| 152 | return scaledScanWindow.contains(barcodeBoundingBox) | 157 | return scaledScanWindow.contains(barcodeBoundingBox) |
| 153 | } | 158 | } |
| 154 | 159 | ||
| @@ -197,7 +202,10 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | @@ -197,7 +202,10 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | ||
| 197 | result.error("textureEntry", "textureEntry is null", null) | 202 | result.error("textureEntry", "textureEntry is null", null) |
| 198 | return@addListener | 203 | return@addListener |
| 199 | } | 204 | } |
| 200 | - | 205 | + |
| 206 | + // Select the correct camera | ||
| 207 | + val selector = if (facing == 0) CameraSelector.DEFAULT_FRONT_CAMERA else CameraSelector.DEFAULT_BACK_CAMERA | ||
| 208 | + | ||
| 201 | // Preview | 209 | // Preview |
| 202 | val surfaceProvider = Preview.SurfaceProvider { request -> | 210 | val surfaceProvider = Preview.SurfaceProvider { request -> |
| 203 | val texture = textureEntry!!.surfaceTexture() | 211 | val texture = textureEntry!!.surfaceTexture() |
| @@ -207,28 +215,30 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | @@ -207,28 +215,30 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | ||
| 207 | } | 215 | } |
| 208 | 216 | ||
| 209 | // Build the preview to be shown on the Flutter texture | 217 | // Build the preview to be shown on the Flutter texture |
| 210 | - val previewBuilder = Preview.Builder() | ||
| 211 | - .setTargetAspectRatio(ratio) | ||
| 212 | - | 218 | + val previewBuilder = Preview.Builder().setTargetAspectRatio(ratio) |
| 213 | preview = previewBuilder.build().apply { setSurfaceProvider(surfaceProvider) } | 219 | preview = previewBuilder.build().apply { setSurfaceProvider(surfaceProvider) } |
| 214 | 220 | ||
| 221 | + // bind to lifecycle temporarily to fetch dimensions. | ||
| 222 | + cameraProvider!!.bindToLifecycle(activity as LifecycleOwner, selector, preview) | ||
| 223 | + val previewResolution = preview!!.resolutionInfo!!.resolution | ||
| 224 | + val previewRotation = preview!!.getTargetRotation() | ||
| 225 | + | ||
| 215 | // Build the analyzer to be passed on to MLKit | 226 | // Build the analyzer to be passed on to MLKit |
| 216 | val analysisBuilder = ImageAnalysis.Builder() | 227 | val analysisBuilder = ImageAnalysis.Builder() |
| 217 | .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) | 228 | .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) |
| 218 | - .setTargetAspectRatio(ratio) | ||
| 219 | - | 229 | + .setTargetAspectRatio(ratio) |
| 230 | + .setTargetRotation(previewRotation) | ||
| 220 | val analysis = analysisBuilder.build().apply { setAnalyzer(executor, analyzer) } | 231 | val analysis = analysisBuilder.build().apply { setAnalyzer(executor, analyzer) } |
| 221 | - | ||
| 222 | - // Select the correct camera | ||
| 223 | - val selector = if (facing == 0) CameraSelector.DEFAULT_FRONT_CAMERA else CameraSelector.DEFAULT_BACK_CAMERA | ||
| 224 | - | ||
| 225 | - camera = cameraProvider!!.bindToLifecycle(activity as LifecycleOwner, selector, preview, analysis) | ||
| 226 | - | ||
| 227 | - val analysisSize = analysis.resolutionInfo?.resolution ?: Size(0, 0) | ||
| 228 | - val previewSize = preview!!.resolutionInfo?.resolution ?: Size(0, 0) | ||
| 229 | 232 | ||
| 230 | - Log.i("LOG", "Analyzer: $analysisSize") | ||
| 231 | - Log.i("LOG", "Preview: $previewSize") | 233 | + val viewPort = ViewPort.Builder(Rational(previewResolution.width, previewResolution.height), previewRotation).build() |
| 234 | + val useCaseGroup = UseCaseGroup.Builder() | ||
| 235 | + .setViewPort(viewPort) | ||
| 236 | + .addUseCase(preview!!) | ||
| 237 | + .addUseCase(analysis) | ||
| 238 | + .build() | ||
| 239 | + | ||
| 240 | + cameraProvider!!.unbindAll() | ||
| 241 | + camera = cameraProvider!!.bindToLifecycle(activity as LifecycleOwner, selector, useCaseGroup) | ||
| 232 | 242 | ||
| 233 | if (camera == null) { | 243 | if (camera == null) { |
| 234 | result.error("camera", "camera is null", null) | 244 | result.error("camera", "camera is null", null) |
| @@ -277,11 +287,6 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | @@ -277,11 +287,6 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | ||
| 277 | scanner.process(inputImage) | 287 | scanner.process(inputImage) |
| 278 | .addOnSuccessListener { barcodes -> | 288 | .addOnSuccessListener { barcodes -> |
| 279 | for (barcode in barcodes) { | 289 | for (barcode in barcodes) { |
| 280 | - if(scanWindow != null) { | ||
| 281 | - val match = isbarCodeInScanWindow(scanWindow!!, barcode, inputImage) | ||
| 282 | - if(!match) continue | ||
| 283 | - } | ||
| 284 | - | ||
| 285 | barcodeFound = true | 290 | barcodeFound = true |
| 286 | sink?.success(mapOf("name" to "barcode", "data" to barcode.data)) | 291 | sink?.success(mapOf("name" to "barcode", "data" to barcode.data)) |
| 287 | } | 292 | } |
| @@ -45,9 +45,10 @@ class _BarcodeScannerWithScanWindowState | @@ -45,9 +45,10 @@ class _BarcodeScannerWithScanWindowState | ||
| 45 | body: Builder( | 45 | body: Builder( |
| 46 | builder: (context) { | 46 | builder: (context) { |
| 47 | return Stack( | 47 | return Stack( |
| 48 | + fit: StackFit.expand, | ||
| 48 | children: [ | 49 | children: [ |
| 49 | MobileScanner( | 50 | MobileScanner( |
| 50 | - fit: BoxFit.cover, | 51 | + fit: BoxFit.contain, |
| 51 | scanWindow: scanWindow, | 52 | scanWindow: scanWindow, |
| 52 | controller: controller, | 53 | controller: controller, |
| 53 | onDetect: onDetect, | 54 | onDetect: onDetect, |
-
Please register or login to post a comment