From 53220410ed3a3b6e995c12e8abca4fd8d732f3cd Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Mon, 29 Apr 2024 17:12:26 +0100 Subject: [PATCH 1/9] fix: set resolution to a higher one References: https://outsystemsrd.atlassian.net/browse/RMET-3399 --- build.gradle | 8 +++++--- pom.xml | 2 +- .../barcode/controller/helper/OSBARCZXingHelper.kt | 2 +- .../plugins/barcode/view/OSBARCScannerActivity.kt | 1 + 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 5e4ffee..f924f2e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = "1.6.20" + ext.kotlin_version = "1.8.0" ext.jacocoVersion = '0.8.7' repositories { google() @@ -78,7 +78,9 @@ android { compose true } composeOptions { - kotlinCompilerExtensionVersion '1.2.0-alpha08' + //kotlinCompilerExtensionVersion '1.2.0-alpha08' + //kotlinCompilerExtensionVersion '1.5.7' + kotlinCompilerExtensionVersion '1.4.0' } packaging { @@ -115,7 +117,7 @@ dependencies { androidTestImplementation "androidx.compose.ui:ui-test-junit4:1.0.5" debugImplementation "androidx.compose.ui:ui-tooling:1.0.5" - implementation "androidx.camera:camera-camera2:1.0.2" + implementation "androidx.camera:camera-camera2:1.3.0" implementation 'androidx.camera:camera-lifecycle:1.0.2' implementation 'androidx.camera:camera-view:1.0.0-alpha31' implementation 'androidx.camera:camera-core:1.0.0' diff --git a/pom.xml b/pom.xml index 232bc36..affd120 100644 --- a/pom.xml +++ b/pom.xml @@ -7,5 +7,5 @@ 4.0.0 com.github.outsystems osbarcode-android - 1.1.0 + 1.1.0.1 diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt b/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt index 0a095d3..99ccd58 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt @@ -64,7 +64,7 @@ class OSBARCZXingHelper: OSBARCZXingHelperInterface { DecodeHintType.TRY_HARDER to arrayListOf(true) ) ) - }.decode(binaryBitmap) + }.decodeWithState(binaryBitmap) onSuccess(result.text) } catch (e: NotFoundException) { // keep trying, no barcode was found in this camera frame diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt index b4bff6e..334eb45 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -289,6 +289,7 @@ class OSBARCScannerActivity : ComponentActivity() { val preview = Preview.Builder().build() preview.setSurfaceProvider(previewView.surfaceProvider) val imageAnalysis = ImageAnalysis.Builder() + .setTargetResolution(android.util.Size(1920, 1080)) .setBackpressureStrategy(STRATEGY_KEEP_ONLY_LATEST) .build() imageAnalysis.setAnalyzer( From ac4f059620af4473e7eb806613228e81d1edb401 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Mon, 29 Apr 2024 17:34:08 +0100 Subject: [PATCH 2/9] fix: set kotlin version and compose version for MABS 10 Context: In order to use version 1.3.0 of the CameraX Library, we need to use at least version 1.4.0 of the Compose Compiler. But to build with MABS 10, we need to use version 1.5.7 of the compose compiler. References: https://outsystemsrd.atlassian.net/browse/RMET-3399 --- build.gradle | 5 ++--- pom.xml | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index f924f2e..ca37820 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = "1.8.0" + ext.kotlin_version = "1.9.21" ext.jacocoVersion = '0.8.7' repositories { google() @@ -79,8 +79,7 @@ android { } composeOptions { //kotlinCompilerExtensionVersion '1.2.0-alpha08' - //kotlinCompilerExtensionVersion '1.5.7' - kotlinCompilerExtensionVersion '1.4.0' + kotlinCompilerExtensionVersion '1.5.7' } packaging { diff --git a/pom.xml b/pom.xml index affd120..d3e901e 100644 --- a/pom.xml +++ b/pom.xml @@ -7,5 +7,5 @@ 4.0.0 com.github.outsystems osbarcode-android - 1.1.0.1 + 1.1.0.2 From c11f1eb0744845d9aa9e7bdeffa5931d22ae0e07 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Mon, 29 Apr 2024 19:41:59 +0100 Subject: [PATCH 3/9] fix: use updated way of setting resolution References: https://outsystemsrd.atlassian.net/browse/RMET-3399 --- .../plugins/barcode/view/OSBARCScannerActivity.kt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt index 334eb45..e81570c 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -23,6 +23,8 @@ import androidx.camera.core.CameraSelector import androidx.camera.core.ImageAnalysis import androidx.camera.core.ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST import androidx.camera.core.Preview +import androidx.camera.core.resolutionselector.ResolutionSelector +import androidx.camera.core.resolutionselector.ResolutionStrategy import androidx.camera.lifecycle.ProcessCameraProvider import androidx.camera.view.PreviewView import androidx.compose.foundation.BorderStroke @@ -288,8 +290,16 @@ class OSBARCScannerActivity : ComponentActivity() { val previewView = PreviewView(context) val preview = Preview.Builder().build() preview.setSurfaceProvider(previewView.surfaceProvider) + + val resolutionSelector = ResolutionSelector.Builder().setResolutionStrategy( + ResolutionStrategy(android.util.Size(1920, 1080), + ResolutionStrategy.FALLBACK_RULE_NONE) + ).build() + val imageAnalysis = ImageAnalysis.Builder() - .setTargetResolution(android.util.Size(1920, 1080)) + //.setTargetResolution(android.util.Size(1920, 1080)) + //.setTargetResolution(android.util.Size(1280, 720)) + .setResolutionSelector(resolutionSelector) .setBackpressureStrategy(STRATEGY_KEEP_ONLY_LATEST) .build() imageAnalysis.setAnalyzer( From 616fe024991c525f68c71f73156fb3f697e9fa5b Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 30 Apr 2024 10:19:27 +0100 Subject: [PATCH 4/9] fix: remove TRY_HARDER parameter Context: After testing in multiple devices, this only resulted in slower readings rather than better results. References: https://outsystemsrd.atlassian.net/browse/RMET-3399 --- .../barcode/controller/helper/OSBARCZXingHelper.kt | 8 +------- .../plugins/barcode/view/OSBARCScannerActivity.kt | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt b/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt index 99ccd58..2ed199d 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt @@ -58,13 +58,7 @@ class OSBARCZXingHelper: OSBARCZXingHelperInterface { try { val source = RGBLuminanceSource(width, height, pixels) val binaryBitmap = BinaryBitmap(HybridBinarizer(source)) - val result = MultiFormatReader().apply { - setHints( - mapOf( - DecodeHintType.TRY_HARDER to arrayListOf(true) - ) - ) - }.decodeWithState(binaryBitmap) + val result = MultiFormatReader().decodeWithState(binaryBitmap) onSuccess(result.text) } catch (e: NotFoundException) { // keep trying, no barcode was found in this camera frame diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt index e81570c..7bcc9e2 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -297,8 +297,6 @@ class OSBARCScannerActivity : ComponentActivity() { ).build() val imageAnalysis = ImageAnalysis.Builder() - //.setTargetResolution(android.util.Size(1920, 1080)) - //.setTargetResolution(android.util.Size(1280, 720)) .setResolutionSelector(resolutionSelector) .setBackpressureStrategy(STRATEGY_KEEP_ONLY_LATEST) .build() From ede5289eeaad8602530c46bc8f8c64fbeb286f4c Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 30 Apr 2024 12:06:33 +0100 Subject: [PATCH 5/9] feat: use CameraX method to convert image to bitmap Context: As we'll be able to use version 1.3.0 of the CameraX library, we can now use this the ImageProxy.toBitmap() method instead of using our own method. References: https://outsystemsrd.atlassian.net/browse/RMET-3399 --- .../controller/OSBARCBarcodeAnalyzer.kt | 48 +------------------ 1 file changed, 1 insertion(+), 47 deletions(-) diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCBarcodeAnalyzer.kt b/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCBarcodeAnalyzer.kt index 02b99b0..3fce011 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCBarcodeAnalyzer.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCBarcodeAnalyzer.kt @@ -42,7 +42,7 @@ class OSBARCBarcodeAnalyzer( try { scanLibrary.scanBarcode( image, - cropBitmap(imageProxyToBitmap(image)), + cropBitmap(image.toBitmap()), { onBarcodeScanned(it) }, @@ -57,52 +57,6 @@ class OSBARCBarcodeAnalyzer( image.close() } - /** - * Converts an ImageProxy object to a Bitmap. - * Once we can compile this library with Kotlin 1.9.10, and consequently - * can use version 1.5.3 of the Compose Compiler, this method is unnecessary, - * since we will be able to use version 1.3.0 of the CameraX library - * and obtain the bitmap directly from the ImageProxy, using ImageProxy.toBitmap. - * More info: - * - https://developer.android.com/jetpack/androidx/releases/compose-kotlin - * - https://developer.android.com/jetpack/androidx/releases/camera#1.3.0 - * @param image - ImageProxy object that represents the image to be analyzed. - */ - private fun imageProxyToBitmap(image: ImageProxy): Bitmap { - - // get image data - val planes = image.planes - val yBuffer: ByteBuffer = planes[0].buffer - val uBuffer: ByteBuffer = planes[1].buffer - val vBuffer: ByteBuffer = planes[2].buffer - - // get image width and height - val imageWidth = image.width - val imageHeight = image.height - - // calculate image data size - val ySize = yBuffer.remaining() - val uSize = uBuffer.remaining() - val vSize = vBuffer.remaining() - - // use byte arrays for image data - val data = ByteArray(ySize + uSize + vSize) - yBuffer.get(data, 0, ySize) - uBuffer.get(data, ySize, uSize) - vBuffer.get(data, ySize + uSize, vSize) - - // create a YUV image - // ImageFormat.NV21 used because it's efficient and widely supported - val yuvImage = YuvImage(data, ImageFormat.NV21, imageWidth, imageHeight, null) - - // convert YUV to Bitmap - val out = ByteArrayOutputStream() - yuvImage.compressToJpeg(Rect(0, 0, imageWidth, imageHeight), 100, out) - val imageBytes = out.toByteArray() - return imageHelper.bitmapFromImageBytes(imageBytes) - } - - /** * Creates a cropped bitmap for the region of interest to scan, * where the cropped image is approximately the same size as the frame From 3539a5c939ac8f1148d6749573cdcd5ec513e2a6 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 30 Apr 2024 12:07:56 +0100 Subject: [PATCH 6/9] feat: set fallback rule for resolution Context: We're requesting a resolution of 1920x1080 for the frames that will be scanned. If this resolution isn't available on the device, we set the fallback to the closest highest resolution. If that also isn't available, then it will fallback to the closest lower resolution. References: https://outsystemsrd.atlassian.net/browse/RMET-3399 --- .../outsystems/plugins/barcode/view/OSBARCScannerActivity.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt index 7bcc9e2..d420a92 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -292,10 +292,9 @@ class OSBARCScannerActivity : ComponentActivity() { preview.setSurfaceProvider(previewView.surfaceProvider) val resolutionSelector = ResolutionSelector.Builder().setResolutionStrategy( - ResolutionStrategy(android.util.Size(1920, 1080), - ResolutionStrategy.FALLBACK_RULE_NONE) + ResolutionStrategy(android.util.Size(1920, 1080), // high resolution for optimal scanning + ResolutionStrategy.FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER) ).build() - val imageAnalysis = ImageAnalysis.Builder() .setResolutionSelector(resolutionSelector) .setBackpressureStrategy(STRATEGY_KEEP_ONLY_LATEST) From 4f9a006d42a0b26a1acedfafb657b92238314eea Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 30 Apr 2024 12:25:25 +0100 Subject: [PATCH 7/9] refactor: update unit tests according to changes References: https://outsystemsrd.atlassian.net/browse/RMET-3399 --- pom.xml | 2 +- .../plugins/barcode/controller/OSBARCBarcodeAnalyzer.kt | 5 ----- .../plugins/barcode/controller/helper/OSBARCZXingHelper.kt | 1 - .../kotlin/com/outsystems/plugins/barcode/ScanCodeTests.kt | 5 +++++ 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index d3e901e..65c0baa 100644 --- a/pom.xml +++ b/pom.xml @@ -7,5 +7,5 @@ 4.0.0 com.github.outsystems osbarcode-android - 1.1.0.2 + 1.1.0.3 diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCBarcodeAnalyzer.kt b/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCBarcodeAnalyzer.kt index 3fce011..f238a1b 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCBarcodeAnalyzer.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCBarcodeAnalyzer.kt @@ -1,9 +1,6 @@ package com.outsystems.plugins.barcode.controller import android.graphics.Bitmap -import android.graphics.ImageFormat -import android.graphics.Rect -import android.graphics.YuvImage import android.util.Log import androidx.camera.core.ImageAnalysis import androidx.camera.core.ImageProxy @@ -11,9 +8,7 @@ import com.outsystems.plugins.barcode.controller.helper.OSBARCImageHelperInterfa import com.outsystems.plugins.barcode.model.OSBARCError import com.outsystems.plugins.barcode.view.ui.theme.SizeRatioHeight import com.outsystems.plugins.barcode.view.ui.theme.SizeRatioWidth -import java.io.ByteArrayOutputStream import java.lang.Exception -import java.nio.ByteBuffer /** * This class is responsible for implementing the ImageAnalysis.Analyzer interface, diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt b/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt index 2ed199d..f95e38e 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt @@ -4,7 +4,6 @@ import android.graphics.Bitmap import android.graphics.Matrix import android.util.Log import com.google.zxing.BinaryBitmap -import com.google.zxing.DecodeHintType import com.google.zxing.MultiFormatReader import com.google.zxing.NotFoundException import com.google.zxing.RGBLuminanceSource diff --git a/src/test/kotlin/com/outsystems/plugins/barcode/ScanCodeTests.kt b/src/test/kotlin/com/outsystems/plugins/barcode/ScanCodeTests.kt index 7a69b3a..2fd2aec 100644 --- a/src/test/kotlin/com/outsystems/plugins/barcode/ScanCodeTests.kt +++ b/src/test/kotlin/com/outsystems/plugins/barcode/ScanCodeTests.kt @@ -287,6 +287,7 @@ class ScanCodeTests { success = true resultCode = RESULT_CODE } + Mockito.doReturn(mockBitmap).`when`(mockImageProxy).toBitmap() OSBARCBarcodeAnalyzer( scanLibMock, imageHelperMock, @@ -327,6 +328,7 @@ class ScanCodeTests { exception = false error = OSBARCError.ZXING_LIBRARY_ERROR } + Mockito.doReturn(mockBitmap).`when`(mockImageProxy).toBitmap() OSBARCBarcodeAnalyzer( scanLibMock, imageHelperMock, @@ -347,6 +349,7 @@ class ScanCodeTests { exception = false error = OSBARCError.MLKIT_LIBRARY_ERROR } + Mockito.doReturn(mockBitmap).`when`(mockImageProxy).toBitmap() OSBARCBarcodeAnalyzer( scanLibMock, imageHelperMock, @@ -386,6 +389,7 @@ class ScanCodeTests { success = true resultCode = RESULT_CODE } + Mockito.doReturn(mockBitmap).`when`(mockImageProxy).toBitmap() OSBARCBarcodeAnalyzer( scanLibMock, imageHelperMock, @@ -406,6 +410,7 @@ class ScanCodeTests { success = true resultCode = RESULT_CODE } + Mockito.doReturn(mockBitmap).`when`(mockImageProxy).toBitmap() OSBARCBarcodeAnalyzer( scanLibMock, imageHelperMock, From 97865f3a5d7d4626ff6172046864cc64f13213db Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 30 Apr 2024 13:57:07 +0100 Subject: [PATCH 8/9] chore: remove commented line References: https://outsystemsrd.atlassian.net/browse/RMET-3399 --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index ca37820..7afca49 100644 --- a/build.gradle +++ b/build.gradle @@ -78,7 +78,6 @@ android { compose true } composeOptions { - //kotlinCompilerExtensionVersion '1.2.0-alpha08' kotlinCompilerExtensionVersion '1.5.7' } From 1e83d8910441ef592d36b8ee85375a34afcb902a Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 30 Apr 2024 14:13:29 +0100 Subject: [PATCH 9/9] chore: update changelog References: https://outsystemsrd.atlassian.net/browse/RMET-3399 --- CHANGELOG.md | 5 +++++ pom.xml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d492bb..6d90dd9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 The changes documented here do not include those from the original repository. +## [1.1.1] + +### 30-04-2024 +- Fix: Improve scanning by using higher resolution frames (https://outsystemsrd.atlassian.net/browse/RMET-3399). + ## [1.1.0] ### 26-03-2024 diff --git a/pom.xml b/pom.xml index 65c0baa..c1b4b98 100644 --- a/pom.xml +++ b/pom.xml @@ -7,5 +7,5 @@ 4.0.0 com.github.outsystems osbarcode-android - 1.1.0.3 + 1.1.1