Skip to content

Commit

Permalink
Merge pull request #27 from OutSystems/fix/RMET-3399/improve-code-rea…
Browse files Browse the repository at this point in the history
…dability

RMET-3399 OSBarcodeLib-Android - Improve code readability by using higher resolution
  • Loading branch information
alexgerardojacinto committed Apr 30, 2024
2 parents f9a80ad + 1e83d89 commit ffde556
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 64 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = "1.6.20"
ext.kotlin_version = "1.9.21"
ext.jacocoVersion = '0.8.7'
repositories {
google()
Expand Down Expand Up @@ -78,7 +78,7 @@ android {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion '1.2.0-alpha08'
kotlinCompilerExtensionVersion '1.5.7'
}

packaging {
Expand Down Expand Up @@ -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'
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.outsystems</groupId>
<artifactId>osbarcode-android</artifactId>
<version>1.1.0</version>
<version>1.1.1</version>
</project>
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
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
import com.outsystems.plugins.barcode.controller.helper.OSBARCImageHelperInterface
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,
Expand Down Expand Up @@ -42,7 +37,7 @@ class OSBARCBarcodeAnalyzer(
try {
scanLibrary.scanBarcode(
image,
cropBitmap(imageProxyToBitmap(image)),
cropBitmap(image.toBitmap()),
{
onBarcodeScanned(it)
},
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ class ScanCodeTests {
success = true
resultCode = RESULT_CODE
}
Mockito.doReturn(mockBitmap).`when`(mockImageProxy).toBitmap()
OSBARCBarcodeAnalyzer(
scanLibMock,
imageHelperMock,
Expand Down Expand Up @@ -327,6 +328,7 @@ class ScanCodeTests {
exception = false
error = OSBARCError.ZXING_LIBRARY_ERROR
}
Mockito.doReturn(mockBitmap).`when`(mockImageProxy).toBitmap()
OSBARCBarcodeAnalyzer(
scanLibMock,
imageHelperMock,
Expand All @@ -347,6 +349,7 @@ class ScanCodeTests {
exception = false
error = OSBARCError.MLKIT_LIBRARY_ERROR
}
Mockito.doReturn(mockBitmap).`when`(mockImageProxy).toBitmap()
OSBARCBarcodeAnalyzer(
scanLibMock,
imageHelperMock,
Expand Down Expand Up @@ -386,6 +389,7 @@ class ScanCodeTests {
success = true
resultCode = RESULT_CODE
}
Mockito.doReturn(mockBitmap).`when`(mockImageProxy).toBitmap()
OSBARCBarcodeAnalyzer(
scanLibMock,
imageHelperMock,
Expand All @@ -406,6 +410,7 @@ class ScanCodeTests {
success = true
resultCode = RESULT_CODE
}
Mockito.doReturn(mockBitmap).`when`(mockImageProxy).toBitmap()
OSBARCBarcodeAnalyzer(
scanLibMock,
imageHelperMock,
Expand Down

0 comments on commit ffde556

Please sign in to comment.