Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/rmet 2912/ use coroutines for bitmap work #11

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ The changes documented here do not include those from the original repository.

## [Unreleased]

### 13-12-2023
Android - Refactor - Use coroutines to work with bitmaps (https://outsystemsrd.atlassian.net/browse/RMET-2912)

### 06-12-2023
Android - Implement scanning only the frame area (Portrait, Landscape, Adaptive) (https://outsystemsrd.atlassian.net/browse/RMET-2912)

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>0.0.29</version>
<version>0.0.30</version>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ 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 kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.ByteArrayOutputStream
import java.lang.Exception
import java.nio.ByteBuffer
Expand Down Expand Up @@ -39,20 +42,22 @@ class OSBARCBarcodeAnalyzer(
* @param image - ImageProxy object that represents the image to be analyzed.
*/
override fun analyze(image: ImageProxy) {
try {
scanLibrary.scanBarcode(
image,
cropBitmap(imageProxyToBitmap(image)),
{
onBarcodeScanned(it)
},
{
onScanningError(it)
}
)
} catch (e: Exception) {
e.message?.let { Log.e(LOG_TAG, it) }
onScanningError(OSBARCError.SCANNING_GENERAL_ERROR)
CoroutineScope(Dispatchers.Default).launch {
try {
scanLibrary.scanBarcode(
image,
cropBitmap(imageProxyToBitmap(image)),
{
onBarcodeScanned(it)
},
{
onScanningError(it)
}
)
} catch (e: Exception) {
e.message?.let { Log.e(LOG_TAG, it) }
onScanningError(OSBARCError.SCANNING_GENERAL_ERROR)
}
}
}

Expand All @@ -67,7 +72,7 @@ class OSBARCBarcodeAnalyzer(
* - 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 {
private suspend fun imageProxyToBitmap(image: ImageProxy): Bitmap {

// get image data
val planes = image.planes
Expand Down Expand Up @@ -110,7 +115,7 @@ class OSBARCBarcodeAnalyzer(
* It uses different ratios depending on the orientation of the device - portrait or landscape.
* @param bitmap - Bitmap object to crop.
*/
private fun cropBitmap(bitmap: Bitmap): Bitmap {
private suspend fun cropBitmap(bitmap: Bitmap): Bitmap {
val rectWidth: Int
val rectHeight: Int

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class OSBARCMLKitWrapper(private val helper: OSBARCMLKitHelperInterface): OSBARC
* @param onSuccess - The code to be executed if the operation was successful.
* @param onError - The code to be executed if the operation was not successful.
*/
override fun scanBarcode(
override suspend fun scanBarcode(
imageProxy: ImageProxy,
imageBitmap: Bitmap,
onSuccess: (String) -> Unit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.outsystems.plugins.barcode.model.OSBARCError
* Interface that provides the signature of the scanBarcode method
*/
fun interface OSBARCScanLibraryInterface {
fun scanBarcode(
suspend fun scanBarcode(
imageProxy: ImageProxy,
imageBitmap: Bitmap,
onSuccess: (String) -> Unit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class OSBARCZXingWrapper(private val helper: OSBARCZXingHelperInterface) : OSBAR
* @param onSuccess - The code to be executed if the operation was successful.
* @param onError - The code to be executed if the operation was not successful.
*/
override fun scanBarcode(
override suspend fun scanBarcode(
imageProxy: ImageProxy,
imageBitmap: Bitmap,
onSuccess: (String) -> Unit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.outsystems.plugins.barcode.controller.helper

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

/**
* Helper class that implements the OSBARCImageHelperInterface
Expand All @@ -14,13 +16,14 @@ class OSBARCImageHelper: OSBARCImageHelperInterface {
* @param imageBytes - ByteArray to convert
* @return the resulting bitmap.
*/
override fun bitmapFromImageBytes(imageBytes: ByteArray): Bitmap {
return BitmapFactory.decodeByteArray(
imageBytes,
0, // use 0 in the offset to decode from the beginning of imageBytes
imageBytes.size // use byte array size as length because we want to decode the whole image
)
}
override suspend fun bitmapFromImageBytes(imageBytes: ByteArray): Bitmap =
withContext(Dispatchers.Default) {
return@withContext BitmapFactory.decodeByteArray(
imageBytes,
0, // use 0 in the offset to decode from the beginning of imageBytes
imageBytes.size // use byte array size as length because we want to decode the whole image
)
}

/**
* Creates a bitmap that is a subset of the source bitmap,
Expand All @@ -32,19 +35,21 @@ class OSBARCImageHelper: OSBARCImageHelperInterface {
* @param rectHeight - Height of the bitmap.
* @return the resulting bitmap.
*/
override fun createSubsetBitmapFromSource(
override suspend fun createSubsetBitmapFromSource(
source: Bitmap,
rectLeft: Int,
rectTop: Int,
rectWidth: Int,
rectHeight: Int
): Bitmap {
return Bitmap.createBitmap(
source,
rectLeft,
rectTop,
rectWidth,
rectHeight
)
}
): Bitmap =
withContext(Dispatchers.Default) {
return@withContext Bitmap.createBitmap(
source,
rectLeft,
rectTop,
rectWidth,
rectHeight
)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import android.graphics.Bitmap
* Interface that provides the signature of the type's methods.
*/
interface OSBARCImageHelperInterface {
fun bitmapFromImageBytes(imageBytes: ByteArray): Bitmap
fun createSubsetBitmapFromSource(
suspend fun bitmapFromImageBytes(imageBytes: ByteArray): Bitmap
suspend fun createSubsetBitmapFromSource(
source: Bitmap,
rectLeft: Int,
rectTop: Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import com.google.zxing.MultiFormatReader
import com.google.zxing.NotFoundException
import com.google.zxing.RGBLuminanceSource
import com.google.zxing.common.HybridBinarizer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

/**
* Helper class that implements the OSBARCZXingHelperInterface
Expand All @@ -27,22 +29,27 @@ class OSBARCZXingHelper: OSBARCZXingHelperInterface {
* @param rotationDegrees - degrees to rotate the image.
* @return the resulting bitmap.
*/
override fun rotateBitmap(bitmap: Bitmap, rotationDegrees: Int): Bitmap {
// create a matrix for rotation
val matrix = Matrix()
matrix.postRotate(rotationDegrees.toFloat())

// actually rotate the image
return Bitmap.createBitmap(
bitmap,
0, // 0 is the x coordinate of the first pixel in source bitmap
0, // 0 is the y coordinate of the first pixel in source bitmap
bitmap.width, // number of pixels in each row
bitmap.height, // number of rows
matrix, // matrix to be used for rotation
true // true states that source bitmap should be filtered using matrix (rotation)
)
}
override suspend fun rotateBitmap(bitmap: Bitmap, rotationDegrees: Int): Bitmap =
withContext(Dispatchers.Default) {
return@withContext try {
// create a matrix for rotation
val matrix = Matrix()
matrix.postRotate(rotationDegrees.toFloat())
// actually rotate the image
Bitmap.createBitmap(
bitmap,
0, // 0 is the x coordinate of the first pixel in source bitmap
0, // 0 is the y coordinate of the first pixel in source bitmap
bitmap.width, // number of pixels in each row
bitmap.height, // number of rows
matrix, // matrix to be used for rotation
true // true states that source bitmap should be filtered using matrix (rotation)
)
} finally {
// do nothing
// we need to use finally to avoid compilation error
}
}

/**
* Scans an image looking for barcodes, using the ZXing library.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import android.graphics.Bitmap
* Interface that provides the signature of the type's methods.
*/
interface OSBARCZXingHelperInterface {
fun rotateBitmap(bitmap: Bitmap, rotationDegrees: Int): Bitmap
suspend fun rotateBitmap(bitmap: Bitmap, rotationDegrees: Int): Bitmap
fun decodeImage(
pixels: IntArray,
width: Int,
Expand Down
Loading