Skip to content

Commit 6079b7f

Browse files
committed
implemented AutoZoom feature for Android
1 parent 8e983f1 commit 6079b7f

File tree

6 files changed

+79
-16
lines changed

6 files changed

+79
-16
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ See the example app for detailed implementation information.
3838
| analyzeImage (Gallery) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
3939
| returnImage | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
4040
| scanWindow | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
41+
| autoZoom | :heavy_check_mark: | :x: | :x: | :x: |
4142

4243
## Platform Support
4344

android/src/main/kotlin/dev/steenbakker/mobile_scanner/MobileScanner.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,11 @@ class MobileScanner(
499499
camera?.cameraControl?.setLinearZoom(scale.toFloat())
500500
}
501501

502+
fun setZoomRatio(zoomRatio: Double) {
503+
if (camera == null) throw ZoomWhenStopped()
504+
camera?.cameraControl?.setZoomRatio(zoomRatio.toFloat())
505+
}
506+
502507
/**
503508
* Reset the zoom rate of the camera.
504509
*/

android/src/main/kotlin/dev/steenbakker/mobile_scanner/MobileScannerHandler.kt

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package dev.steenbakker.mobile_scanner
22

33
import android.app.Activity
4+
import android.content.Context
5+
import android.hardware.camera2.CameraCharacteristics
6+
import android.hardware.camera2.CameraManager
47
import android.net.Uri
58
import android.os.Handler
69
import android.os.Looper
@@ -18,6 +21,7 @@ import io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener
1821
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
1922
import io.flutter.view.TextureRegistry
2023
import java.io.File
24+
import com.google.mlkit.vision.barcode.ZoomSuggestionOptions
2125

