From 46c34b37da4c2010cfc9f1193f8604196b7cae23 Mon Sep 17 00:00:00 2001 From: Abhishek Upmanyu Date: Sun, 20 Jun 2021 23:23:47 +0530 Subject: [PATCH 1/2] Add rotate image feature --- lib/injection.config.dart | 15 +++-- lib/main.dart | 3 + lib/models/scan/image_processing_model.dart | 17 ++++++ lib/services/opencv/opencv_service.dart | 13 +++- lib/views/scan/pages/pages.dart | 15 ++--- .../widgets/options_bar/options_bar.dart | 60 +++++++++++++++---- .../scan/pages/widgets/page_list_view.dart | 50 +++++++++++----- .../scan/widgets/bottom_bar/bottom_bar.dart | 3 +- pubspec.lock | 55 +++++++++-------- pubspec.yaml | 1 + 10 files changed, 164 insertions(+), 68 deletions(-) diff --git a/lib/injection.config.dart b/lib/injection.config.dart index 1dcb0ca..6c69169 100644 --- a/lib/injection.config.dart +++ b/lib/injection.config.dart @@ -7,17 +7,22 @@ import 'package:get_it/get_it.dart' as _i1; import 'package:injectable/injectable.dart' as _i2; -import 'models/settings/permissions_model.dart' as _i4; +import 'models/scan/image_processing_model.dart' as _i4; +import 'models/settings/permissions_model.dart' as _i6; +import 'services/opencv/opencv_service.dart' as _i3; import 'services/permission_handler/permission_handler_service.dart' - as _i3; // ignore_for_file: unnecessary_lambdas + as _i5; // ignore_for_file: unnecessary_lambdas // ignore_for_file: lines_longer_than_80_chars /// initializes the registration of provided dependencies inside of [GetIt] _i1.GetIt $initGetIt(_i1.GetIt get, {String? environment, _i2.EnvironmentFilter? environmentFilter}) { final gh = _i2.GetItHelper(get, environment, environmentFilter); - gh.singleton<_i3.PermissionHandlerService>(_i3.PermissionHandlerService()); - gh.singleton<_i4.PermissionsModel>( - _i4.PermissionsModel(get<_i3.PermissionHandlerService>())); + gh.lazySingleton<_i3.OpenCVService>(() => _i3.OpenCVService()); + gh.lazySingleton<_i4.ImageProcessingModel>( + () => _i4.ImageProcessingModel(get<_i3.OpenCVService>())); + gh.singleton<_i5.PermissionHandlerService>(_i5.PermissionHandlerService()); + gh.singleton<_i6.PermissionsModel>( + _i6.PermissionsModel(get<_i5.PermissionHandlerService>())); return get; } diff --git a/lib/main.dart b/lib/main.dart index 764193a..189b3f9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:injectable/injectable.dart'; +import 'package:project_scanit/injection.dart'; import 'package:project_scanit/views/core/app_widget.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); + configureInjection(Environment.prod); runApp(AppWidget()); } diff --git a/lib/models/scan/image_processing_model.dart b/lib/models/scan/image_processing_model.dart index 0a525d0..8fae0c3 100644 --- a/lib/models/scan/image_processing_model.dart +++ b/lib/models/scan/image_processing_model.dart @@ -1,13 +1,25 @@ import 'dart:typed_data'; import 'package:flutter/foundation.dart'; +import 'package:injectable/injectable.dart'; import 'package:project_scanit/models/scan/captured_image.dart'; import 'package:project_scanit/models/scan/image_filter.dart'; +import 'package:project_scanit/services/opencv/opencv_service.dart'; +@LazySingleton() class ImageProcessingModel extends ChangeNotifier { // TODO: write all images processing functions here :) // See capture button onTap to get Uint8List image :) + final OpenCVService _openCVService; List images = []; + int index = 0; + + ImageProcessingModel(this._openCVService); + + void setIndex(int newIndex) { + index = newIndex; + notifyListeners(); + } void getRawImage(Uint8List image) async { images.add(CapturedImage( @@ -23,6 +35,11 @@ class ImageProcessingModel extends ChangeNotifier { cropToEdges() {} + rotate() { + // TODO: rotate image 90 deg clockwise from list at `index` + notifyListeners(); + } + applyFilter() {} reorder() {} diff --git a/lib/services/opencv/opencv_service.dart b/lib/services/opencv/opencv_service.dart index 5f11bae..f92e191 100644 --- a/lib/services/opencv/opencv_service.dart +++ b/lib/services/opencv/opencv_service.dart @@ -1,3 +1,14 @@ -class OpencvService { +import 'dart:typed_data'; +import 'package:injectable/injectable.dart'; +import 'package:opencv/opencv.dart'; + +@LazySingleton() +class OpenCVService { + OpenCV openCV = OpenCV(); + + Future rotate(double degree) async { + // TODO: add rotation function + return Uint8List(0); + } } \ No newline at end of file diff --git a/lib/views/scan/pages/pages.dart b/lib/views/scan/pages/pages.dart index a33a60e..adb1a9f 100644 --- a/lib/views/scan/pages/pages.dart +++ b/lib/views/scan/pages/pages.dart @@ -11,16 +11,11 @@ class Pages extends StatelessWidget { color: Color(0xff262626), child: Column( children: [ - Expanded(child: PageListView()), - Material( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(16.0), - topRight: Radius.circular(16.0), - ), - color: Colors.white, - elevation: 8.0, - child: OptionsBar(), - ), + Expanded(child: Padding( + padding: const EdgeInsets.all(8.0), + child: PageListView(), + )), + OptionsBar(), ], ), ); diff --git a/lib/views/scan/pages/widgets/options_bar/options_bar.dart b/lib/views/scan/pages/widgets/options_bar/options_bar.dart index 91f513c..4146cf1 100644 --- a/lib/views/scan/pages/widgets/options_bar/options_bar.dart +++ b/lib/views/scan/pages/widgets/options_bar/options_bar.dart @@ -1,21 +1,57 @@ import 'package:flutter/material.dart'; +import 'package:project_scanit/models/scan/image_processing_model.dart'; import 'package:project_scanit/views/scan/pages/widgets/options_bar/widgets/option_tile.dart'; +import 'package:provider/provider.dart'; class OptionsBar extends StatelessWidget { @override Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - OptionTile(icon: Icons.add_circle_rounded, text: 'Add Page', onTap: () {}), - OptionTile(icon: Icons.crop_rounded, text: 'Crop', onTap: () {}), - OptionTile(icon: Icons.rotate_right_rounded, text: 'Rotate', onTap: () {}), - OptionTile(icon: Icons.filter_rounded, text: 'Filter', onTap: () {}), - OptionTile(icon: Icons.view_array_rounded, text: 'Rearrange', onTap: () {}), - OptionTile(icon: Icons.remove_circle_rounded, text: 'Remove', onTap: () {}), - ], + final imageProcessingModelProvider = + Provider.of(context); + return Material( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(16.0), + topRight: Radius.circular(16.0), + ), + color: Colors.white, + elevation: 8.0, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + OptionTile( + icon: Icons.add_circle_rounded, + text: 'Add Page', + onTap: () {}, + ), + OptionTile( + icon: Icons.crop_rounded, + text: 'Crop', + onTap: () {}, + ), + OptionTile( + icon: Icons.rotate_right_rounded, + text: 'Rotate', + onTap: () => imageProcessingModelProvider.rotate(), + ), + OptionTile( + icon: Icons.filter_rounded, + text: 'Filter', + onTap: () {}, + ), + OptionTile( + icon: Icons.view_array_rounded, + text: 'Rearrange', + onTap: () {}, + ), + OptionTile( + icon: Icons.remove_circle_rounded, + text: 'Remove', + onTap: () {}, + ), + ], + ), ), ); } diff --git a/lib/views/scan/pages/widgets/page_list_view.dart b/lib/views/scan/pages/widgets/page_list_view.dart index c1a99ac..366b7b5 100644 --- a/lib/views/scan/pages/widgets/page_list_view.dart +++ b/lib/views/scan/pages/widgets/page_list_view.dart @@ -11,22 +11,42 @@ class PageListView extends StatelessWidget { Provider.of(context); print(imageProcessingModelProvider.images.length); - return Swiper( - scrollDirection: Axis.horizontal, - itemCount: imageProcessingModelProvider.images.length, - loop: false, - scale: 0.9, - viewportFraction: 0.8, - itemBuilder: (context, index) { - return Center( - child: Material( - color: Colors.transparent, - elevation: 8.0, - child: - Image.memory(imageProcessingModelProvider.images[index].image), + return Column( + children: [ + Expanded( + child: Swiper( + scrollDirection: Axis.horizontal, + itemCount: imageProcessingModelProvider.images.length, + loop: false, + scale: 0.9, + viewportFraction: 0.8, + onIndexChanged: (index) => + imageProcessingModelProvider.setIndex(index), + itemBuilder: (context, index) { + return Center( + child: Material( + color: Colors.transparent, + elevation: 8.0, + child: Image.memory( + imageProcessingModelProvider.images[index].image), + ), + ); + }, ), - ); - }, + ), + Material( + borderRadius: BorderRadius.circular(512.0), + color: Colors.white, + elevation: 8.0, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'Page ${imageProcessingModelProvider.index+1}', + style: TextStyle(fontSize: 12.0), + ), + ), + ), + ], ); } } diff --git a/lib/views/scan/widgets/bottom_bar/bottom_bar.dart b/lib/views/scan/widgets/bottom_bar/bottom_bar.dart index 3b859df..5bdef4e 100644 --- a/lib/views/scan/widgets/bottom_bar/bottom_bar.dart +++ b/lib/views/scan/widgets/bottom_bar/bottom_bar.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:project_scanit/injection.dart'; import 'package:project_scanit/models/scan/capture_model.dart'; import 'package:project_scanit/models/scan/image_processing_model.dart'; import 'package:project_scanit/views/scan/widgets/bottom_bar/widgets/capture_button.dart'; @@ -6,7 +7,7 @@ import 'package:project_scanit/views/scan/pages/pages.dart'; import 'package:provider/provider.dart'; class BottomBar extends StatelessWidget { - final imageProcessingModel = ImageProcessingModel(); + final imageProcessingModel = getIt(); @override Widget build(BuildContext context) { final captureModelProvider = Provider.of(context); diff --git a/pubspec.lock b/pubspec.lock index 48e092f..26a8ab3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,14 +7,14 @@ packages: name: _fe_analyzer_shared url: "https://pub.dartlang.org" source: hosted - version: "21.0.0" + version: "22.0.0" analyzer: dependency: transitive description: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "1.5.0" + version: "1.7.0" animations: dependency: "direct main" description: @@ -35,7 +35,7 @@ packages: name: args url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.1" async: dependency: transitive description: @@ -63,7 +63,7 @@ packages: name: build url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "2.0.2" build_config: dependency: transitive description: @@ -84,14 +84,14 @@ packages: name: build_resolvers url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.3" build_runner: dependency: "direct dev" description: name: build_runner url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.0.4" build_runner_core: dependency: transitive description: @@ -105,21 +105,21 @@ packages: name: built_collection url: "https://pub.dartlang.org" source: hosted - version: "5.0.0" + version: "5.1.0" built_value: dependency: transitive description: name: built_value url: "https://pub.dartlang.org" source: hosted - version: "8.0.6" + version: "8.1.0" camera: dependency: "direct main" description: name: camera url: "https://pub.dartlang.org" source: hosted - version: "0.8.1" + version: "0.8.1+3" camera_platform_interface: dependency: transitive description: @@ -231,14 +231,14 @@ packages: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.1.2" file: dependency: transitive description: name: file url: "https://pub.dartlang.org" source: hosted - version: "6.1.1" + version: "6.1.2" fixnum: dependency: transitive description: @@ -252,7 +252,7 @@ packages: name: flare_flutter url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "3.0.1" flutter: dependency: "direct main" description: flutter @@ -295,7 +295,7 @@ packages: name: get_it url: "https://pub.dartlang.org" source: hosted - version: "7.1.3" + version: "7.1.4" glob: dependency: transitive description: @@ -337,14 +337,14 @@ packages: name: injectable url: "https://pub.dartlang.org" source: hosted - version: "1.4.0" + version: "1.4.1" injectable_generator: dependency: "direct dev" description: name: injectable_generator url: "https://pub.dartlang.org" source: hosted - version: "1.4.0" + version: "1.4.1" io: dependency: transitive description: @@ -401,6 +401,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" + opencv: + dependency: "direct main" + description: + name: opencv + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" package_config: dependency: transitive description: @@ -449,35 +456,35 @@ packages: name: pdf url: "https://pub.dartlang.org" source: hosted - version: "3.4.0" + version: "3.4.2" pedantic: dependency: transitive description: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.11.0" + version: "1.11.1" permission_handler: dependency: "direct main" description: name: permission_handler url: "https://pub.dartlang.org" source: hosted - version: "8.0.0+1" + version: "8.1.1" permission_handler_platform_interface: dependency: transitive description: name: permission_handler_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "3.5.0" + version: "3.6.0" petitparser: dependency: transitive description: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "4.1.0" + version: "4.2.0" platform: dependency: transitive description: @@ -547,7 +554,7 @@ packages: name: shared_preferences url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.0.6" shared_preferences_linux: dependency: transitive description: @@ -608,7 +615,7 @@ packages: name: source_gen url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.0.2" source_span: dependency: transitive description: @@ -720,7 +727,7 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.2.1" xdg_directories: dependency: transitive description: @@ -744,4 +751,4 @@ packages: version: "3.1.0" sdks: dart: ">=2.13.0 <3.0.0" - flutter: ">=1.22.0" + flutter: ">=2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 2bbf60a..9ef031d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -34,6 +34,7 @@ dependencies: animations: flare_flutter: flutter_swiper: + opencv: pdf: From ce821ec8e616b5c5c3b4d4357d59e22b08b805f5 Mon Sep 17 00:00:00 2001 From: Abhishek Upmanyu Date: Tue, 4 Oct 2022 08:24:47 +0530 Subject: [PATCH 2/2] Upgrade flutter and kotlin versions --- android/app/build.gradle | 6 +++--- android/app/src/main/AndroidManifest.xml | 1 + android/build.gradle | 4 ++-- android/gradle/wrapper/gradle-wrapper.properties | 2 +- pubspec.yaml | 5 +++-- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 650625d..bea9427 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 30 + compileSdkVersion 33 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -44,8 +44,8 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "cheeseball.project_scanit" - minSdkVersion 21 - targetSdkVersion 30 + minSdkVersion 26 + targetSdkVersion 33 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index e5dd565..527d8d4 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,6 +7,7 @@ android:icon="@mipmap/ic_launcher">