casvanluijtelaar

working android

@@ -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,