2226
class MobileScannerHandler(
2327
private val activity: Activity,
@@ -138,13 +142,14 @@ class MobileScannerHandler(
138142
val timeout: Int = call.argument<Int>("timeout") ?: 250
139143
val cameraResolutionValues: List<Int>? = call.argument<List<Int>>("cameraResolution")
140144
val useNewCameraSelector: Boolean = call.argument<Boolean>("useNewCameraSelector") ?: false
145+
val enableAutoZoom: Boolean = call.argument<Boolean>("autoZoom") ?: false
141146
val cameraResolution: Size? = if (cameraResolutionValues != null) {
142147
Size(cameraResolutionValues[0], cameraResolutionValues[1])
143148
} else {
144149
null
145150
}
146151

147-
val barcodeScannerOptions: BarcodeScannerOptions? = buildBarcodeScannerOptions(formats)
152+
val barcodeScannerOptions: BarcodeScannerOptions? = buildBarcodeScannerOptions(formats, enableAutoZoom)
148153

149154
val position =
150155
if (facing == 0) CameraSelector.DEFAULT_FRONT_CAMERA else CameraSelector.DEFAULT_BACK_CAMERA
@@ -230,7 +235,7 @@ class MobileScannerHandler(
230235

231236
mobileScanner!!.analyzeImage(
232237
Uri.fromFile(File(filePath)),
233-
buildBarcodeScannerOptions(formats),
238+
buildBarcodeScannerOptions(formats, false),
234239
analyzeImageSuccessCallback,
235240
analyzeImageErrorCallback)
236241
}
@@ -253,6 +258,14 @@ class MobileScannerHandler(
253258
}
254259
}
255260

261+
private fun setZoomRatio(scale: Float) : Boolean {
262+
try {
263+
mobileScanner!!.setZoomRatio(scale.toDouble())
264+
return true
265+
} catch (e: ZoomWhenStopped) { }
266+
return false
267+
}
268+
256269
private fun resetScale(result: MethodChannel.Result) {
257270
try {
258271
mobileScanner!!.resetScale()
@@ -269,25 +282,54 @@ class MobileScannerHandler(
269282
result.success(null)
270283
}
271284

272-
private fun buildBarcodeScannerOptions(formats: List<Int>?): BarcodeScannerOptions? {
285+
private fun buildBarcodeScannerOptions(formats: List<Int>?, enableAutoZoom: Boolean): BarcodeScannerOptions? {
286+
val builder : BarcodeScannerOptions.Builder?
273287
if (formats == null) {
274-
return null
288+
builder = BarcodeScannerOptions.Builder()
289+
} else {
290+
val formatsList: MutableList<Int> = mutableListOf()
291+
292+
for (formatValue in formats) {
293+
formatsList.add(BarcodeFormats.fromRawValue(formatValue).intValue)
294+
}
295+
296+
if (formatsList.size == 1) {
297+
builder = BarcodeScannerOptions.Builder().setBarcodeFormats(formatsList.first())
298+
} else {
299+
builder = BarcodeScannerOptions.Builder().setBarcodeFormats(
300+
formatsList.first(),
301+
*formatsList.subList(1, formatsList.size).toIntArray()
302+
)
303+
}
275304
}
276305

277-
val formatsList: MutableList<Int> = mutableListOf()
278-
279-
for (formatValue in formats) {
280-
formatsList.add(BarcodeFormats.fromRawValue(formatValue).intValue)
306+
if (enableAutoZoom) {
307+
builder.setZoomSuggestionOptions(
308+
ZoomSuggestionOptions.Builder {
309+
setZoomRatio(it)
310+
}.setMaxSupportedZoomRatio(getMaxZoomRatio())
311+
.build())
281312
}
282313

283-
if (formatsList.size == 1) {
284-
return BarcodeScannerOptions.Builder().setBarcodeFormats(formatsList.first())
285-
.build()
286-
}
314+
return builder.build()
315+
}
316+
317+
private fun getMaxZoomRatio(): Float {
318+
val cameraManager = activity.getSystemService(Context.CAMERA_SERVICE) as CameraManager
319+
var maxZoom = 1.0F
320+
321+
try {
322+
for (cameraId in cameraManager.cameraIdList) {
323+
val characteristics = cameraManager.getCameraCharacteristics(cameraId)
287324

288-
return BarcodeScannerOptions.Builder().setBarcodeFormats(
289-
formatsList.first(),
290-
*formatsList.subList(1, formatsList.size).toIntArray()
291-
).build()
325+
val maxZoomRatio = characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM)
326+
if (maxZoomRatio != null && maxZoomRatio > maxZoom) {
327+
maxZoom = maxZoomRatio
328+
}
329+
}
330+
} catch (e: Exception) {
331+
e.printStackTrace()
332+
}
333+
return maxZoom
292334
}
293335
}

example/lib/barcode_scanner_controller.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class _BarcodeScannerWithControllerState
1919
autoStart: false,
2020
torchEnabled: true,
2121
useNewCameraSelector: true,
22+
enableAutoZoom: true
2223
);
2324

2425
Barcode? _barcode;

lib/src/mobile_scanner_controller.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class MobileScannerController extends ValueNotifier<MobileScannerState> {
2626
this.returnImage = false,
2727
this.torchEnabled = false,
2828
this.useNewCameraSelector = false,
29+
this.enableAutoZoom = false
2930
}) : detectionTimeoutMs =
3031
detectionSpeed == DetectionSpeed.normal ? detectionTimeoutMs : 0,
3132
assert(
@@ -96,6 +97,11 @@ class MobileScannerController extends ValueNotifier<MobileScannerState> {
9697
/// Only supported on Android.
9798
final bool useNewCameraSelector;
9899

100+
/// Whether the Camera should auto zoom.
101+
///
102+
/// Only supported on Android.
103+
final bool enableAutoZoom;
104+
99105
/// The internal barcode controller, that listens for detected barcodes.
100106
final StreamController<BarcodeCapture> _barcodesController =
101107
StreamController.broadcast();
@@ -283,6 +289,7 @@ class MobileScannerController extends ValueNotifier<MobileScannerState> {
283289
returnImage: returnImage,
284290
torchEnabled: torchEnabled,
285291
useNewCameraSelector: useNewCameraSelector,
292+
enableAutoZoom: enableAutoZoom
286293
);
287294

288295
try {

lib/src/objects/start_options.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class StartOptions {
1515
required this.returnImage,
1616
required this.torchEnabled,
1717
required this.useNewCameraSelector,
18+
required this.enableAutoZoom
1819
});
1920

2021
/// The direction for the camera.
@@ -43,6 +44,11 @@ class StartOptions {
4344
/// This option is only supported on Android. Other platforms will ignore this option.
4445
final bool useNewCameraSelector;
4546

47+
/// Whether the Camera should auto zoom.
48+
///
49+
/// This option is only supported on Android. Other platforms will ignore this option.
50+
final bool enableAutoZoom;
51+
4652
Map<String, Object?> toMap() {
4753
return <String, Object?>{
4854
if (cameraResolution != null)
@@ -58,6 +64,7 @@ class StartOptions {
5864
'timeout': detectionTimeoutMs,
5965
'torch': torchEnabled,
6066
'useNewCameraSelector': useNewCameraSelector,
67+
'autoZoom' : enableAutoZoom
6168
};
6269
}
6370
}

0 commit comments

Comments
 (0)