From 7badd21d67db30019ae67ac26cd5c1e716ad9f04 Mon Sep 17 00:00:00 2001 From: Hennik Hunsaker Date: Thu, 2 Dec 2021 17:25:21 -0700 Subject: [PATCH] Switch to a new MLKit library which runs on-device --- README.md | 33 +++++------- example/android/app/build.gradle | 4 +- .../android/app/src/main/AndroidManifest.xml | 2 +- example/lib/main.dart | 11 ++-- example/lib/main_face.dart | 4 +- example/lib/main_live.dart | 12 ++--- example/pubspec.lock | 51 ++++--------------- example/pubspec.yaml | 1 + lib/flutter_camera_ml_vision.dart | 8 +-- lib/utils.dart | 34 +++++++------ pubspec.lock | 51 ++++--------------- pubspec.yaml | 6 +-- 12 files changed, 72 insertions(+), 145 deletions(-) diff --git a/README.md b/README.md index e5a2230..a92bf7c 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,10 @@ First, add `flutter_camera_ml_vision` as a dependency. dependencies: flutter: sdk: flutter - flutter_camera_ml_vision: ^2.2.4 + flutter_camera_ml_vision: ^3.0.1 ... ``` -## Configure Firebase -You must also configure Firebase for each platform project: Android and iOS (see the `example` folder or https://firebase.google.com/codelabs/firebase-get-to-know-flutter#3 for step by step details). - - ### iOS Add two rows to the ios/Runner/Info.plist: @@ -42,10 +38,10 @@ Or in text format add the key: If you're using one of the on-device APIs, include the corresponding ML Kit library model in your Podfile. Then run pod update in a terminal within the same directory as your Podfile. ``` -pod 'Firebase/MLVisionBarcodeModel' -pod 'Firebase/MLVisionFaceModel' -pod 'Firebase/MLVisionLabelModel' -pod 'Firebase/MLVisionTextModel' +pod 'GoogleMLKit/BarcodeScanning' +pod 'GoogleMLKit/FaceDetection' +pod 'GoogleMLKit/ImageLabeling' +pod 'GoogleMLKit/TextRecognition' ``` ### Android @@ -65,7 +61,7 @@ android { dependencies { // ... - api 'com.google.firebase:firebase-ml-vision-image-label-model:19.0.0' + api 'com.google.mlkit:image-labeling:17.0.5' } } ``` @@ -78,7 +74,7 @@ Optional but recommended: If you use the on-device API, configure your app to au ... @@ -90,7 +86,7 @@ Optional but recommended: If you use the on-device API, configure your app to au ```dart CameraMlVision>( - detector: FirebaseVision.instance.barcodeDetector().detectInImage, + detector: GoogleMlKit.vision.barcodeScanner().processImage, onResult: (List barcodes) { if (!mounted || resultSent) { return; @@ -101,15 +97,14 @@ CameraMlVision>( ) ``` -`CameraMlVision` is a widget that shows the preview of the camera. It takes a detector as a parameter here we pass the `detectInImage` method of the `BarcodeDetector` object. -The detector parameter can take all the different FirebaseVision Detector. Here is a list : +`CameraMlVision` is a widget that shows the preview of the camera. It takes a detector as a parameter; here we pass the `processImage` method of the `BarcodeScanner` object. +The detector parameter can take all the different MLKit Vision Detectors. Here is a list : ``` -FirebaseVision.instance.barcodeDetector().detectInImage -FirebaseVision.instance.cloudLabelDetector().detectInImage -FirebaseVision.instance.faceDetector().processImage -FirebaseVision.instance.labelDetector().detectInImage -FirebaseVision.instance.textRecognizer().processImage +GoogleMlKit.vision.barcodeScanner().processImage +GoogleMlKit.vision.imageLabeler().processImage +GoogleMlKit.vision.faceDetector().processImage +GoogleMlKit.vision.textDetector().processImage ``` Then when something is detected the onResult callback is called with the data in the parameter of the function. diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 456484e..77836b0 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -55,10 +55,8 @@ flutter { } dependencies { - api 'com.google.firebase:firebase-ml-vision-barcode-model:16.1.2' + implementation 'com.google.mlkit:barcode-scanning:17.0.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' } - -apply plugin: 'com.google.gms.google-services' diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 62f8934..67db473 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -31,7 +31,7 @@ diff --git a/example/lib/main.dart b/example/lib/main.dart index e5d416e..8c743f6 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,6 +1,7 @@ +import 'dart:developer'; import 'dart:ui'; -import 'package:firebase_ml_vision/firebase_ml_vision.dart'; +import 'package:google_ml_kit/google_ml_kit.dart'; import 'package:flutter/material.dart'; import 'package:flutter_camera_ml_vision/flutter_camera_ml_vision.dart'; @@ -55,7 +56,7 @@ class _MyHomePageState extends State { } setState(() { - data.add(barcode.displayValue); + data.add(barcode.value.displayValue); }); }, child: Text('Scan product'), @@ -78,7 +79,7 @@ class ScanPage extends StatefulWidget { class _ScanPageState extends State { bool resultSent = false; - BarcodeDetector detector = FirebaseVision.instance.barcodeDetector(); + BarcodeScanner scanner = GoogleMlKit.vision.barcodeScanner(); @override Widget build(BuildContext context) { @@ -97,7 +98,7 @@ class _ScanPageState extends State { ), ); }, - detector: detector.detectInImage, + detector: scanner.processImage, onResult: (List barcodes) { if (!mounted || resultSent || @@ -109,7 +110,7 @@ class _ScanPageState extends State { Navigator.of(context).pop(barcodes.first); }, onDispose: () { - detector.close(); + scanner.close(); }, ), ), diff --git a/example/lib/main_face.dart b/example/lib/main_face.dart index 805eaf1..f28a42c 100644 --- a/example/lib/main_face.dart +++ b/example/lib/main_face.dart @@ -1,5 +1,5 @@ import 'package:camera/camera.dart'; -import 'package:firebase_ml_vision/firebase_ml_vision.dart'; +import 'package:google_ml_kit/google_ml_kit.dart'; import 'package:flutter/material.dart'; import 'package:flutter_camera_ml_vision/flutter_camera_ml_vision.dart'; @@ -32,7 +32,7 @@ class _MyHomePageState extends State { final _scanKey = GlobalKey(); CameraLensDirection cameraLensDirection = CameraLensDirection.front; FaceDetector detector = - FirebaseVision.instance.faceDetector(FaceDetectorOptions( + GoogleMlKit.vision.faceDetector(FaceDetectorOptions( enableTracking: true, mode: FaceDetectorMode.accurate, )); diff --git a/example/lib/main_live.dart b/example/lib/main_live.dart index 4b0d214..f6b6cba 100644 --- a/example/lib/main_live.dart +++ b/example/lib/main_live.dart @@ -1,4 +1,4 @@ -import 'package:firebase_ml_vision/firebase_ml_vision.dart'; +import 'package:google_ml_kit/google_ml_kit.dart'; import 'package:flutter/material.dart'; import 'package:flutter_camera_ml_vision/flutter_camera_ml_vision.dart'; @@ -29,7 +29,7 @@ class MyHomePage extends StatefulWidget { class _MyHomePageState extends State { List data = []; final _scanKey = GlobalKey(); - BarcodeDetector detector = FirebaseVision.instance.barcodeDetector(); + BarcodeScanner scanner = GoogleMlKit.vision.barcodeScanner(); @override Widget build(BuildContext context) { @@ -42,21 +42,21 @@ class _MyHomePageState extends State { children: [ CameraMlVision>( key: _scanKey, - detector: detector.detectInImage, + detector: scanner.processImage, resolution: ResolutionPreset.high, onResult: (barcodes) { if (barcodes == null || barcodes.isEmpty || - data.contains(barcodes.first.displayValue) || + data.contains(barcodes.first.value.displayValue) || !mounted) { return; } setState(() { - data.add(barcodes.first.displayValue); + data.add(barcodes.first.value.displayValue); }); }, onDispose: () { - detector.close(); + scanner.close(); }, ), Container( diff --git a/example/pubspec.lock b/example/pubspec.lock index aff02c6..b040bdb 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -7,7 +7,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0" + version: "2.8.1" boolean_selector: dependency: transitive description: @@ -42,7 +42,7 @@ packages: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.1" clock: dependency: transitive description: @@ -106,34 +106,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.1.0" - firebase_core: - dependency: transitive - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.0" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - firebase_ml_vision: - dependency: transitive - description: - name: firebase_ml_vision - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0+1" flutter: dependency: "direct main" description: flutter @@ -145,24 +117,19 @@ packages: path: ".." relative: true source: path - version: "3.0.0+1" + version: "3.0.1" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - js: + google_ml_kit: dependency: transitive description: - name: js + name: google_ml_kit url: "https://pub.dartlang.org" source: hosted - version: "0.6.3" + version: "0.7.3" matcher: dependency: transitive description: @@ -176,7 +143,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.7.0" path: dependency: transitive description: @@ -265,7 +232,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.1" stack_trace: dependency: transitive description: @@ -307,7 +274,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19" + version: "0.4.2" typed_data: dependency: transitive description: diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 61d2aa0..0736b8f 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -30,6 +30,7 @@ dev_dependencies: flutter_test: sdk: flutter +publish_to: none # For information on the generic Dart part of this file, see the # following page: https://www.dartlang.org/tools/pub/pubspec diff --git a/lib/flutter_camera_ml_vision.dart b/lib/flutter_camera_ml_vision.dart index 6c9689b..849df53 100644 --- a/lib/flutter_camera_ml_vision.dart +++ b/lib/flutter_camera_ml_vision.dart @@ -8,7 +8,7 @@ import 'dart:ui'; import 'package:camera/camera.dart'; import 'package:collection/collection.dart'; import 'package:device_info/device_info.dart'; -import 'package:firebase_ml_vision/firebase_ml_vision.dart'; +import 'package:google_ml_kit/google_ml_kit.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -18,7 +18,7 @@ export 'package:camera/camera.dart'; part 'utils.dart'; -typedef HandleDetection = Future Function(FirebaseVisionImage image); +typedef HandleDetection = Future Function(InputImage image); typedef ErrorWidgetBuilder = Widget Function( BuildContext context, CameraError error); @@ -66,7 +66,7 @@ class CameraMlVisionState extends State> XFile? _lastImage; final _visibilityKey = UniqueKey(); CameraController? _cameraController; - ImageRotation? _rotation; + InputImageRotation? _rotation; _CameraState _cameraMlVisionState = _CameraState.loading; CameraError _cameraError = CameraError.unknown; bool _alreadyCheckingImage = false; @@ -149,7 +149,7 @@ class CameraMlVisionState extends State> CameraValue? get cameraValue => _cameraController?.value; - ImageRotation? get imageRotation => _rotation; + InputImageRotation? get imageRotation => _rotation; Future Function() get prepareForVideoRecording => _cameraController!.prepareForVideoRecording; diff --git a/lib/utils.dart b/lib/utils.dart index 571cd18..cc77716 100644 --- a/lib/utils.dart +++ b/lib/utils.dart @@ -2,7 +2,8 @@ part of 'flutter_camera_ml_vision.dart'; Future _getCamera(CameraLensDirection dir) async { final cameras = await availableCameras(); - final camera = cameras.firstWhereOrNull((camera) => camera.lensDirection == dir); + final camera = + cameras.firstWhereOrNull((camera) => camera.lensDirection == dir); return camera ?? (cameras.isEmpty ? null : cameras.first); } @@ -12,17 +13,18 @@ Uint8List _concatenatePlanes(List planes) { return allBytes.done().buffer.asUint8List(); } -FirebaseVisionImageMetadata buildMetaData( +InputImageData buildMetaData( CameraImage image, - ImageRotation rotation, + InputImageRotation rotation, ) { - return FirebaseVisionImageMetadata( - rawFormat: image.format.raw, + return InputImageData( + inputImageFormat: InputImageFormatMethods.fromRawValue(image.format.raw) ?? + InputImageFormat.NV21, size: Size(image.width.toDouble(), image.height.toDouble()), - rotation: rotation, + imageRotation: rotation, planeData: image.planes .map( - (plane) => FirebaseVisionImagePlaneMetadata( + (plane) => InputImagePlaneMetadata( bytesPerRow: plane.bytesPerRow, height: plane.height, width: plane.width, @@ -35,26 +37,26 @@ FirebaseVisionImageMetadata buildMetaData( Future _detect( CameraImage image, HandleDetection handleDetection, - ImageRotation rotation, + InputImageRotation rotation, ) async { return handleDetection( - FirebaseVisionImage.fromBytes( - _concatenatePlanes(image.planes), - buildMetaData(image, rotation), + InputImage.fromBytes( + bytes: _concatenatePlanes(image.planes), + inputImageData: buildMetaData(image, rotation), ), ); } -ImageRotation _rotationIntToImageRotation(int rotation) { +InputImageRotation _rotationIntToImageRotation(int rotation) { switch (rotation) { case 0: - return ImageRotation.rotation0; + return InputImageRotation.Rotation_0deg; case 90: - return ImageRotation.rotation90; + return InputImageRotation.Rotation_90deg; case 180: - return ImageRotation.rotation180; + return InputImageRotation.Rotation_180deg; default: assert(rotation == 270); - return ImageRotation.rotation270; + return InputImageRotation.Rotation_270deg; } } diff --git a/pubspec.lock b/pubspec.lock index ae6c6ca..9a19ecc 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,7 +7,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0" + version: "2.8.1" boolean_selector: dependency: transitive description: @@ -42,7 +42,7 @@ packages: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.1" clock: dependency: transitive description: @@ -99,34 +99,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.1.0" - firebase_core: - dependency: "direct main" - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.0" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - firebase_ml_vision: - dependency: "direct main" - description: - name: firebase_ml_vision - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0+1" flutter: dependency: "direct main" description: flutter @@ -137,18 +109,13 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - js: - dependency: transitive + google_ml_kit: + dependency: "direct main" description: - name: js + name: google_ml_kit url: "https://pub.dartlang.org" source: hosted - version: "0.6.3" + version: "0.7.3" matcher: dependency: transitive description: @@ -162,7 +129,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.7.0" path: dependency: transitive description: @@ -251,7 +218,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.1" stack_trace: dependency: transitive description: @@ -293,7 +260,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19" + version: "0.4.2" typed_data: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 9a193c3..e3be73b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,11 +10,7 @@ environment: dependencies: flutter: sdk: flutter - firebase_ml_vision: ^0.12.0+1 - #git: - # url: git://github.com/algirdasmac/flutterfire - # path: packages/firebase_ml_vision - firebase_core: ^1.1.0 + google_ml_kit: ^0.7.3 visibility_detector: ^0.2.0 path_provider: ^2.0.1 pedantic: ^1.11.0