diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3faca98..737c2d4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,12 +15,13 @@ jobs: os: [ubuntu-latest, windows-latest] steps: - uses: actions/checkout@v2 - - uses: actions/setup-java@v1 + - uses: actions/setup-java@v4 with: - java-version: '21.x' + distribution: 'temurin' + java-version: '21' - uses: subosito/flutter-action@v2 with: - flutter-version: '3.24.3' + flutter-version: '3.35.6' - run: dart --version - run: flutter --version - run: flutter pub get @@ -44,12 +45,13 @@ jobs: os: [macos-15] steps: - uses: actions/checkout@v2 - - uses: actions/setup-java@v1 + - uses: actions/setup-java@v4 with: - java-version: '21.x' + distribution: 'temurin' + java-version: '21' - uses: subosito/flutter-action@v2 with: - flutter-version: '3.24.3' + flutter-version: '3.35.6' - run: dart --version - run: flutter --version - run: flutter pub get diff --git a/CHANGELOG.md b/CHANGELOG.md index 53b3cbb..d78ad18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## 1.3.0 + +* Bumped Android to 4.4.0 +* Bumped iOS to 2.3.0 +* Added `userCanChangeDPI` and `userCanChangePageSize` to control visibility of DPI and page-size buttons in the per-image edit menu (both platforms). +* Added `editMenuButtonText`, `dpiEditButtonText`, `pageSizeEditButtonText`, `doneButtonText`, and `undoCropButtonText` for localizing the edit mode and crop screen controls (iOS only). +* Each image in the result now includes `DetectedTexts`, a list of detected text strings with bounding box positions. Populated when `performOnDeviceOCR` is `true`. +* `DPI.auto` (the default) now outputs images at native camera resolution regardless of `pageFormat` on both platforms. +* Deprecated `deleteOptionsButtonText` — will be removed in a future version. +* Minimum iOS version bumped to 15. + ## 1.2.0 * Bumped Android to 4.3.0 diff --git a/README.md b/README.md index 6448bd3..73194ba 100644 --- a/README.md +++ b/README.md @@ -181,6 +181,12 @@ config.userCanCropManually = false; // Whether to hide or show the color changing button in the Review Screen. (default shown/true) config.userCanChangeColorSetting = false; +// Whether to show the DPI button in the edit menu. (default false) +config.userCanChangeDPI = false; + +// Whether to show the Page Size button in the edit menu. (default false) +config.userCanChangePageSize = false; + // To add extra horizontal and / or vertical padding to the cropped image. config.cropPadding.width = 100; config.cropPadding.height = 100; @@ -264,19 +270,6 @@ config.imageMovingSensitivityAndroid = 50; #### iOS only ```dart - -// The text inside of the color selection alert dialog button named original. -config.imageColorOriginalText = "original"; - -// The text inside of the color selection alert dialog button named grayscale. -config.imageColorGrayscaleText = "grayscale"; - -// The text inside of the color selection alert dialog button named enhanced. -config.imageColorEnhancedText = "enhanced"; - -// The text inside of the color selection alert dialog button named black and white. -config.imageColorBlackAndWhiteText = "Black & White"; - // Whether the camera has a view finder overlay (a helper grid so the user knows where the document should be), should be a Boolean. config.isViewFinderEnabled = true; @@ -310,6 +303,10 @@ Add or edit the file `android/app/src/res/values/colors.xml`, add the following: #444444 #ffffff #2dc36a + #ffffff + #000000 + #d32f2f + #1976d2 ``` @@ -436,6 +433,42 @@ config.continueButtonText = "Continue" // The text shown in the crop screen to save the bounding box. config.saveCropButtonText = "Save" + +// The text inside of the color selection alert dialog button named original. +config.imageColorOriginalText = "original"; + +// The text inside of the color selection alert dialog button named grayscale. +config.imageColorGrayscaleText = "grayscale"; + +// The text inside of the color selection alert dialog button named enhanced. +config.imageColorEnhancedText = "enhanced"; + +// The text inside of the color selection alert dialog button named black and white. +config.imageColorBlackAndWhiteText = "Black & White"; + +// The text above the shutter button to indicate auto capture status. +config.autoCaptureButtonText = "Auto"; + +// The text above the shutter button to indicate auto capture status. +config.manualButtonText = "Manual"; + +// The title in the delete action alert dialog. (Deprecated: will be removed in a future version) +config.deleteOptionsButtonText = "Delete or Retake?"; + +// The text on the edit button in the review screen. +config.editMenuButtonText = "Edit"; + +// The text on the DPI button inside the edit menu. +config.dpiEditButtonText = "DPI"; + +// The text on the Page Size button inside the edit menu. +config.pageSizeEditButtonText = "Page Size"; + +// The text on the done button inside the edit menu. +config.doneButtonText = "Done"; + +// The text on the undo button in the crop screen. +config.undoCropButtonText = "Undo"; ``` ### Customize image in CameraMode instructions diff --git a/android/build.gradle b/android/build.gradle index c42d4c1..0a61577 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -77,7 +77,7 @@ android { } dependencies { - def fallbackKlippaScannerVersion = "4.3.0" + def fallbackKlippaScannerVersion = "4.4.0" def klippaScannerVersion = project.hasProperty('klippaScannerVersion') ? project.klippaScannerVersion : fallbackKlippaScannerVersion implementation "com.klippa:scanner:$klippaScannerVersion" } diff --git a/android/src/main/kotlin/com/klippa/scanner/klippa_scanner_sdk/KlippaScannerSdkPlugin.kt b/android/src/main/kotlin/com/klippa/scanner/klippa_scanner_sdk/KlippaScannerSdkPlugin.kt index 8919493..7c42af2 100644 --- a/android/src/main/kotlin/com/klippa/scanner/klippa_scanner_sdk/KlippaScannerSdkPlugin.kt +++ b/android/src/main/kotlin/com/klippa/scanner/klippa_scanner_sdk/KlippaScannerSdkPlugin.kt @@ -289,6 +289,14 @@ class KlippaScannerSdkPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, P scannerSession.menu.userCanChangeColorSetting = it } + call.argument("UserCanChangeDPI")?.let { + scannerSession.menu.userCanChangeDPI = it + } + + call.argument("UserCanChangePageSize")?.let { + scannerSession.menu.userCanChangePageSize = it + } + call.argument("UserCanPickMediaFromStorage")?.let { scannerSession.menu.userCanPickMediaFromStorage = it } @@ -401,10 +409,20 @@ class KlippaScannerSdkPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, P } private fun klippaScannerDidFinishScanningWithResult(result: KlippaScannerResult) { - val images: MutableList> = mutableListOf() + val images: MutableList> = mutableListOf() for (image in result.results) { - val imageDict = mapOf("Filepath" to image.location) + val detectedTexts: MutableList> = mutableListOf() + for (detectedText in image.detectedTexts) { + val boundingBox = mapOf( + "x" to detectedText.boundingBox.x.toDouble(), + "y" to detectedText.boundingBox.y.toDouble(), + "width" to detectedText.boundingBox.width.toDouble(), + "height" to detectedText.boundingBox.height.toDouble() + ) + detectedTexts.add(mapOf("Text" to detectedText.text, "BoundingBox" to boundingBox)) + } + val imageDict = mapOf("Filepath" to image.location, "DetectedTexts" to detectedTexts) images.add(imageDict) } diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index c3496c6..4d70785 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -24,7 +24,7 @@ if (flutterVersionName == null) { android { namespace "com.klippa.scanner.klippa_scanner_sdk_example" - compileSdk 35 + compileSdk 36 sourceSets { main.java.srcDirs += 'src/main/kotlin' @@ -46,7 +46,7 @@ android { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.klippa.scanner.examplekotlin" minSdkVersion 25 - targetSdkVersion 35 + targetSdkVersion 36 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 46b6728..36b58ff 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Fri Oct 11 10:23:14 CEST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/example/android/settings.gradle b/example/android/settings.gradle index 4270eab..71944f4 100644 --- a/example/android/settings.gradle +++ b/example/android/settings.gradle @@ -18,8 +18,8 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "8.6.1" apply false - id "org.jetbrains.kotlin.android" version "2.0.20" apply false + id "com.android.application" version "8.12.3" apply false + id "org.jetbrains.kotlin.android" version "2.3.0" apply false } include ":app" \ No newline at end of file diff --git a/example/ios/Podfile b/example/ios/Podfile index 4d421ce..bac8808 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -platform :ios, '14.0' +platform :ios, '15.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 361a913..7b94ba8 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -360,7 +360,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -379,7 +379,7 @@ DEVELOPMENT_TEAM = 7ZXKJ433J8; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -439,7 +439,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -488,7 +488,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -509,7 +509,7 @@ DEVELOPMENT_TEAM = 7ZXKJ433J8; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -533,7 +533,7 @@ DEVELOPMENT_TEAM = 7ZXKJ433J8; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/ios/Classes/SwiftKlippaScannerSdkPlugin.swift b/ios/Classes/SwiftKlippaScannerSdkPlugin.swift index e5e63da..72c2029 100644 --- a/ios/Classes/SwiftKlippaScannerSdkPlugin.swift +++ b/ios/Classes/SwiftKlippaScannerSdkPlugin.swift @@ -201,6 +201,38 @@ public class SwiftKlippaScannerSdkPlugin: NSObject, FlutterPlugin, KlippaScanner builder.klippaButtonTexts.imageColorBlackAndWhiteText = imageColorBlackAndWhiteText } + if let autoCaptureButtonText = builderArgs?["AutoCaptureButtonText"] as? String { + builder.klippaButtonTexts.autoCaptureButtonText = autoCaptureButtonText + } + + if let manualButtonText = builderArgs?["ManualButtonText"] as? String { + builder.klippaButtonTexts.manualButtonText = manualButtonText + } + + if let deleteOptionsButtonText = builderArgs?["DeleteOptionsButtonText"] as? String { + builder.klippaButtonTexts.deleteOptionsButtonText = deleteOptionsButtonText + } + + if let editMenuButtonText = builderArgs?["EditMenuButtonText"] as? String { + builder.klippaButtonTexts.editMenuButtonText = editMenuButtonText + } + + if let dpiEditButtonText = builderArgs?["DpiEditButtonText"] as? String { + builder.klippaButtonTexts.dpiEditButtonText = dpiEditButtonText + } + + if let pageSizeEditButtonText = builderArgs?["PageSizeEditButtonText"] as? String { + builder.klippaButtonTexts.pageSizeEditButtonText = pageSizeEditButtonText + } + + if let doneButtonText = builderArgs?["DoneButtonText"] as? String { + builder.klippaButtonTexts.doneButtonText = doneButtonText + } + + if let undoCropButtonText = builderArgs?["UndoCropButtonText"] as? String { + builder.klippaButtonTexts.undoCropButtonText = undoCropButtonText + } + if let cancelConfirmationMessage = builderArgs?["CancelConfirmationMessage"] as? String { builder.klippaMessages.cancelConfirmationMessage = cancelConfirmationMessage } @@ -229,6 +261,14 @@ public class SwiftKlippaScannerSdkPlugin: NSObject, FlutterPlugin, KlippaScanner builder.klippaMenu.userCanChangeColorSetting = userCanChangeColorSetting } + if let userCanChangeDPI = builderArgs?["UserCanChangeDPI"] as? Bool { + builder.klippaMenu.userCanChangeDPI = userCanChangeDPI + } + + if let userCanChangePageSize = builderArgs?["UserCanChangePageSize"] as? Bool { + builder.klippaMenu.userCanChangePageSize = userCanChangePageSize + } + if let primaryColor = builderArgs?["PrimaryColor"] as? String { builder.klippaColors.primaryColor = hexColorToUIColor(hex: primaryColor) } @@ -463,9 +503,19 @@ public class SwiftKlippaScannerSdkPlugin: NSObject, FlutterPlugin, KlippaScanner } public func klippaScannerDidFinishScanningWithResult(result: KlippaScannerResult) { - var images: [[String: String]] = [] + var images: [[String: Any]] = [] for image in result.results { - let imageDict = ["Filepath" : image.path] + var detectedTexts: [[String: Any]] = [] + for detectedText in image.detectedTexts { + let boundingBox: [String: Any] = [ + "x": detectedText.boundingBox.origin.x, + "y": detectedText.boundingBox.origin.y, + "width": detectedText.boundingBox.size.width, + "height": detectedText.boundingBox.size.height + ] + detectedTexts.append(["Text": detectedText.text, "BoundingBox": boundingBox]) + } + let imageDict: [String: Any] = ["Filepath": image.path, "DetectedTexts": detectedTexts] images.append(imageDict) } diff --git a/ios/klippa_scanner_sdk.podspec b/ios/klippa_scanner_sdk.podspec index 15f1bde..ef1024c 100644 --- a/ios/klippa_scanner_sdk.podspec +++ b/ios/klippa_scanner_sdk.podspec @@ -16,7 +16,7 @@ Allows you to do document scanning with the Klippa Scanner SDK from Flutter apps s.source_files = 'Classes/**/*' s.dependency 'Flutter' s.dependency 'Klippa-Scanner' - s.platform = :ios, '14.0' + s.platform = :ios, '15.0' # Flutter.framework does not contain a i386 slice. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } diff --git a/ios/sdk_version b/ios/sdk_version index ccbccc3..276cbf9 100644 --- a/ios/sdk_version +++ b/ios/sdk_version @@ -1 +1 @@ -2.2.0 +2.3.0 diff --git a/lib/klippa_scanner_sdk.dart b/lib/klippa_scanner_sdk.dart index 0614291..782fb5c 100644 --- a/lib/klippa_scanner_sdk.dart +++ b/lib/klippa_scanner_sdk.dart @@ -135,6 +135,12 @@ class CameraConfig { /// Whether to hide or show the color changing button in the Review Screen. (default shown/true) bool? userCanChangeColorSetting; + /// Whether to show the DPI button in the edit menu. (default false) + bool? userCanChangeDPI; + + /// Whether to show the Page Size button in the edit menu. (default false) + bool? userCanChangePageSize; + /// If you would like to use a custom model for object detection. Model + labels file should be packaged in your bundle. ModelOptions model = new ModelOptions(); @@ -217,6 +223,31 @@ class CameraConfig { /// The text inside of the color selection alert dialog button named black and white. String? imageColorBlackAndWhiteText; + /// The text above the shutter button to indicate whether auto capture is enabled or not. + String? autoCaptureButtonText; + + /// The text above the shutter button to indicate whether manual capture is enabled or not. + String? manualButtonText; + + /// Deprecated: The text inside of the delete options alert dialog. + @Deprecated('deleteOptionsButtonText will be removed in a future version.') + String? deleteOptionsButtonText; + + /// The text on the edit button in the review screen (replaces the old filter button). + String? editMenuButtonText; + + /// The text on the DPI button inside the edit menu. + String? dpiEditButtonText; + + /// The text on the Page Size button inside the edit menu. + String? pageSizeEditButtonText; + + /// The text on the done button inside the edit menu. + String? doneButtonText; + + /// The text on the undo button in the crop screen. + String? undoCropButtonText; + /// The text to finish the scanner on the edit screen. String? continueButtonText; @@ -435,6 +466,14 @@ class KlippaScannerSdk { config.userCanChangeColorSetting; } + if (config.userCanChangeDPI != null) { + parameters["UserCanChangeDPI"] = config.userCanChangeDPI; + } + + if (config.userCanChangePageSize != null) { + parameters["UserCanChangePageSize"] = config.userCanChangePageSize; + } + if (config.userCanPickMediaFromStorage != null) { parameters["UserCanPickMediaFromStorage"] = config.userCanPickMediaFromStorage; @@ -571,6 +610,39 @@ class KlippaScannerSdk { config.imageColorBlackAndWhiteText; } + if (config.autoCaptureButtonText != null) { + parameters["AutoCaptureButtonText"] = config.autoCaptureButtonText; + } + + if (config.manualButtonText != null) { + parameters["ManualButtonText"] = config.manualButtonText; + } + + // ignore: deprecated_member_use_from_same_package + if (config.deleteOptionsButtonText != null) { + parameters["DeleteOptionsButtonText"] = config.deleteOptionsButtonText; + } + + if (config.editMenuButtonText != null) { + parameters["EditMenuButtonText"] = config.editMenuButtonText; + } + + if (config.dpiEditButtonText != null) { + parameters["DpiEditButtonText"] = config.dpiEditButtonText; + } + + if (config.pageSizeEditButtonText != null) { + parameters["PageSizeEditButtonText"] = config.pageSizeEditButtonText; + } + + if (config.doneButtonText != null) { + parameters["DoneButtonText"] = config.doneButtonText; + } + + if (config.undoCropButtonText != null) { + parameters["UndoCropButtonText"] = config.undoCropButtonText; + } + if (config.continueButtonText != null) { parameters["ContinueButtonText"] = config.continueButtonText; } diff --git a/pubspec.yaml b/pubspec.yaml index 0034594..808db55 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: klippa_scanner_sdk description: Allows you to do document scanning with the Klippa Scanner SDK from Flutter apps. -version: 1.2.0 +version: 1.3.0 homepage: https://github.com/klippa-app/flutter-klippa-scanner-sdk environment: