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/build.gradle b/build.gradle index 5e4ffee..7afca49 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = "1.6.20" + ext.kotlin_version = "1.9.21" ext.jacocoVersion = '0.8.7' repositories { google() @@ -78,7 +78,7 @@ android { compose true } composeOptions { - kotlinCompilerExtensionVersion '1.2.0-alpha08' + kotlinCompilerExtensionVersion '1.5.7' } packaging { @@ -115,7 +115,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..c1b4b98 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 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..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, @@ -42,7 +37,7 @@ class OSBARCBarcodeAnalyzer( try { scanLibrary.scanBarcode( image, - cropBitmap(imageProxyToBitmap(image)), + cropBitmap(image.toBitmap()), { onBarcodeScanned(it) }, @@ -57,52 +52,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 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..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 @@ -58,13 +57,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) - ) - ) - }.decode(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 b4bff6e..d420a92 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,7 +290,13 @@ 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), // high resolution for optimal scanning + ResolutionStrategy.FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER) + ).build() val imageAnalysis = ImageAnalysis.Builder() + .setResolutionSelector(resolutionSelector) .setBackpressureStrategy(STRATEGY_KEEP_ONLY_LATEST) .build() imageAnalysis.setAnalyzer( 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,