diff --git a/example/lib/barcode_list_scanner_controller.dart b/example/lib/barcode_list_scanner_controller.dart index e8c81ec5e5cc402589c29f2f7488e4bb4b0a7f12..30c5a1b1c2db2288b8f4a01937e68a3217675c5d 100644 --- a/example/lib/barcode_list_scanner_controller.dart +++ b/example/lib/barcode_list_scanner_controller.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; @@ -126,21 +127,24 @@ class _BarcodeListScannerWithControllerState ), ), ), - IconButton( - color: Colors.white, - icon: ValueListenableBuilder( - valueListenable: controller.cameraFacingState, - builder: (context, state, child) { - switch (state) { - case CameraFacing.front: - return const Icon(Icons.camera_front); - case CameraFacing.back: - return const Icon(Icons.camera_rear); - } - }, + Visibility( + visible: defaultTargetPlatform != TargetPlatform.ohos, + child: IconButton( + color: Colors.white, + icon: ValueListenableBuilder( + valueListenable: controller.cameraFacingState, + builder: (context, state, child) { + switch (state) { + case CameraFacing.front: + return const Icon(Icons.camera_front); + case CameraFacing.back: + return const Icon(Icons.camera_rear); + } + }, + ), + iconSize: 32.0, + onPressed: () => controller.switchCamera(), ), - iconSize: 32.0, - onPressed: () => controller.switchCamera(), ), IconButton( color: Colors.white, diff --git a/example/lib/barcode_scanner_controller.dart b/example/lib/barcode_scanner_controller.dart index 9e1221d211ef2b0e689cfd596f5ae1a783159dbf..a9d0dcf43b0c878cdd77ab3816e86163ea0195d9 100644 --- a/example/lib/barcode_scanner_controller.dart +++ b/example/lib/barcode_scanner_controller.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; @@ -140,23 +141,26 @@ class _BarcodeScannerWithControllerState ), ), ), - IconButton( - color: Colors.white, - icon: ValueListenableBuilder( - valueListenable: controller.cameraFacingState, - builder: (context, state, child) { - switch (state) { - case CameraFacing.front: - return const Icon(Icons.camera_front); - case CameraFacing.back: - return const Icon(Icons.camera_rear); - } - }, + Visibility( + visible: defaultTargetPlatform != TargetPlatform.ohos, + child: IconButton( + color: Colors.white, + icon: ValueListenableBuilder( + valueListenable: controller.cameraFacingState, + builder: (context, state, child) { + switch (state) { + case CameraFacing.front: + return const Icon(Icons.camera_front); + case CameraFacing.back: + return const Icon(Icons.camera_rear); + } + }, + ), + iconSize: 32.0, + onPressed: (numberOfCameras ?? 0) < 2 + ? null + : () => controller.switchCamera(), ), - iconSize: 32.0, - onPressed: (numberOfCameras ?? 0) < 2 - ? null - : () => controller.switchCamera(), ), IconButton( color: Colors.white, diff --git a/example/lib/barcode_scanner_returning_image.dart b/example/lib/barcode_scanner_returning_image.dart index 15c1912a4a76f24217e06d6f0c698b8346a18f90..8faba0eaaf1b3a2a93c703f1f2aff6c5b5fecf9a 100644 --- a/example/lib/barcode_scanner_returning_image.dart +++ b/example/lib/barcode_scanner_returning_image.dart @@ -1,5 +1,6 @@ import 'dart:math'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:mobile_scanner_example/scanner_error_widget.dart'; @@ -146,21 +147,24 @@ class _BarcodeScannerReturningImageState ), ), ), - IconButton( - color: Colors.white, - icon: ValueListenableBuilder( - valueListenable: controller.cameraFacingState, - builder: (context, state, child) { - switch (state) { - case CameraFacing.front: - return const Icon(Icons.camera_front); - case CameraFacing.back: - return const Icon(Icons.camera_rear); - } - }, + Visibility( + visible: defaultTargetPlatform != TargetPlatform.ohos, + child: IconButton( + color: Colors.white, + icon: ValueListenableBuilder( + valueListenable: controller.cameraFacingState, + builder: (context, state, child) { + switch (state) { + case CameraFacing.front: + return const Icon(Icons.camera_front); + case CameraFacing.back: + return const Icon(Icons.camera_rear); + } + }, + ), + iconSize: 32.0, + onPressed: () => controller.switchCamera(), ), - iconSize: 32.0, - onPressed: () => controller.switchCamera(), ), ], ), diff --git a/example/lib/barcode_scanner_window.dart b/example/lib/barcode_scanner_window.dart index 974ff50537ed8e313be27fbf1b636092861bc164..d8669090bcd0bf37f7af925d7390e7f54b1cffe2 100644 --- a/example/lib/barcode_scanner_window.dart +++ b/example/lib/barcode_scanner_window.dart @@ -160,7 +160,7 @@ class BarcodeOverlay extends CustomPainter { double verticalPadding = size.height - adjustedSize.destination.height; double horizontalPadding = size.width - adjustedSize.destination.width; if (verticalPadding > 0) { - verticalPadding = verticalPadding / 2; + verticalPadding = defaultTargetPlatform == TargetPlatform.ohos ? ((verticalPadding - 130) / 2) : verticalPadding / 2; } else { verticalPadding = 0; } diff --git a/example/lib/barcode_scanner_zoom.dart b/example/lib/barcode_scanner_zoom.dart index b6986fec365230518f6ca3e8504a01119f812685..5823cbfb95a0de83dc5a5b2d0d10c7db5294743c 100644 --- a/example/lib/barcode_scanner_zoom.dart +++ b/example/lib/barcode_scanner_zoom.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; @@ -20,7 +21,7 @@ class _BarcodeScannerWithZoomState extends State ); bool isStarted = true; - double _zoomFactor = 0.0; + double _zoomFactor = defaultTargetPlatform == TargetPlatform.ohos ? 10 : 0.0; @override Widget build(BuildContext context) { @@ -72,7 +73,12 @@ class _BarcodeScannerWithZoomState extends State onChanged: (value) { setState(() { _zoomFactor = value; - controller.setZoomScale(value); + if (defaultTargetPlatform == + TargetPlatform.ohos) { + controller.setZoomScale(value / 10); + } else { + controller.setZoomScale(value); + } }); }, ), @@ -143,21 +149,24 @@ class _BarcodeScannerWithZoomState extends State ), ), ), - IconButton( - color: Colors.white, - icon: ValueListenableBuilder( - valueListenable: controller.cameraFacingState, - builder: (context, state, child) { - switch (state) { - case CameraFacing.front: - return const Icon(Icons.camera_front); - case CameraFacing.back: - return const Icon(Icons.camera_rear); - } - }, + Visibility( + visible: defaultTargetPlatform != TargetPlatform.ohos, + child: IconButton( + color: Colors.white, + icon: ValueListenableBuilder( + valueListenable: controller.cameraFacingState, + builder: (context, state, child) { + switch (state) { + case CameraFacing.front: + return const Icon(Icons.camera_front); + case CameraFacing.back: + return const Icon(Icons.camera_rear); + } + }, + ), + iconSize: 32.0, + onPressed: () => controller.switchCamera(), ), - iconSize: 32.0, - onPressed: () => controller.switchCamera(), ), IconButton( color: Colors.white, diff --git a/example/lib/mobile_scanner_overlay.dart b/example/lib/mobile_scanner_overlay.dart index ced7e439485a084e6b17dcf504b74654bba0efaa..a5ed02e8249f12b93bb5577374a0d54a82a8abcf 100644 --- a/example/lib/mobile_scanner_overlay.dart +++ b/example/lib/mobile_scanner_overlay.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:mobile_scanner_example/scanner_error_widget.dart'; @@ -140,11 +141,15 @@ class _BarcodeScannerWithOverlayState extends State { ); }, ), - IconButton( - onPressed: () => controller.switchCamera(), - icon: const Icon( - Icons.cameraswitch_rounded, - color: Colors.white, + Visibility( + visible: defaultTargetPlatform != + TargetPlatform.ohos, + child: IconButton( + onPressed: () => controller.switchCamera(), + icon: const Icon( + Icons.cameraswitch_rounded, + color: Colors.white, + ), ), ), ], diff --git a/lib/src/mobile_scanner_controller.dart b/lib/src/mobile_scanner_controller.dart index 69d21f17afe1e2f01754fcf39176de40960f011d..d2be8f9a6a51281186d2323a8059d3d814cc4d01 100644 --- a/lib/src/mobile_scanner_controller.dart +++ b/lib/src/mobile_scanner_controller.dart @@ -394,13 +394,24 @@ class MobileScannerController { /// [zoomScale] must be within 0.0 and 1.0, where 1.0 is the max zoom, and 0.0 /// is zoomed out. Future setZoomScale(double zoomScale) async { - if (zoomScale < 0 || zoomScale > 1) { - throw const MobileScannerException( - errorCode: MobileScannerErrorCode.genericError, - errorDetails: MobileScannerErrorDetails( - message: 'The zoomScale must be between 0 and 1.', - ), - ); + if (defaultTargetPlatform == TargetPlatform.ohos) { + if (zoomScale < 0 || zoomScale > 10) { + throw const MobileScannerException( + errorCode: MobileScannerErrorCode.genericError, + errorDetails: MobileScannerErrorDetails( + message: 'The zoomScale must be between 0 and 10.', + ), + ); + } + } else { + if (zoomScale < 0 || zoomScale > 1) { + throw const MobileScannerException( + errorCode: MobileScannerErrorCode.genericError, + errorDetails: MobileScannerErrorDetails( + message: 'The zoomScale must be between 0 and 1.', + ), + ); + } } await _methodChannel.invokeMethod('setScale', zoomScale); } diff --git a/ohos/src/main/ets/MobileScannerPlugin.ets b/ohos/src/main/ets/MobileScannerPlugin.ets index 3c18e8c91a8d9d43d0f2213eec510add8966c1fe..f406ce7d429a4667f040d18b5495968e531901b9 100644 --- a/ohos/src/main/ets/MobileScannerPlugin.ets +++ b/ohos/src/main/ets/MobileScannerPlugin.ets @@ -86,12 +86,10 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab onAttachedToEngine(binding: FlutterPluginBinding): void { this.binding = binding; - this.applicationContext = binding.getApplicationContext(); this.methodChannel = new MethodChannel(binding.getBinaryMessenger(), "dev.steenbakker.mobile_scanner/scanner/method"); this.methodChannel.setMethodCallHandler(this); - this.eventChannel = new EventChannel(binding.getBinaryMessenger(), "dev.steenbakker.mobile_scanner/scanner/event"); this.eventChannel.setStreamHandler({ onListen: (args: Object, eventSink: EventSink) => { @@ -100,7 +98,6 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab onCancel: () => { } }); - // texture const textureRegistry = this.binding!.getTextureRegistry(); const textureId = textureRegistry.getTextureId(); @@ -114,13 +111,9 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab this.applicationContext = null; this.methodChannel?.setMethodCallHandler(null); this.methodChannel = null; - this.eventChannel?.setStreamHandler(null); this.eventChannel = null; - this.isStart = false; - - // unregisterTexture binding.getTextureRegistry().unregisterTexture(this.textureId); } @@ -179,11 +172,9 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab if (!!cameraResolutionValues && cameraResolutionValues.length >= 2) { cameraResolution = [cameraResolutionValues[0], cameraResolutionValues[1]] } - if (!this.isStart) { this.isStart = true; let torchable: boolean = hasFlashUnit(this.applicationContext!) - let scanTypes = [scanCore.ScanType.ALL] if (formats) { scanTypes = [] @@ -194,27 +185,20 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab } }) } - const options: scanBarcode.ScanOptions = { scanTypes: scanTypes, enableMultiMode: true, enableAlbum: true } customScan.init(options); - // 设置预览流高度,默认单位:vp const cameraHeight: number = px2vp(cameraResolution[1]) // 设置预览流宽度,默认单位:vp const cameraWidth: number = px2vp(cameraResolution[0]) - this.cameraWidth = cameraWidth; this.cameraHeight = cameraHeight; - this.setDisplay() - this.startScan() - //customScan.on('lightingFlash', this.torchCallback); - if (torch) { customScan.openFlashLight() } else { @@ -224,7 +208,6 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab name: 'torchState', data: customScan.getFlashLightStatus() ? TorchState.on : TorchState.off }); - // dart 中接收的 width 和 height 会转换为 double 类型,返回整数会导致异常 result.success({ "textureId": this.textureId, @@ -235,7 +218,6 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab "torchable": torchable, "numberOfCameras": 1 }); - } else { result.error( "MobileScanner", @@ -253,7 +235,6 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab return; } // 解析码值结果跳转应用服务页 - Log.i(TAG, `Succeeded in getting ScanResult by callback, result: ${JSON.stringify(result)}`); let i = 0 let first: boolean = true const _r: Barcode[] = result.map(item => { @@ -277,19 +258,14 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab y: i.y / this.scanHeight * this.cameraHeight }) as Point) } as Barcode; - }).filter(barcode => { - if (this.scanWindow) { - return this.isBarcodeInScanWindow(barcode); - } else { - return true; - } - }); - this.callback(_r, this.imageBuffer, this.cameraWidth, this.cameraHeight) + }) + this.callback(_r, this.imageBuffer, this.cameraWidth, this.cameraHeight); + // 扫描完成后需要调用重新扫描继续识别 setTimeout(() => { if (this.isStart) { customScan.rescan(); } - }, 250) + }, 250); } // 返回相机帧的回调 private frameCallback: AsyncCallback = @@ -315,7 +291,6 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab let packingOpt: image.PackingOption = { format: "image/jpeg", quality: 100 } let imgBuffer = await packer.packing(pixelMap, packingOpt); this.imageBuffer = new Uint8Array(imgBuffer) - if (frameResult.scanCodeRects[0]) { this.scanCodeRect = []; // 码图位置信息转换 @@ -348,7 +323,6 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab height: this.scanHeight, surfaceId: this.surfaceId!, }; - customScan.start(viewControl, this.scanCallback, this.frameCallback) } @@ -376,7 +350,6 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab await customScan.stop(); await customScan.release() } catch (e) { - Log.e(TAG, "customScan Stop Error:" + JSON.stringify(e)); this.isStart = true; } } @@ -404,18 +377,14 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab enableAlbum: true } let inputImage: detectBarcode.InputImage = { uri: call.args } - detectBarcode.decode(inputImage, options, (error: BusinessError, scanResult: Array) => { if (error && error.code) { - Log.e(TAG, "analyzeImage:Callback Error:" + JSON.stringify(error)); return } - Log.d(TAG, "analyzeImage:Callback scan result:" + JSON.stringify(scanResult)); if (scanResult.length == 0) { result.success(false) return } - const barcodes: Barcode[] = scanResult.map(item => { let cornerPoints = item.cornerPoints; let corners: Array = [] @@ -439,17 +408,27 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab name: 'barcode', data: barcodes }) - result.success(true) }) } setScale(call: MethodCall, result: MethodResult) { - result.notImplemented() + let zoomValue: number = call.args as number; + try { + customScan.setZoom(zoomValue); + result.success(true); + } catch (error) { + result.success(false); + } } resetScale(result: MethodResult) { - result.notImplemented() + try { + customScan.setZoom(1); + result.success(true); + } catch (error) { + result.success(false); + } } updateScanWindow(call: MethodCall, result: MethodResult) { @@ -458,6 +437,17 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab } callback(barcodes: Barcode[], image: Uint8Array | null, width: number, height: number) { + barcodes = barcodes.filter(barcode => { + if (this.scanWindow) { + return this.isBarcodeInScanWindow(barcode); + ; + } else { + return true; + } + }); + if (barcodes.length == 0) { + return + } if (image) { this.publishEvent({ "name": "barcode", @@ -476,11 +466,12 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab private isBarcodeInScanWindow(barcode: Barcode): boolean { const corners = barcode.corners; - const top = this.scanWindow![1] * this.cameraHeight; - const bottom = this.scanWindow![3] * this.cameraHeight; - const left = this.scanWindow![0] * this.cameraWidth; - const right = this.scanWindow![2] * this.cameraWidth; - return corners.reduce((r, item) => r && item.x > left && item.x < right && item.y > top && item.y < bottom, true) + const left = Math.round(this.scanWindow![0] * this.cameraWidth); + const top = Math.round(this.scanWindow![1] * this.cameraHeight); + const right = Math.round(this.scanWindow![2] * this.cameraWidth); + const bottom = Math.round(this.scanWindow![3] * this.cameraHeight); + return corners.reduce((r, item) => r && item.x >= left && item.x <= right && item.y >= top && item.y <= bottom, + true) } errorCallback(error: string) { @@ -492,10 +483,8 @@ export class MobileScannerPlugin implements FlutterPlugin, MethodCallHandler, Ab torchCallback(error: BusinessError, bool: boolean) { if (error) { - Log.e(TAG, `Failed to cancel Flash by callback. Code: ${error.code}, message: ${error.message}`); return; } - this.publishEvent({ name: 'torchState', data: customScan.getFlashLightStatus() ? TorchState.on : TorchState.off