├── .gitignore
├── .images
├── ScanbotSDKLogo.png
├── ScanbotSDKLogo_darkmode.png
├── auto-capture.png
├── auto-crop.png
├── check-scanner.png
├── mrz-scanner.png
├── user-guidance.png
└── vin-scanner.png
├── Libraries.txt
├── README.md
├── angular.json
├── config.xml
├── e2e
├── protractor.conf.js
├── src
│ ├── app.e2e-spec.ts
│ └── app.po.ts
└── tsconfig.e2e.json
├── ionic.config.json
├── package-lock.json
├── package.json
├── resources
├── README.md
├── android
│ ├── icon
│ │ ├── drawable-hdpi-icon.png
│ │ ├── drawable-ldpi-icon.png
│ │ ├── drawable-mdpi-icon.png
│ │ ├── drawable-xhdpi-icon.png
│ │ ├── drawable-xxhdpi-icon.png
│ │ └── drawable-xxxhdpi-icon.png
│ └── splash
│ │ ├── drawable-land-hdpi-screen.png
│ │ ├── drawable-land-ldpi-screen.png
│ │ ├── drawable-land-mdpi-screen.png
│ │ ├── drawable-land-xhdpi-screen.png
│ │ ├── drawable-land-xxhdpi-screen.png
│ │ ├── drawable-land-xxxhdpi-screen.png
│ │ ├── drawable-port-hdpi-screen.png
│ │ ├── drawable-port-ldpi-screen.png
│ │ ├── drawable-port-mdpi-screen.png
│ │ ├── drawable-port-xhdpi-screen.png
│ │ ├── drawable-port-xxhdpi-screen.png
│ │ └── drawable-port-xxxhdpi-screen.png
├── icon.png
├── ios
│ ├── icon
│ │ ├── icon-1024.png
│ │ ├── icon-108@2x.png
│ │ ├── icon-20.png
│ │ ├── icon-20@2x.png
│ │ ├── icon-20@3x.png
│ │ ├── icon-24@2x.png
│ │ ├── icon-27.5@2x.png
│ │ ├── icon-29.png
│ │ ├── icon-29@2x.png
│ │ ├── icon-29@3x.png
│ │ ├── icon-40.png
│ │ ├── icon-40@2x.png
│ │ ├── icon-40@3x.png
│ │ ├── icon-44@2x.png
│ │ ├── icon-50.png
│ │ ├── icon-50@2x.png
│ │ ├── icon-60.png
│ │ ├── icon-60@2x.png
│ │ ├── icon-60@3x.png
│ │ ├── icon-72.png
│ │ ├── icon-72@2x.png
│ │ ├── icon-76.png
│ │ ├── icon-76@2x.png
│ │ ├── icon-83.5@2x.png
│ │ ├── icon-86@2x.png
│ │ ├── icon-98@2x.png
│ │ ├── icon-small.png
│ │ ├── icon-small@2x.png
│ │ ├── icon-small@3x.png
│ │ ├── icon.png
│ │ └── icon@2x.png
│ └── splash
│ │ ├── Default-1792h~iphone.png
│ │ ├── Default-2436h.png
│ │ ├── Default-2688h~iphone.png
│ │ ├── Default-568h@2x~iphone.png
│ │ ├── Default-667h.png
│ │ ├── Default-736h.png
│ │ ├── Default-Landscape-1792h~iphone.png
│ │ ├── Default-Landscape-2436h.png
│ │ ├── Default-Landscape-2688h~iphone.png
│ │ ├── Default-Landscape-736h.png
│ │ ├── Default-Landscape@2x~ipad.png
│ │ ├── Default-Landscape@~ipadpro.png
│ │ ├── Default-Landscape~ipad.png
│ │ ├── Default-Portrait@2x~ipad.png
│ │ ├── Default-Portrait@~ipadpro.png
│ │ ├── Default-Portrait~ipad.png
│ │ ├── Default@2x~iphone.png
│ │ ├── Default@2x~universal~anyany.png
│ │ └── Default~iphone.png
└── splash.png
├── scanbot-sdk-app-resources
├── ios
│ └── ScanbotSDKOCRData.bundle
│ │ └── .gitkeep
└── shared
│ └── ocr
│ ├── deu.traineddata
│ ├── eng.traineddata
│ └── osd.traineddata
├── src
├── app
│ ├── app-routing.module.ts
│ ├── app.component.html
│ ├── app.component.spec.ts
│ ├── app.component.ts
│ ├── app.module.ts
│ ├── barcode-document-list
│ │ ├── barcode-document-list.module.ts
│ │ ├── barcode-document-list.page.html
│ │ └── barcode-document-list.page.ts
│ ├── barcode-list
│ │ ├── barcode-list.module.ts
│ │ ├── barcode-list.page.html
│ │ └── barcode-list.page.ts
│ ├── barcode-result-list
│ │ ├── barcode-result-list.module.ts
│ │ ├── barcode-result-list.page.html
│ │ ├── barcode-result-list.page.scss
│ │ ├── barcode-result-list.page.spec.ts
│ │ └── barcode-result-list.page.ts
│ ├── check-recognizer-results
│ │ ├── check-recognizer-results.module.ts
│ │ ├── check-recognizer-results.page.html
│ │ ├── check-recognizer-results.page.spec.ts
│ │ └── check-recognizer-results.page.ts
│ ├── generic-document-recognizer-results
│ │ ├── generic-document-recognizer-results.module.ts
│ │ ├── generic-document-recognizer-results.page.html
│ │ ├── generic-document-recognizer-results.page.scss
│ │ ├── generic-document-recognizer-results.page.spec.ts
│ │ └── generic-document-recognizer-results.page.ts
│ ├── home
│ │ ├── home.module.ts
│ │ ├── home.page.html
│ │ ├── home.page.scss
│ │ └── home.page.ts
│ ├── image-results
│ │ ├── image-results.module.ts
│ │ ├── image-results.page.html
│ │ ├── image-results.page.scss
│ │ └── image-results.page.ts
│ ├── image-view
│ │ ├── image-view.module.ts
│ │ ├── image-view.page.html
│ │ └── image-view.page.ts
│ ├── medical-certificate-scanner-results
│ │ ├── medical-certificate-scanner-results-routing.module.ts
│ │ ├── medical-certificate-scanner-results.module.ts
│ │ ├── medical-certificate-scanner-results.page.html
│ │ ├── medical-certificate-scanner-results.page.scss
│ │ ├── medical-certificate-scanner-results.page.spec.ts
│ │ └── medical-certificate-scanner-results.page.ts
│ ├── mrz-scanner-results
│ │ ├── mrz-scanner-results-routing.module.ts
│ │ ├── mrz-scanner-results.module.ts
│ │ ├── mrz-scanner-results.page.html
│ │ ├── mrz-scanner-results.page.scss
│ │ ├── mrz-scanner-results.page.spec.ts
│ │ └── mrz-scanner-results.page.ts
│ ├── section-list
│ │ ├── section-list.component.html
│ │ ├── section-list.component.scss
│ │ ├── section-list.component.spec.ts
│ │ └── section-list.component.ts
│ └── services
│ │ ├── barcode-document-list.service.ts
│ │ ├── barcode-list.service.ts
│ │ ├── dialogs.service.ts
│ │ ├── image-results.repository.ts
│ │ ├── scanbot-sdk-demo.service.ts
│ │ └── scanner-results.service.ts
├── assets
│ ├── icon
│ │ └── favicon.png
│ └── shapes.svg
├── environments
│ ├── environment.prod.ts
│ └── environment.ts
├── global.scss
├── index.html
├── karma.conf.js
├── main.ts
├── polyfills.ts
├── test.ts
├── theme
│ └── variables.scss
├── tsconfig.app.json
├── tsconfig.spec.json
└── utils
│ ├── byte-array-utils.ts
│ ├── gdr-utils.ts
│ └── image-filters.ts
├── tsconfig.json
└── typings
└── cordova-typings.d.ts
/.gitignore:
--------------------------------------------------------------------------------
1 | # Specifies intentionally untracked files to ignore when using Git
2 | # http://git-scm.com/docs/gitignore
3 |
4 | www/*
5 | !www/.gitkeep
6 |
7 | *~
8 | *.sw[mnpcod]
9 | *.log
10 | *.tmp
11 | *.tmp.*
12 | log.txt
13 | *.sublime-project
14 | *.sublime-workspace
15 | .vscode/
16 | npm-debug.log*
17 |
18 | .idea/
19 | .ionic/
20 | .sourcemaps/
21 | .sass-cache/
22 | .tmp/
23 | .versions/
24 | coverage/
25 | node_modules/
26 | tmp/
27 | temp/
28 | platforms/
29 | plugins/
30 | plugins/android.json
31 | plugins/ios.json
32 | $RECYCLE.BIN/
33 |
34 | .DS_Store
35 | Thumbs.db
36 | UserInterfaceState.xcuserstate
37 |
38 | reinstall-dev-scanbot-plugin.sh
39 |
40 | sdk-ios.zip
41 |
42 | .angular/
43 |
--------------------------------------------------------------------------------
/.images/ScanbotSDKLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/.images/ScanbotSDKLogo.png
--------------------------------------------------------------------------------
/.images/ScanbotSDKLogo_darkmode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/.images/ScanbotSDKLogo_darkmode.png
--------------------------------------------------------------------------------
/.images/auto-capture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/.images/auto-capture.png
--------------------------------------------------------------------------------
/.images/auto-crop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/.images/auto-crop.png
--------------------------------------------------------------------------------
/.images/check-scanner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/.images/check-scanner.png
--------------------------------------------------------------------------------
/.images/mrz-scanner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/.images/mrz-scanner.png
--------------------------------------------------------------------------------
/.images/user-guidance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/.images/user-guidance.png
--------------------------------------------------------------------------------
/.images/vin-scanner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/.images/vin-scanner.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | # Example app for the Scanbot Cordova Ionic Document Scanner SDK and Data Capture Modules
9 |
10 | This example app shows how to integrate the [Scanbot Document Scanner SDK](https://scanbot.io/document-scanner-sdk/?utm_source=github.com&utm_medium=referral&utm_campaign=dev_sites) and [Scanbot Data Capture Modules](https://scanbot.io/data-capture-software/?utm_source=github.com&utm_medium=referral&utm_campaign=dev_sites) for Cordova.
11 |
12 | ## What is the Scanbot SDK?
13 |
14 | The Scanbot SDK is a set of high-level APIs that lets you integrate document scanning and data extraction functionalities, into your mobile apps and websites. It runs on all common mobile devices and operates entirely offline. No data is transmitted to our or third-party servers.
15 |
16 | With our Ready-To-Use UI (RTU UI) components, you can integrate the Scanbot SDK into your apps in less than an hour.
17 |
18 | 💡 For more details about the Scanbot Cordova Document Scanner SDK and Data Capture Modules, please check out our [documentation.](https://docs.scanbot.io/document-scanner-sdk/cordova/introduction/?utm_source=github.com&utm_medium=referral&utm_campaign=dev_sites)
19 |
20 | ## How to run this example app?
21 |
22 | ### Requirements
23 |
24 | * [NodeJS 16+](https://nodejs.org/) (installation via [nvm](https://github.com/nvm-sh/nvm) recommended)
25 | * [Cordova CLI](https://cordova.apache.org/)
26 | * [Ionic CLI](https://ionicframework.com/)
27 | * [native-run CLI](https://www.npmjs.com/package/native-run)
28 | * [Android Studio](https://developer.android.com/studio) and [Xcode](https://developer.apple.com/xcode/)
29 |
30 | ### Installation
31 |
32 | Install node modules:
33 |
34 | `npm install`
35 |
36 | Install Cordova platforms and plugins (defined in the config.xml of this app):
37 |
38 | `ionic cordova prepare`
39 |
40 | Check installed platforms and plugins:
41 |
42 | `cordova platform ls`
43 |
44 | `cordova plugin ls`
45 |
46 | You should see Android and iOS as installed platforms and cordova-plugin-scanbot-sdk as installed plugins.
47 |
48 | ### Running the app
49 |
50 | #### Android:
51 |
52 | `ionic cordova run android`
53 |
54 | #### iOS:
55 |
56 | `ionic cordova prepare ios`
57 |
58 | Open the workspace platforms/ios/Scanbot SDK Example Ionic.xcworkspace in Xcode and adjust the "Signing" settings accordingly. Then build and run the app in Xcode.
59 |
60 | ## Overview of the Scanbot SDK
61 |
62 | ### Document Scanner SDK
63 |
64 | Our Cordova Plugin Document Scanner allows you to turn smartphones into reliable and easy-to-use document scanners. It offers the following features:
65 |
66 | * **User guidance**: Ease of use is crucial for large user bases. Our on-screen user guidance helps even non-tech-savvy users create perfect scans.
67 |
68 | * **Automatic capture**: The SDK automatically captures the scan when the device is optimally positioned over the document. This reduces the risk of blurry or incomplete document scans compared to manually-triggered capture. If an error occurs during this process, the system will prompt the user to reposition the document until the document has been scanned successfully.
69 |
70 | * **Automatic cropping**: Our SDK uses edge detection to automatically identify document borders. Then, it uses auto-cropping to straighten and crop the scanned document, ensuring high-quality scan results.
71 |
72 | * **Custom filters:** Every use case has specific image requirements. With the SDK’s custom filters you can turn the captured image into optimal input for your backend system. They include grayscale, several binarization options, and more. All these filters can be automatically applied to all the scanned pages of the file.
73 |
74 | * **Document Quality Analyzer:** This feature automatically rates the quality of the pages from “very poor” to “excellent.” If the quality is below a specified threshold, it displays an error message to prompt the user to rescan.
75 |
76 | * **Export formats:** The Scanbot Document Scanner SDK supports several output formats (JPG, PDF, TIFF, and PNG). This ensures your downstream solutions receive the best format to store, print, or share the digitized document – or to process it further.
77 |
78 | |  |  |  |
79 | | :-- | :-- | :-- |
80 |
81 | ### Data Capture Modules
82 |
83 | The Scanbot SDK Data Capture Modules allow you to extract data from a wide range of structured documents and to integrate OCR text recognition capabilities. They include:
84 |
85 | #### [MRZ Scanner](https://scanbot.io/data-capture-software/mrz-scanner/?utm_source=github.com&utm_medium=referral&utm_campaign=dev_sites)
86 | This module allows quick and accurate data extraction from the machine-readable zones on identity documents. It captures all important MRZ data from IDs and passports and returns it in the form of simple key-value pairs. This is much simpler, faster, and less mistake-prone than manual data entry.
87 |
88 | #### [Check Scanner (MICR)](https://scanbot.io/data-capture-software/check-scanner/?utm_source=github.com&utm_medium=referral&utm_campaign=dev_sites)
89 | The MICR Scanner offers reliable data extraction from international paper checks, capturing check numbers, routing numbers, and account numbers from MICR codes. This simplifies workflows and reduces errors that frustrate customers and employees.
90 |
91 | #### [Text Pattern Scanner](https://scanbot.io/data-capture-software/data-scanner/?utm_source=github.com&utm_medium=referral&utm_campaign=dev_sites)
92 | Our Text Pattern Scanner allows quick and accurate extraction of single-line data. It captures information based on customizable patterns tailored to your specific use case. This replaces error-prone manual data entry with automatic capture.
93 |
94 | #### [VIN Scanner](https://scanbot.io/data-capture-software/vin-scanner/?utm_source=github.com&utm_medium=referral&utm_campaign=dev_sites)
95 | The VIN scanner enables instant capture of vehicle identification numbers (VINs) from trucks or car doors. It uses OCR to convert the image of the VIN code into structured data for backend processing. This module integrates into mobile or web-based fleet management applications, enabling you to replace error-prone manual entry with fast, reliable data extraction.
96 |
97 | #### Document Data Extractor
98 | Through this feature, our SDK offers document detection and data capture capabilities for a wider range of documents. It accurately identifies and crops various standardized document types including [German ID cards](https://scanbot.io/data-capture-software/id-scanner/?utm_source=github.com&utm_medium=referral&utm_campaign=dev_sites), passports, [driver's licenses](https://scanbot.io/data-capture-software/german-drivers-license-scanner/?utm_source=github.com&utm_medium=referral&utm_campaign=dev_sites), [residence permits](https://scanbot.io/data-capture-software/residence-permit-scanner/?utm_source=github.com&utm_medium=referral&utm_campaign=dev_sites), and the [EHIC](https://scanbot.io/data-capture-software/ehic-scanner/?utm_source=github.com&utm_medium=referral&utm_campaign=dev_sites). It uses the Scanbot OCR engine for accurate data field recognition, without requiring additional OCR language files.
99 |
100 | |  |  |  |
101 | | :-- | :-- | :-- |
102 |
103 | ## Additional information
104 |
105 | ### Free integration support
106 |
107 | Need help integrating or testing our Cordova Document Scanner SDK? We offer [free developer support](https://docs.scanbot.io/support/?utm_source=github.com&utm_medium=referral&utm_campaign=dev_sites) via Slack, MS Teams, or email.
108 |
109 | As a customer, you also get access to a dedicated support Slack or Microsoft Teams channel to talk directly to your Customer Success Manager and our engineers.
110 |
111 | ### Trial licensing and pricing
112 |
113 | The Scanbot SDK examples will run for one minute per session without a license. After that, all functionalities and UI components will stop working.
114 |
115 | To try the Scanbot SDK without the one-minute limit, you can request a free, no-strings-attached [7-day trial license](https://scanbot.io/trial/?utm_source=github.com&utm_medium=referral&utm_campaign=dev_sites).
116 |
117 | Alternatively, check out our [demo apps](https://scanbot.io/demo-apps/?utm_source=github.com&utm_medium=referral&utm_campaign=dev_sites) to test the SDK.
118 |
119 | Our pricing model is simple: Unlimited document scanning for a flat annual license fee, full support included. There are no tiers, usage charges, or extra fees. [Contact](https://scanbot.io/contact-sales/?utm_source=github.com&utm_medium=referral&utm_campaign=dev_sites) our team to receive your quote.
120 |
121 | ### Other supported platforms
122 |
123 | Besides Cordova & Ionic, the Scanbot SDK is available on:
124 |
125 | * [Android](https://github.com/doo/scanbot-sdk-example-android) (native)
126 | * [iOS](https://github.com/doo/scanbot-sdk-example-ios) (native)
127 | * [JavaScript](https://github.com/doo/scanbot-sdk-example-web)
128 | * [Capacitor & Ionic (Angular)](https://github.com/doo/scanbot-sdk-example-capacitor-ionic)
129 | * [Capacitor & Ionic (React)](https://github.com/doo/scanbot-sdk-example-ionic-react)
130 | * [Capacitor & Ionic (Vue.js)](https://github.com/doo/scanbot-sdk-example-ionic-vuejs)
131 | * [Flutter](https://github.com/doo/scanbot-sdk-example-flutter)
132 | * [.NET MAUI](https://github.com/doo/scanbot-sdk-maui-example)
133 | * [React Native](https://github.com/doo/scanbot-sdk-example-react-native)
134 | * [Xamarin](https://github.com/doo/scanbot-sdk-example-xamarin) & [Xamarin.Forms](https://github.com/doo/scanbot-sdk-example-xamarin-forms)
135 |
136 | Our Barcode Scanner SDK additionally also supports [Compose Multiplatform / KMP](https://github.com/doo/scanbot-barcode-scanner-sdk-example-kmp), [UWP](https://github.com/doo/scanbot-barcode-scanner-sdk-example-windows) (Windows), and [Linux](https://github.com/doo/scanbot-sdk-example-linux).
137 |
--------------------------------------------------------------------------------
/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular-devkit/core/src/workspace/workspace-schema.json",
3 | "version": 1,
4 | "defaultProject": "app",
5 | "newProjectRoot": "projects",
6 | "projects": {
7 | "app": {
8 | "root": "",
9 | "sourceRoot": "src",
10 | "projectType": "application",
11 | "prefix": "app",
12 | "schematics": {},
13 | "architect": {
14 | "build": {
15 | "builder": "@angular-devkit/build-angular:browser",
16 | "options": {
17 | "outputPath": "www",
18 | "index": "src/index.html",
19 | "main": "src/main.ts",
20 | "polyfills": "src/polyfills.ts",
21 | "tsConfig": "src/tsconfig.app.json",
22 | "assets": [
23 | {
24 | "glob": "**/*",
25 | "input": "src/assets",
26 | "output": "assets"
27 | },
28 | {
29 | "glob": "**/*.svg",
30 | "input": "node_modules/ionicons/dist/ionicons/svg",
31 | "output": "./svg"
32 | }
33 | ],
34 | "styles": [
35 | {
36 | "input": "src/theme/variables.scss"
37 | },
38 | {
39 | "input": "src/global.scss"
40 | }
41 | ],
42 | "scripts": []
43 | },
44 | "configurations": {
45 | "production": {
46 | "fileReplacements": [
47 | {
48 | "replace": "src/environments/environment.ts",
49 | "with": "src/environments/environment.prod.ts"
50 | }
51 | ],
52 | "optimization": true,
53 | "outputHashing": "all",
54 | "sourceMap": false,
55 | "extractCss": true,
56 | "namedChunks": false,
57 | "aot": true,
58 | "extractLicenses": true,
59 | "vendorChunk": false,
60 | "buildOptimizer": true,
61 | "budgets": [
62 | {
63 | "type": "initial",
64 | "maximumWarning": "2mb",
65 | "maximumError": "5mb"
66 | }
67 | ]
68 | },
69 | "ci": {
70 | "progress": false
71 | }
72 | }
73 | },
74 | "serve": {
75 | "builder": "@angular-devkit/build-angular:dev-server",
76 | "options": {
77 | "browserTarget": "app:build"
78 | },
79 | "configurations": {
80 | "production": {
81 | "browserTarget": "app:build:production"
82 | },
83 | "ci": {
84 | "progress": false
85 | }
86 | }
87 | },
88 | "extract-i18n": {
89 | "builder": "@angular-devkit/build-angular:extract-i18n",
90 | "options": {
91 | "browserTarget": "app:build"
92 | }
93 | },
94 | "test": {
95 | "builder": "@angular-devkit/build-angular:karma",
96 | "options": {
97 | "main": "src/test.ts",
98 | "polyfills": "src/polyfills.ts",
99 | "tsConfig": "src/tsconfig.spec.json",
100 | "karmaConfig": "src/karma.conf.js",
101 | "styles": [],
102 | "scripts": [],
103 | "assets": [
104 | {
105 | "glob": "favicon.ico",
106 | "input": "src/",
107 | "output": "/"
108 | },
109 | {
110 | "glob": "**/*",
111 | "input": "src/assets",
112 | "output": "/assets"
113 | }
114 | ]
115 | },
116 | "configurations": {
117 | "ci": {
118 | "progress": false,
119 | "watch": false
120 | }
121 | }
122 | },
123 | "lint": {
124 | "builder": "@angular-devkit/build-angular:tslint",
125 | "options": {
126 | "tsConfig": ["src/tsconfig.app.json", "src/tsconfig.spec.json"],
127 | "exclude": ["**/node_modules/**"]
128 | }
129 | },
130 | "ionic-cordova-build": {
131 | "builder": "@ionic/cordova-builders:cordova-build",
132 | "options": {
133 | "browserTarget": "app:build"
134 | },
135 | "configurations": {
136 | "production": {
137 | "browserTarget": "app:build:production"
138 | }
139 | }
140 | },
141 | "ionic-cordova-serve": {
142 | "builder": "@ionic/cordova-builders:cordova-build",
143 | "options": {
144 | "cordovaBuildTarget": "app:ionic-cordova-build",
145 | "devServerTarget": "app:serve"
146 | },
147 | "configurations": {
148 | "production": {
149 | "cordovaBuildTarget": "app:ionic-cordova-build:production",
150 | "devServerTarget": "app:serve:production"
151 | }
152 | }
153 | }
154 | }
155 | },
156 | "app-e2e": {
157 | "root": "e2e/",
158 | "projectType": "application",
159 | "architect": {
160 | "e2e": {
161 | "builder": "@angular-devkit/build-angular:protractor",
162 | "options": {
163 | "protractorConfig": "e2e/protractor.conf.js",
164 | "devServerTarget": "app:serve"
165 | },
166 | "configurations": {
167 | "ci": {
168 | "devServerTarget": "app:serve:ci"
169 | }
170 | }
171 | },
172 | "lint": {
173 | "builder": "@angular-devkit/build-angular:tslint",
174 | "options": {
175 | "tsConfig": "e2e/tsconfig.e2e.json",
176 | "exclude": ["**/node_modules/**"]
177 | }
178 | }
179 | }
180 | }
181 | },
182 | "cli": {
183 | "defaultCollection": "@ionic/angular-toolkit",
184 | "analytics": false
185 | },
186 | "schematics": {
187 | "@ionic/angular-toolkit:component": {
188 | "styleext": "scss"
189 | },
190 | "@ionic/angular-toolkit:page": {
191 | "styleext": "scss"
192 | }
193 | }
194 | }
195 |
--------------------------------------------------------------------------------
/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Scanbot SDK Example Ionic
4 | Example App for the Scanbot SDK Cordova Plugin with Ionic Framework
5 | Scanbot / doo GmbH
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | Scan Documents, QR-/Barcodes, MRZ, etc.
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/e2e/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // Protractor configuration file, see link for more information
2 | // https://github.com/angular/protractor/blob/master/lib/config.ts
3 |
4 | const { SpecReporter } = require('jasmine-spec-reporter');
5 |
6 | exports.config = {
7 | allScriptsTimeout: 11000,
8 | specs: [
9 | './src/**/*.e2e-spec.ts'
10 | ],
11 | capabilities: {
12 | 'browserName': 'chrome'
13 | },
14 | directConnect: true,
15 | baseUrl: 'http://localhost:4200/',
16 | framework: 'jasmine',
17 | jasmineNodeOpts: {
18 | showColors: true,
19 | defaultTimeoutInterval: 30000,
20 | print: function() {}
21 | },
22 | onPrepare() {
23 | require('ts-node').register({
24 | project: require('path').join(__dirname, './tsconfig.e2e.json')
25 | });
26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/e2e/src/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { AppPage } from './app.po';
2 |
3 | describe('new App', () => {
4 | let page: AppPage;
5 |
6 | beforeEach(() => {
7 | page = new AppPage();
8 | });
9 |
10 | it('should be blank', () => {
11 | page.navigateTo();
12 | expect(page.getParagraphText()).toContain('The world is your oyster.');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/e2e/src/app.po.ts:
--------------------------------------------------------------------------------
1 | import { browser, by, element } from 'protractor';
2 |
3 | export class AppPage {
4 | navigateTo() {
5 | return browser.get('/');
6 | }
7 |
8 | getParagraphText() {
9 | return element(by.deepCss('app-root ion-content')).getText();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/e2e/tsconfig.e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/app",
5 | "module": "commonjs",
6 | "target": "es5",
7 | "types": [
8 | "jasmine",
9 | "jasminewd2",
10 | "node"
11 | ]
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ionic.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "scanbot-sdk-example-ionic",
3 | "integrations": {
4 | "cordova": {}
5 | },
6 | "type": "angular"
7 | }
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "scanbot-sdk-example-ionic",
3 | "version": "4.18.1",
4 | "author": "Scanbot SDK GmbH",
5 | "homepage": "https://scanbot.io",
6 | "scripts": {
7 | "ng": "ng",
8 | "start": "ng serve",
9 | "build": "ng build",
10 | "test": "ng test",
11 | "lint": "ng lint",
12 | "e2e": "ng e2e"
13 | },
14 | "private": true,
15 | "dependencies": {
16 | "@angular/common": "^15.2.9",
17 | "@angular/core": "^15.2.9",
18 | "@angular/forms": "^15.2.9",
19 | "@angular/platform-browser": "^15.2.9",
20 | "@angular/platform-browser-dynamic": "^15.2.9",
21 | "@angular/router": "^15.2.9",
22 | "@awesome-cordova-plugins/camera": "^6.4.0",
23 | "@awesome-cordova-plugins/core": "^6.4.0",
24 | "@awesome-cordova-plugins/file": "^6.4.0",
25 | "@awesome-cordova-plugins/status-bar": "^6.4.0",
26 | "@ionic-native/camera": "^5.36.0",
27 | "@ionic/angular": "6.7.5",
28 | "@ionic/cordova-builders": "^9.0.0",
29 | "@ionic/storage-angular": "^3.0.6",
30 | "core-js": "^3.30.0",
31 | "rxjs": "6.6.0",
32 | "sass": "^1.60.0",
33 | "sharp": "^0.32.0",
34 | "source-map": "^0.7.4",
35 | "underscore": "1.13.6",
36 | "zone.js": "^0.13.0"
37 | },
38 | "devDependencies": {
39 | "@angular-devkit/architect": "^0.1502.4",
40 | "@angular-devkit/build-angular": "^15.2.9",
41 | "@angular-devkit/core": "^15.2.9",
42 | "@angular-devkit/schematics": "^15.2.9",
43 | "@angular/cli": "^15.2.4",
44 | "@angular/compiler": "^15.2.5",
45 | "@angular/compiler-cli": "^15.2.5",
46 | "@angular/language-service": "^15.2.5",
47 | "@ionic/angular-toolkit": "^9.0.0",
48 | "@types/jasmine": "^4.3.5",
49 | "@types/jasminewd2": "^2.0.10",
50 | "@types/node": "^18.15.11",
51 | "compare-func": "^2.0.0",
52 | "cordova-android": "^12.0.1",
53 | "cordova-ios": "^7.0.0",
54 | "cordova-plugin-camera": "7.0.0",
55 | "cordova-plugin-device": "^2.1.0",
56 | "cordova-plugin-file": "8.0.0",
57 | "cordova-plugin-ionic-keyboard": "^2.2.0",
58 | "cordova-plugin-ionic-webview": "^5.0.0",
59 | "cordova-plugin-scanbot-sdk": "4.18.1",
60 | "cordova-plugin-splashscreen": "^6.0.0",
61 | "cordova-plugin-statusbar": "^2.4.3",
62 | "cordova.plugins.diagnostic": "^7.1.1",
63 | "jasmine-core": "5.1.1",
64 | "jasmine-spec-reporter": "^7.0.0",
65 | "karma": "^6.4.1",
66 | "karma-chrome-launcher": "^3.1.1",
67 | "karma-coverage-istanbul-reporter": "^3.0.3",
68 | "karma-jasmine": "^5.1.0",
69 | "karma-jasmine-html-reporter": "^2.1.0",
70 | "ts-node": "^10.9.1",
71 | "typescript": "^4.8.2"
72 | },
73 | "description": "Example App for the Scanbot SDK Cordova Plugin with Ionic Framework",
74 | "cordova": {
75 | "plugins": {
76 | "cordova-plugin-statusbar": {},
77 | "cordova-plugin-device": {},
78 | "cordova-plugin-ionic-keyboard": {},
79 | "cordova-plugin-camera": {},
80 | "cordova-plugin-file": {
81 | "ANDROIDX_WEBKIT_VERSION": "1.4.0"
82 | },
83 | "cordova-plugin-ionic-webview": {
84 | "ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
85 | },
86 | "cordova-plugin-splashscreen": {},
87 | "cordova.plugins.diagnostic": {
88 | "ANDROIDX_VERSION": "[1.0, 1.4]",
89 | "ANDROIDX_APPCOMPAT_VERSION": "1.3.1"
90 | },
91 | "cordova-plugin-scanbot-sdk": {
92 | "CAMERA_USAGE_DESCRIPTION": " "
93 | }
94 | },
95 | "platforms": [
96 | "android",
97 | "ios"
98 | ]
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/resources/README.md:
--------------------------------------------------------------------------------
1 | These are Cordova resources. You can replace icon.png and splash.png and run
2 | `ionic cordova resources` to generate custom icons and splash screens for your
3 | app. See `ionic cordova resources --help` for details.
4 |
5 | Cordova reference documentation:
6 |
7 | - Icons: https://cordova.apache.org/docs/en/latest/config_ref/images.html
8 | - Splash Screens: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-splashscreen/
9 |
--------------------------------------------------------------------------------
/resources/android/icon/drawable-hdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/icon/drawable-hdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-ldpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/icon/drawable-ldpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-mdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/icon/drawable-mdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-xhdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/icon/drawable-xhdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-xxhdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/icon/drawable-xxhdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-xxxhdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/icon/drawable-xxxhdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-hdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/splash/drawable-land-hdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-ldpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/splash/drawable-land-ldpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-mdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/splash/drawable-land-mdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-xhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/splash/drawable-land-xhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-xxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/splash/drawable-land-xxhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-xxxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/splash/drawable-land-xxxhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-hdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/splash/drawable-port-hdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-ldpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/splash/drawable-port-ldpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-mdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/splash/drawable-port-mdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-xhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/splash/drawable-port-xhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-xxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/splash/drawable-port-xxhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-xxxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/android/splash/drawable-port-xxxhdpi-screen.png
--------------------------------------------------------------------------------
/resources/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/icon.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-1024.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-108@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-108@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-20.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-20@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-20@3x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-24@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-24@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-27.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-27.5@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-29.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-29@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-29@3x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-40.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-40@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-40@3x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-44@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-44@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-50.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-50@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-60.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-60@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-60@3x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-72.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-72@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-76.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-76@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-83.5@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-86@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-86@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-98@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-98@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-small.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-small@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon-small@3x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/icon/icon@2x.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-1792h~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-1792h~iphone.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-2436h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-2436h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-2688h~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-2688h~iphone.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-568h@2x~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-568h@2x~iphone.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-667h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-667h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-736h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-736h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape-1792h~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-Landscape-1792h~iphone.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape-2436h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-Landscape-2436h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape-2688h~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-Landscape-2688h~iphone.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape-736h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-Landscape-736h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-Landscape@2x~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape@~ipadpro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-Landscape@~ipadpro.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-Landscape~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Portrait@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-Portrait@2x~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Portrait@~ipadpro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-Portrait@~ipadpro.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Portrait~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default-Portrait~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default@2x~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default@2x~iphone.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default@2x~universal~anyany.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default@2x~universal~anyany.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/ios/splash/Default~iphone.png
--------------------------------------------------------------------------------
/resources/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/resources/splash.png
--------------------------------------------------------------------------------
/scanbot-sdk-app-resources/ios/ScanbotSDKOCRData.bundle/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/scanbot-sdk-app-resources/ios/ScanbotSDKOCRData.bundle/.gitkeep
--------------------------------------------------------------------------------
/scanbot-sdk-app-resources/shared/ocr/deu.traineddata:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/scanbot-sdk-app-resources/shared/ocr/deu.traineddata
--------------------------------------------------------------------------------
/scanbot-sdk-app-resources/shared/ocr/eng.traineddata:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/scanbot-sdk-app-resources/shared/ocr/eng.traineddata
--------------------------------------------------------------------------------
/scanbot-sdk-app-resources/shared/ocr/osd.traineddata:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/scanbot-sdk-app-resources/shared/ocr/osd.traineddata
--------------------------------------------------------------------------------
/src/app/app-routing.module.ts:
--------------------------------------------------------------------------------
1 | import {NgModule} from '@angular/core';
2 | import {Routes, RouterModule} from '@angular/router';
3 |
4 | const routes: Routes = [
5 | {path: '', redirectTo: 'home', pathMatch: 'full'},
6 | {path: 'home', loadChildren: () => import('./home/home.module').then(x => x.HomePageModule)},
7 | {path: 'image-results', loadChildren: () => import('./image-results/image-results.module').then(x => x.ImageResultsPageModule)},
8 | {path: 'image-view/:pageId', loadChildren: () => import('.//image-view/image-view.module').then(x => x.ImageViewPageModule)},
9 | {path: 'barcode-list', loadChildren: () => import('./barcode-list/barcode-list.module').then(x => x.BarcodeListModule)},
10 | {
11 | path: 'barcode-document-list',
12 | loadChildren: () => import('./barcode-document-list/barcode-document-list.module').then(x => x.BarcodeDocumentListModule)
13 | },
14 | {
15 | path: 'barcode-result-list',
16 | loadChildren: () => import('./barcode-result-list/barcode-result-list.module').then(x => x.BarcodeResultListPageModule)
17 | },
18 | {
19 | path: 'generic-document-recognizer-results',
20 | loadChildren: () => import('./generic-document-recognizer-results/generic-document-recognizer-results.module').then(x => x.GenericDocumentRecognizerResultsPageModule)
21 | },
22 | {
23 | path: 'check-recognizer-results',
24 | loadChildren: () => import('./check-recognizer-results/check-recognizer-results.module').then(x => x.CheckRecognizerResultsPageModule)
25 | },
26 | {
27 | path: 'mrz-scanner-results',
28 | loadChildren: () => import('./mrz-scanner-results/mrz-scanner-results.module').then(m => m.MrzScannerResultsPageModule)
29 | },
30 | {
31 | path: 'medical-certificate-scanner-results',
32 | loadChildren: () => import('./medical-certificate-scanner-results/medical-certificate-scanner-results.module').then(m => m.MedicalCertificateScannerResultsPageModule)
33 | },
34 | ];
35 |
36 | @NgModule({
37 | imports: [RouterModule.forRoot(routes)],
38 | exports: [RouterModule]
39 | })
40 | export class AppRoutingModule {
41 | }
42 |
--------------------------------------------------------------------------------
/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
2 | import { TestBed, async } from '@angular/core/testing';
3 |
4 | import { Platform } from '@ionic/angular';
5 | import { StatusBar } from '@awesome-cordova-plugins/status-bar/ngx';
6 |
7 | import { AppComponent } from './app.component';
8 |
9 | describe('AppComponent', () => {
10 |
11 | let statusBarSpy, platformReadySpy, platformSpy;
12 |
13 | beforeEach(async(() => {
14 | statusBarSpy = jasmine.createSpyObj('StatusBar', ['styleDefault']);
15 | platformReadySpy = Promise.resolve();
16 | platformSpy = jasmine.createSpyObj('Platform', { ready: platformReadySpy });
17 |
18 | TestBed.configureTestingModule({
19 | declarations: [AppComponent],
20 | schemas: [CUSTOM_ELEMENTS_SCHEMA],
21 | providers: [
22 | { provide: StatusBar, useValue: statusBarSpy },
23 | { provide: Platform, useValue: platformSpy },
24 | ],
25 | }).compileComponents();
26 | }));
27 |
28 | it('should create the app', () => {
29 | const fixture = TestBed.createComponent(AppComponent);
30 | const app = fixture.debugElement.componentInstance;
31 | expect(app).toBeTruthy();
32 | });
33 |
34 | it('should initialize the app', async () => {
35 | TestBed.createComponent(AppComponent);
36 | expect(platformSpy.ready).toHaveBeenCalled();
37 | await platformReadySpy;
38 | expect(statusBarSpy.styleDefault).toHaveBeenCalled();
39 | });
40 |
41 | // TODO: add more tests!
42 |
43 | });
44 |
--------------------------------------------------------------------------------
/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { Platform } from '@ionic/angular';
3 | import { StatusBar } from '@awesome-cordova-plugins/status-bar/ngx';
4 |
5 |
6 | @Component({
7 | selector: 'app-root',
8 | templateUrl: 'app.component.html'
9 | })
10 | export class AppComponent {
11 | constructor(
12 | private platform: Platform,
13 | private statusBar: StatusBar
14 | ) {
15 | this.initializeApp();
16 | }
17 |
18 | initializeApp() {
19 | this.platform.ready().then(() => {
20 | this.statusBar.styleLightContent();
21 | });
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { RouteReuseStrategy } from '@angular/router';
4 | import { File } from '@awesome-cordova-plugins/file/ngx';
5 |
6 | import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
7 | import { StatusBar } from '@awesome-cordova-plugins/status-bar/ngx';
8 | import { IonicStorageModule } from '@ionic/storage-angular';
9 |
10 | import { AppComponent } from './app.component';
11 | import { AppRoutingModule } from './app-routing.module';
12 | import { DialogsService } from './services/dialogs.service';
13 | import { ScanbotSdkDemoService } from './services/scanbot-sdk-demo.service';
14 | import { ImageResultsRepository } from './services/image-results.repository';
15 |
16 | @NgModule({
17 | declarations: [AppComponent],
18 | imports: [
19 | BrowserModule,
20 | IonicModule.forRoot(),
21 | AppRoutingModule,
22 | IonicStorageModule.forRoot()
23 | ],
24 | providers: [
25 | StatusBar,
26 | { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
27 | DialogsService,
28 | ScanbotSdkDemoService,
29 | ImageResultsRepository,
30 | File
31 | ],
32 | bootstrap: [AppComponent]
33 | })
34 | export class AppModule {}
35 |
--------------------------------------------------------------------------------
/src/app/barcode-document-list/barcode-document-list.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { FormsModule } from '@angular/forms';
4 | import { IonicModule } from '@ionic/angular';
5 | import { RouterModule } from '@angular/router';
6 | import { BarcodeDocumentListPage } from './barcode-document-list.page';
7 |
8 | @NgModule({
9 | imports: [
10 | CommonModule,
11 | FormsModule,
12 | IonicModule,
13 | RouterModule.forChild([
14 | {
15 | path: '',
16 | component: BarcodeDocumentListPage
17 | }
18 | ])
19 | ],
20 | declarations: [BarcodeDocumentListPage]
21 | })
22 |
23 | export class BarcodeDocumentListModule { }
24 |
--------------------------------------------------------------------------------
/src/app/barcode-document-list/barcode-document-list.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Accepted Documents
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Enable Document Filters
16 |
17 |
18 |
19 |
20 | Filters
21 |
22 |
23 |
24 | {{documentType.key}}
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/app/barcode-document-list/barcode-document-list.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, NgZone } from '@angular/core';
2 | import { BarcodeDocumentListService } from '../services/barcode-document-list.service';
3 | import { BarcodeDocumentFormat } from 'cordova-plugin-scanbot-sdk';
4 |
5 | @Component({
6 | selector: 'app-barcode-document-list',
7 | templateUrl: 'barcode-document-list.page.html',
8 | })
9 | export class BarcodeDocumentListPage {
10 |
11 | documentTypes: Array<{ key: BarcodeDocumentFormat, value: boolean }> = [];
12 | isFilteringEnabled: boolean;
13 |
14 | constructor(private ngZone: NgZone) {
15 | this.documentTypes = BarcodeDocumentListService.list;
16 | this.isFilteringEnabled = BarcodeDocumentListService.isFilteringEnabled;
17 | }
18 |
19 | onChange($event: CustomEvent) {
20 | const key = $event.detail.value;
21 | const value = $event.detail.checked;
22 | BarcodeDocumentListService.update(key, value);
23 | }
24 |
25 | onEnabledChange($event: CustomEvent) {
26 | BarcodeDocumentListService.isFilteringEnabled = $event.detail.checked;
27 | this.ngZone.run(() => {
28 | this.isFilteringEnabled = BarcodeDocumentListService.isFilteringEnabled;
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/app/barcode-list/barcode-list.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import {FormsModule} from '@angular/forms';
4 | import {IonicModule} from '@ionic/angular';
5 | import {RouterModule} from '@angular/router';
6 | import {BarcodeListPage} from './barcode-list.page';
7 |
8 | @NgModule({
9 | imports: [
10 | CommonModule,
11 | FormsModule,
12 | IonicModule,
13 | RouterModule.forChild([
14 | {
15 | path: '',
16 | component: BarcodeListPage
17 | }
18 | ])
19 | ],
20 | declarations: [BarcodeListPage]
21 | })
22 |
23 | export class BarcodeListModule { }
24 |
--------------------------------------------------------------------------------
/src/app/barcode-list/barcode-list.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Accepted Barcode Formats
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | {{barcode.key}}
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/app/barcode-list/barcode-list.page.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { BarcodeListService } from '../services/barcode-list.service';
3 | import { BarcodeFormat } from 'cordova-plugin-scanbot-sdk';
4 |
5 | @Component({
6 | selector: 'app-barcode-list',
7 | templateUrl: 'barcode-list.page.html',
8 | })
9 | export class BarcodeListPage {
10 |
11 | barcodes: Array<{ key: BarcodeFormat, value: boolean }> = [];
12 |
13 | constructor() {
14 | this.barcodes = BarcodeListService.items;
15 | }
16 |
17 | onChange($event: CustomEvent) {
18 | const format = $event.detail.value;
19 | const isChecked = $event.detail.checked;
20 | BarcodeListService.update(format, isChecked);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/app/barcode-result-list/barcode-result-list.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { FormsModule } from '@angular/forms';
4 | import { RouterModule } from '@angular/router';
5 | import { IonicModule } from '@ionic/angular';
6 | import { BarcodeResultListPage } from './barcode-result-list.page';
7 |
8 | @NgModule({
9 | imports: [
10 | CommonModule,
11 | FormsModule,
12 | IonicModule,
13 | RouterModule.forChild([
14 | {
15 | path: '',
16 | component: BarcodeResultListPage
17 | }
18 | ])
19 | ],
20 | declarations: [BarcodeResultListPage]
21 | })
22 |
23 | export class BarcodeResultListPageModule {}
24 |
--------------------------------------------------------------------------------
/src/app/barcode-result-list/barcode-result-list.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Detected Barcodes
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
1">
15 | Result {{count + 1}}
16 |
17 |
18 |
19 |
![]()
20 |
21 |
22 |
23 | Detected Barcodes:
24 |
25 |
26 |
27 |
28 | None
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | {{barcode.type}}
37 |
38 |
39 | {{ barcode.textWithExtension }}
40 |
41 |
42 |
43 |
44 | {{"RawBytes"}}
45 |
46 |
47 | {{barcode.rawBytesString}}
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/src/app/barcode-result-list/barcode-result-list.page.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/src/app/barcode-result-list/barcode-result-list.page.scss
--------------------------------------------------------------------------------
/src/app/barcode-result-list/barcode-result-list.page.spec.ts:
--------------------------------------------------------------------------------
1 | import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
3 |
4 | import { BarcodeResultListPage } from './barcode-result-list.page';
5 |
6 | describe('BarcodeResultListPage', () => {
7 | let component: BarcodeResultListPage;
8 | let fixture: ComponentFixture;
9 |
10 | beforeEach(async(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [ BarcodeResultListPage ],
13 | schemas: [CUSTOM_ELEMENTS_SCHEMA],
14 | })
15 | .compileComponents();
16 | }));
17 |
18 | beforeEach(() => {
19 | fixture = TestBed.createComponent(BarcodeResultListPage);
20 | component = fixture.componentInstance;
21 | fixture.detectChanges();
22 | });
23 |
24 | it('should create', () => {
25 | expect(component).toBeTruthy();
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/src/app/barcode-result-list/barcode-result-list.page.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 | import {BarcodeListService, BarcodesDetectionViewModel} from '../services/barcode-list.service';
3 | import {ByteArrayUtils} from 'src/utils/byte-array-utils';
4 | import {ImageResultsRepository} from '../services/image-results.repository';
5 |
6 | @Component({
7 | selector: 'app-barcode-result-list',
8 | templateUrl: './barcode-result-list.page.html',
9 | styleUrls: ['./barcode-result-list.page.scss'],
10 | })
11 | export class BarcodeResultListPage {
12 |
13 | detectedBarcodes: BarcodesDetectionViewModel[];
14 |
15 | constructor(private imageResultsRepository: ImageResultsRepository,) {
16 | let detectedBarcodes = BarcodeListService.detectedBarcodes || [];
17 |
18 | detectedBarcodes = detectedBarcodes.map((item) => {
19 | if (item.snappedImage) {
20 | item.snappedImage = this.imageResultsRepository.sanitizeFileUri(item.snappedImage);
21 | }
22 |
23 | item.barcodes.forEach(element => {
24 | element.rawBytesString = ByteArrayUtils.toString(element.rawBytes);
25 | });
26 | return item;
27 | });
28 |
29 | this.detectedBarcodes = detectedBarcodes;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/app/check-recognizer-results/check-recognizer-results.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { FormsModule } from '@angular/forms';
4 | import { Routes, RouterModule } from '@angular/router';
5 |
6 | import { IonicModule } from '@ionic/angular';
7 |
8 | import { CheckRecognizerResultsPage } from './check-recognizer-results.page';
9 | import { SectionListComponent } from '../section-list/section-list.component';
10 |
11 | const routes: Routes = [
12 | {
13 | path: '',
14 | component: CheckRecognizerResultsPage
15 | }
16 | ];
17 |
18 | @NgModule({
19 | imports: [
20 | CommonModule,
21 | FormsModule,
22 | IonicModule,
23 | RouterModule.forChild(routes),
24 | SectionListComponent
25 | ],
26 | declarations: [CheckRecognizerResultsPage]
27 | })
28 | export class CheckRecognizerResultsPageModule {}
29 |
--------------------------------------------------------------------------------
/src/app/check-recognizer-results/check-recognizer-results.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Check Recognizer Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/app/check-recognizer-results/check-recognizer-results.page.spec.ts:
--------------------------------------------------------------------------------
1 | import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
3 |
4 | import { CheckRecognizerResultsPage } from './check-recognizer-results.page';
5 |
6 | describe('CheckRecognizerResultsPage', () => {
7 | let component: CheckRecognizerResultsPage;
8 | let fixture: ComponentFixture;
9 |
10 | beforeEach(async(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [ CheckRecognizerResultsPage ],
13 | schemas: [CUSTOM_ELEMENTS_SCHEMA],
14 | })
15 | .compileComponents();
16 | }));
17 |
18 | beforeEach(() => {
19 | fixture = TestBed.createComponent(CheckRecognizerResultsPage);
20 | component = fixture.componentInstance;
21 | fixture.detectChanges();
22 | });
23 |
24 | it('should create', () => {
25 | expect(component).toBeTruthy();
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/src/app/check-recognizer-results/check-recognizer-results.page.ts:
--------------------------------------------------------------------------------
1 | import {Component, OnInit} from '@angular/core';
2 | import {CheckRecognizerResult} from 'cordova-plugin-scanbot-sdk';
3 | import {ScanResultSection, ScanResultSectionList} from '../section-list/section-list.component';
4 | import {ScannerResultsService} from '../services/scanner-results.service';
5 | import {GenericDocumentUtils} from '../../utils/gdr-utils';
6 | import {ImageResultsRepository} from '../services/image-results.repository';
7 |
8 |
9 | @Component({
10 | selector: 'app-check-recognizer-results',
11 | templateUrl: './check-recognizer-results.page.html',
12 | })
13 | export class CheckRecognizerResultsPage implements OnInit {
14 | checkResult: CheckRecognizerResult;
15 | displayFields: ScanResultSectionList;
16 |
17 | constructor(
18 | private imageResultsRepository: ImageResultsRepository,
19 | ) {
20 | }
21 |
22 | async ngOnInit() {
23 | this.checkResult = ScannerResultsService.checkRecognizerResult;
24 | this.displayFields = await this.setupProperties();
25 | }
26 |
27 | private async setupProperties(): Promise {
28 |
29 | const commonSection: ScanResultSection = {
30 | title: 'Check Result',
31 | data: [
32 | {
33 | key: 'Recognition Status',
34 | value: this.checkResult.checkStatus,
35 | },
36 | {
37 | key: 'Check Type',
38 | value: this.checkResult.checkType,
39 | },
40 | {
41 | key: 'Recognition confidence',
42 | value: this.checkResult.check.confidence.toString(),
43 | },
44 | ]
45 | };
46 |
47 | if (this.checkResult.imageFileUri) {
48 | commonSection.data.unshift({
49 | key: 'Check Image',
50 | image: this.imageResultsRepository.sanitizeFileUri(this.checkResult.imageFileUri),
51 | });
52 | }
53 |
54 | const checkFieldsSection: ScanResultSection = {
55 | title: this.checkResult.check.type.name,
56 | data: GenericDocumentUtils.gdrFields(this.checkResult.check)
57 | };
58 |
59 | return [
60 | commonSection,
61 | checkFieldsSection
62 | ];
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/app/generic-document-recognizer-results/generic-document-recognizer-results.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { FormsModule } from '@angular/forms';
4 | import { Routes, RouterModule } from '@angular/router';
5 |
6 | import { IonicModule } from '@ionic/angular';
7 |
8 | import { GenericDocumentRecognizerResultsPage } from './generic-document-recognizer-results.page';
9 | import {SectionListComponent} from '../section-list/section-list.component';
10 |
11 | const routes: Routes = [
12 | {
13 | path: '',
14 | component: GenericDocumentRecognizerResultsPage
15 | }
16 | ];
17 |
18 | @NgModule({
19 | imports: [
20 | CommonModule,
21 | FormsModule,
22 | IonicModule,
23 | RouterModule.forChild(routes),
24 | SectionListComponent
25 | ],
26 | declarations: [GenericDocumentRecognizerResultsPage]
27 | })
28 | export class GenericDocumentRecognizerResultsPageModule {}
29 |
--------------------------------------------------------------------------------
/src/app/generic-document-recognizer-results/generic-document-recognizer-results.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Generic Document Recognizer Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/app/generic-document-recognizer-results/generic-document-recognizer-results.page.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/src/app/generic-document-recognizer-results/generic-document-recognizer-results.page.scss
--------------------------------------------------------------------------------
/src/app/generic-document-recognizer-results/generic-document-recognizer-results.page.spec.ts:
--------------------------------------------------------------------------------
1 | import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
3 |
4 | import { GenericDocumentRecognizerResultsPage } from './generic-document-recognizer-results.page';
5 |
6 | describe('GenericDocumentRecognizerResultsPage', () => {
7 | let component: GenericDocumentRecognizerResultsPage;
8 | let fixture: ComponentFixture;
9 |
10 | beforeEach(async(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [ GenericDocumentRecognizerResultsPage ],
13 | schemas: [CUSTOM_ELEMENTS_SCHEMA],
14 | })
15 | .compileComponents();
16 | }));
17 |
18 | beforeEach(() => {
19 | fixture = TestBed.createComponent(GenericDocumentRecognizerResultsPage);
20 | component = fixture.componentInstance;
21 | fixture.detectChanges();
22 | });
23 |
24 | it('should create', () => {
25 | expect(component).toBeTruthy();
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/src/app/generic-document-recognizer-results/generic-document-recognizer-results.page.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 | import {DomSanitizer} from '@angular/platform-browser';
3 | import {ScanResultSection, ScanResultSectionList} from '../section-list/section-list.component';
4 | import {
5 | CategoriesDocument,
6 | DeDriverLicenseBackDocument,
7 | DeDriverLicenseFrontDocument,
8 | DeIdCardBackDocument,
9 | DeIdCardFrontDocument,
10 | DePassportDocument,
11 | Field,
12 | GenericDocumentRecognizerResult
13 | } from 'cordova-plugin-scanbot-sdk';
14 | import {GenericDocumentUtils} from '../../utils/gdr-utils';
15 | import {ScannerResultsService} from '../services/scanner-results.service';
16 |
17 | @Component({
18 | selector: 'app-generic-document-recognizer-results',
19 | templateUrl: './generic-document-recognizer-results.page.html',
20 | styleUrls: ['./generic-document-recognizer-results.page.scss'],
21 | })
22 | export class GenericDocumentRecognizerResultsPage {
23 |
24 | genericDocumentResult: GenericDocumentRecognizerResult;
25 | displayFields: ScanResultSectionList;
26 |
27 | constructor(public sanitizer: DomSanitizer) {
28 | this.genericDocumentResult = ScannerResultsService.genericDocumentRecognizerResult;
29 | this.displayFields = this.setupProperties();
30 | }
31 |
32 | private setupProperties(): ScanResultSectionList {
33 | return this.genericDocumentResult.documents
34 | .map(document => {
35 | switch (document.type.name) {
36 | case 'DeDriverLicenseBack':
37 | return this.deDriverLicenseBackFields(
38 | document as DeDriverLicenseBackDocument,
39 | );
40 | case 'DeDriverLicenseFront':
41 | return this.deDriverLicenseFrontFields(
42 | document as DeDriverLicenseFrontDocument,
43 | );
44 | case 'DeIdCardBack':
45 | return this.deIdCardBackFields(document as DeIdCardBackDocument);
46 | case 'DeIdCardFront':
47 | return this.deIdCardFrontFields(document as DeIdCardFrontDocument);
48 | case 'DePassport':
49 | return this.dePassportFields(document as DePassportDocument);
50 | default:
51 | return [];
52 | }
53 | })
54 | .flat(1);
55 | }
56 |
57 | // German Passport - Display Utility Method
58 | private dePassportFields = (
59 | passportDocument: DePassportDocument,
60 | ): ScanResultSection[] => [
61 | {
62 | title: 'German Passport',
63 | data: [
64 | ...GenericDocumentUtils.gdrCommonFields(passportDocument),
65 | ...GenericDocumentUtils.gdrFields(passportDocument),
66 | ],
67 | },
68 | {
69 | title: 'Passport MRZ',
70 | data: [
71 | ...GenericDocumentUtils.gdrCommonFields(passportDocument.mrz),
72 | ...GenericDocumentUtils.gdrFields(passportDocument.mrz),
73 | ],
74 | },
75 | ];
76 |
77 | // German ID Card (FRONT) - Display Utility Method
78 | private deIdCardFrontFields = (idCardDocument: DeIdCardFrontDocument) => [
79 | {
80 | title: 'German ID Card Front',
81 | data: [
82 | ...GenericDocumentUtils.gdrCommonFields(idCardDocument),
83 | ...GenericDocumentUtils.gdrFields(idCardDocument),
84 | ],
85 | },
86 | ];
87 |
88 | // German ID Card (BACK) - Display Utility Method
89 | private deIdCardBackFields = (idCardDocument: DeIdCardBackDocument) => [
90 | {
91 | title: 'German ID Card Back',
92 | data: [
93 | ...GenericDocumentUtils.gdrCommonFields(idCardDocument),
94 | ...GenericDocumentUtils.gdrFields(idCardDocument),
95 | ],
96 | },
97 | {
98 | title: 'ID Card MRZ',
99 | data: [
100 | ...GenericDocumentUtils.gdrCommonFields(idCardDocument.mrz),
101 | ...GenericDocumentUtils.gdrFields(idCardDocument.mrz),
102 | ],
103 | },
104 | ];
105 |
106 | // Driver License (FRONT) - Display Utility Method
107 | private deDriverLicenseFrontFields = (
108 | driversLicense: DeDriverLicenseFrontDocument,
109 | ) => [
110 | {
111 | title: 'German Drivers licence Front',
112 | data: [
113 | ...GenericDocumentUtils.gdrCommonFields(driversLicense),
114 | ...GenericDocumentUtils.gdrFields(driversLicense),
115 | ],
116 | },
117 | ];
118 |
119 | // Driver License (BACK) - Display Utility Method
120 | private deDriverLicenseBackFields = (
121 | driversLicense: DeDriverLicenseBackDocument,
122 | ) => [
123 | {
124 | title: 'German Drivers licence Back',
125 | data: [
126 | ...GenericDocumentUtils.gdrCommonFields(driversLicense),
127 | ...GenericDocumentUtils.gdrFields(driversLicense),
128 | ],
129 | },
130 | ...this.driverLicenseBackCategoryFields(driversLicense.categories),
131 | ];
132 |
133 | // Driver License (BACK - Categories) - Display Utility Method
134 | private driverLicenseBackCategoryFields = (categories: CategoriesDocument) => [
135 | this.getDriverLicenseCategoryField('A', categories.a),
136 | this.getDriverLicenseCategoryField('A1', categories.a1),
137 | this.getDriverLicenseCategoryField('A2', categories.a2),
138 | this.getDriverLicenseCategoryField('B', categories.b),
139 | this.getDriverLicenseCategoryField('B1', categories.b1),
140 | this.getDriverLicenseCategoryField('BE', categories.be),
141 | this.getDriverLicenseCategoryField('C', categories.c),
142 | this.getDriverLicenseCategoryField('C1', categories.c1),
143 | this.getDriverLicenseCategoryField('C1E', categories.c1e),
144 | this.getDriverLicenseCategoryField('CE', categories.ce),
145 | this.getDriverLicenseCategoryField('D', categories.d),
146 | this.getDriverLicenseCategoryField('D1', categories.d1),
147 | this.getDriverLicenseCategoryField('D1E', categories.d1e),
148 | this.getDriverLicenseCategoryField('DE', categories.de),
149 | this.getDriverLicenseCategoryField('L', categories.l),
150 | this.getDriverLicenseCategoryField('M', categories.m),
151 | this.getDriverLicenseCategoryField('T', categories.t),
152 | ];
153 |
154 | // Driver License Category - Display Utility Method
155 | private getDriverLicenseCategoryField = (
156 | displayName: string,
157 | category?: {
158 | validFrom: Field;
159 | validUntil: Field;
160 | },
161 | ) => {
162 | if (category === undefined) {
163 | return {
164 | title: displayName,
165 | data: [],
166 | };
167 | }
168 |
169 | const from = category?.validFrom.value?.text ?? 'N/A';
170 | const until = category?.validUntil.value?.text ?? 'N/A';
171 |
172 | return {
173 | title: displayName,
174 | data: [
175 | {
176 | key: displayName,
177 | value: `From ${from} to ${until}`,
178 | },
179 | ],
180 | };
181 | };
182 |
183 |
184 | }
185 |
--------------------------------------------------------------------------------
/src/app/home/home.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { IonicModule } from '@ionic/angular';
4 | import { FormsModule } from '@angular/forms';
5 | import { RouterModule } from '@angular/router';
6 |
7 | import { HomePage } from './home.page';
8 |
9 | @NgModule({
10 | imports: [
11 | CommonModule,
12 | FormsModule,
13 | IonicModule,
14 | RouterModule.forChild([
15 | {
16 | path: '',
17 | component: HomePage
18 | }
19 | ])
20 | ],
21 | declarations: [HomePage]
22 | })
23 | export class HomePageModule {}
24 |
--------------------------------------------------------------------------------
/src/app/home/home.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ScanbotSDK Ionic
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | Document Scanner
15 |
16 |
17 | Scan Document
18 |
19 |
20 | Scan Document with Finder
21 |
22 |
23 | Import Image & Detect Document
24 |
25 |
26 | Import Image & Detect Document (JSON)
27 |
28 |
29 | View Image Results
30 |
31 |
32 |
33 |
34 |
35 | Barcode Detector
36 |
37 |
38 | Scan QR-/Barcode
39 |
40 |
41 | Scan Batch of QR-/Barcodes
42 |
43 |
44 | Import Image & Detect Barcodes
45 |
46 |
47 | Set Barcode Formats Filter
48 |
49 |
50 | Set Barcode Document Formats Filter
51 |
52 |
53 |
54 |
55 |
56 | Data Detectors
57 |
58 |
59 | Scan MRZ on ID Card
60 |
61 |
62 | Scan Medical Certificate
63 |
64 |
65 | Scan Generic Documents
66 |
67 |
68 | Scan Checks
69 |
70 |
71 | Scan Health Insurance Card
72 |
73 |
74 | Scan License Plate (ML)
75 |
76 |
77 | Scan License Plate (CLASSIC)
78 |
79 |
80 | Start Text Data Scanner
81 |
82 |
83 | Start VIN Scanner
84 |
85 |
86 | Import Image & Recognize Check
87 |
88 |
89 |
90 |
91 |
92 | Miscellaneous
93 |
94 |
95 | View License Info
96 |
97 |
98 | View OCR Configs
99 |
100 |
101 | Import Image & Apply Filter
102 |
103 |
104 |
105 | Learn More About the Scanbot SDK
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | Copyright (c) 2020 doo GmbH. All rights reserved.
114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/src/app/home/home.page.scss:
--------------------------------------------------------------------------------
1 |
2 | .copyright-label {
3 | width: 100%;
4 | text-align: center;
5 | font-size: 0.60em;
6 | color: #8c8c8c;
7 | margin-bottom: 15px;
8 | }
9 |
--------------------------------------------------------------------------------
/src/app/home/home.page.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 | import {Router} from '@angular/router';
3 | import {ActionSheetController} from '@ionic/angular';
4 |
5 | import {
6 | BatchBarcodeScannerConfiguration,
7 | CheckRecognizerConfiguration,
8 | GenericDocumentRecognizerConfiguration,
9 | HealthInsuranceCardScannerConfiguration,
10 | LicensePlateScannerConfiguration,
11 | LicensePlateScanStrategy,
12 | MedicalCertificateRecognizerConfiguration,
13 | MrzScannerConfiguration,
14 | TextDataScannerConfiguration,
15 | VinScannerConfiguration
16 | } from 'cordova-plugin-scanbot-sdk';
17 |
18 | import {Camera, PictureSourceType} from '@ionic-native/camera';
19 | import {BarcodeDocumentListService} from '../services/barcode-document-list.service';
20 | import {BarcodeListService} from '../services/barcode-list.service';
21 | import {DialogsService} from '../services/dialogs.service';
22 | import {ImageResultsRepository} from '../services/image-results.repository';
23 | import {ScanbotSdkDemoService} from '../services/scanbot-sdk-demo.service';
24 | import {ScannerResultsService} from '../services/scanner-results.service';
25 | import {IMAGE_FILTER_LIST} from '../../utils/image-filters';
26 |
27 | @Component({
28 | selector: 'app-home',
29 | templateUrl: 'home.page.html',
30 | styleUrls: ['home.page.scss'],
31 | })
32 | export class HomePage {
33 |
34 | constructor(
35 | private scanbotService: ScanbotSdkDemoService,
36 | private imageResultsRepository: ImageResultsRepository,
37 | private dialogsService: DialogsService,
38 | private actionSheetController: ActionSheetController,
39 | private router: Router
40 | ) {
41 | }
42 |
43 | async startDocumentScanner() {
44 | try {
45 | if (!(await this.scanbotService.checkLicense())) {
46 | return;
47 | }
48 |
49 | const configs = this.scanbotService.globalDocScannerConfigs();
50 | const result = await this.scanbotService.SDK.UI.startDocumentScanner({uiConfigs: configs});
51 |
52 | if (result.status === 'CANCELED') {
53 | // user has canceled the scanning operation
54 | return;
55 | }
56 |
57 | await this.imageResultsRepository.addPages(result.pages);
58 | await this.gotoImageResults();
59 | } catch (e) {
60 | await this.dialogsService.showAlert(e.message);
61 | }
62 | }
63 |
64 | async startFinderDocumentScanner() {
65 | try {
66 | if (!(await this.scanbotService.checkLicense())) {
67 | return;
68 | }
69 |
70 | const configs = this.scanbotService.globalFinderDocScannerConfigs();
71 | const result = await this.scanbotService.SDK.UI.startFinderDocumentScanner({uiConfigs: configs});
72 |
73 | if (result.status === 'CANCELED') {
74 | // user has canceled the scanning operation
75 | return;
76 | }
77 |
78 | await this.imageResultsRepository.updatePage(result.pages[0]);
79 | await this.gotoImageResults();
80 | } catch (e) {
81 | await this.dialogsService.showAlert(e.message);
82 | }
83 | }
84 |
85 | async pickImageFromPhotoLibrary() {
86 | // Import an image from Photo Library and run auto document detection on it.
87 |
88 | const imageFileUri = await Camera.getPicture({
89 | sourceType: PictureSourceType.PHOTOLIBRARY
90 | });
91 |
92 | if (!(await this.scanbotService.checkLicense())) {
93 | return;
94 | }
95 |
96 | const loading = await this.dialogsService.createLoading('Auto-detecting and cropping...');
97 | try {
98 | await loading.present();
99 |
100 | // First create a new SDK page with the selected original image file:
101 | const createResult = await this.scanbotService.SDK.createPage({originalImageFileUri: imageFileUri});
102 | // and then run auto document detection and cropping on this new page:
103 | const docResult = await this.scanbotService.SDK.detectDocumentOnPage({page: createResult});
104 |
105 | await this.imageResultsRepository.addPages([docResult]);
106 | await this.gotoImageResults();
107 | } catch (e: any) {
108 | console.error('Unable to process selected image.', e);
109 | await this.dialogsService.showAlert(e.message, 'ERROR', 'Unable to process selected image.');
110 | } finally {
111 | await loading.dismiss();
112 | }
113 | }
114 |
115 | async detectDocumentOnImage() {
116 | const imageFileUri = await Camera.getPicture({
117 | sourceType: PictureSourceType.PHOTOLIBRARY
118 | });
119 |
120 | if (!(await this.scanbotService.checkLicense())) {
121 | return;
122 | }
123 |
124 | const loading = await this.dialogsService.createLoading('Detecting...');
125 | try {
126 | await loading.present();
127 |
128 | // Detect document on selected image
129 | const result = await this.scanbotService.SDK.detectDocument({imageFileUri});
130 | // Analyze document quality on selected image
131 | const quality = await this.scanbotService.SDK.documentQualityAnalyzer({imageFileUri});
132 |
133 | await this.dialogsService.showAlert(`Detected Document result: ${JSON.stringify(result, null, 2)}\n` +
134 | `Document Quality result: ${JSON.stringify(quality, null, 2)}`, 'Document detection');
135 |
136 | } catch (e: any) {
137 | console.error('Unable to process selected image.', e);
138 | await this.dialogsService.showAlert(e.message, 'ERROR', 'Unable to process selected image.');
139 | } finally {
140 | await loading.dismiss();
141 | }
142 | }
143 |
144 | async gotoImageResults() {
145 | await this.router.navigateByUrl('/image-results');
146 | }
147 |
148 | async startBarcodeScanner() {
149 | try {
150 | if (!(await this.scanbotService.checkLicense())) {
151 | return;
152 | }
153 |
154 | const result = await this.scanbotService.SDK.UI.startBarcodeScanner({
155 | uiConfigs: {
156 | // Customize colors, text resources, behavior, etc..
157 | finderTextHint: 'Please align the barcode or QR code in the frame above to scan it.',
158 | barcodeFormats: BarcodeListService.getAcceptedTypes(),
159 | acceptedDocumentFormats: BarcodeDocumentListService.getAcceptedFormats(),
160 | finderLineColor: '#0000ff',
161 | finderAspectRatio: {width: 2, height: 1},
162 | topBarBackgroundColor: '#c8193c',
163 | useButtonsAllCaps: false,
164 | // msiPlesseyChecksumAlgorithm: 'Mod1110NCR',
165 | // see further configs ...
166 | }
167 | });
168 |
169 | if (result.status === 'OK') {
170 | BarcodeListService.detectedBarcodes = [{
171 | barcodes: result.barcodes || [],
172 | }];
173 | await this.router.navigateByUrl('/barcode-result-list');
174 | }
175 | } catch (e) {
176 | await this.dialogsService.showAlert(e.message);
177 | }
178 | }
179 |
180 | async startBatchBarcodeScanner() {
181 | try {
182 | if (!(await this.scanbotService.checkLicense())) {
183 | return;
184 | }
185 |
186 | const configs: BatchBarcodeScannerConfiguration = {
187 | // Customize colors, text resources, behavior, etc..
188 | finderTextHint: 'Please align the barcode or QR code in the frame above to scan it.',
189 | barcodeFormats: BarcodeListService.getAcceptedTypes(),
190 | acceptedDocumentFormats: BarcodeDocumentListService.getAcceptedFormats(),
191 | finderAspectRatio: {width: 1, height: 1},
192 | orientationLockMode: 'NONE',
193 | useButtonsAllCaps: false,
194 | // msiPlesseyChecksumAlgorithm: 'Mod1110NCR',
195 | // see further configs ...
196 | };
197 |
198 | const result = await this.scanbotService.SDK.UI.startBatchBarcodeScanner({uiConfigs: configs});
199 |
200 | if (result.status === 'OK') {
201 | BarcodeListService.detectedBarcodes = [{
202 | barcodes: result.barcodes || [],
203 | }];
204 | await this.router.navigateByUrl('/barcode-result-list');
205 | }
206 | } catch (e) {
207 | await this.dialogsService.showAlert(e.message);
208 | }
209 | }
210 |
211 | async startGenericDocumentRecognizer() {
212 | try {
213 | if (!(await this.scanbotService.checkLicense())) {
214 | return;
215 | }
216 |
217 | const config: GenericDocumentRecognizerConfiguration = {
218 | finderLineColor: '#ff0000',
219 | };
220 | const result = await this.scanbotService.SDK.UI.startGenericDocumentRecognizer({uiConfigs: config});
221 |
222 | console.log(JSON.stringify(result));
223 |
224 | if (result.status === 'OK') {
225 | ScannerResultsService.genericDocumentRecognizerResult = result;
226 | await this.router.navigateByUrl('/generic-document-recognizer-results');
227 | }
228 | } catch (e) {
229 | await this.dialogsService.showAlert(e.message);
230 | }
231 | }
232 |
233 | async startCheckRecognizer() {
234 | try {
235 | if (!(await this.scanbotService.checkLicense())) {
236 | return;
237 | }
238 |
239 | const config: CheckRecognizerConfiguration = {};
240 | const result = await this.scanbotService.SDK.UI.startCheckRecognizer({uiConfigs: config});
241 |
242 | console.log(JSON.stringify(result));
243 |
244 | if (result.status === 'OK') {
245 | ScannerResultsService.checkRecognizerResult = result;
246 | await this.router.navigateByUrl('/check-recognizer-results');
247 | } else {
248 | await this.dialogsService.showAlert(result.status, 'Check Recognition Failed');
249 | }
250 | } catch (e) {
251 | await this.dialogsService.showAlert(e.message);
252 | }
253 | }
254 |
255 | async startMrzScanner() {
256 | try {
257 | if (!(await this.scanbotService.checkLicense())) {
258 | return;
259 | }
260 |
261 | const config: MrzScannerConfiguration = {
262 | // Customize colors, text resources, etc..
263 | finderTextHint: 'Please hold your phone over the 2- or 3-line MRZ code at the front of your passport.',
264 | orientationLockMode: 'PORTRAIT',
265 | // see further configs ...
266 | };
267 |
268 | const result = await this.scanbotService.SDK.UI.startMrzScanner({uiConfigs: config});
269 | if (result.status === 'OK') {
270 | ScannerResultsService.mrzScannerResult = result;
271 | await this.router.navigateByUrl('/mrz-scanner-results');
272 | }
273 | } catch (e) {
274 | await this.dialogsService.showAlert(e.message);
275 | }
276 | }
277 |
278 | async startEHICScanner() {
279 | try {
280 | if (!(await this.scanbotService.checkLicense())) {
281 | return;
282 | }
283 |
284 | const config: HealthInsuranceCardScannerConfiguration = {
285 | finderTextHint: 'Please hold your phone over the back of your Health Insurance Card.',
286 | orientationLockMode: 'PORTRAIT',
287 | // see further configs ...
288 | };
289 | const result = await this.scanbotService.SDK.UI.startEHICScanner({uiConfigs: config});
290 | if (result.status === 'OK') {
291 | const fields = result.fields.map(f => `${f.type}: ${f.value} (${f.confidence.toFixed(2)})
`);
292 | await this.dialogsService.showAlert(fields.join(''), 'EHIC Result');
293 | }
294 | } catch (e) {
295 | await this.dialogsService.showAlert(e.message);
296 | }
297 | }
298 |
299 | async setAcceptedBarcodeFormats() {
300 | await this.router.navigateByUrl('/barcode-list');
301 | }
302 |
303 | async setAcceptedBarcodeDocumentFormats() {
304 | await this.router.navigateByUrl('/barcode-document-list');
305 | }
306 |
307 | async viewLicenseInfo() {
308 | const result = await this.scanbotService.SDK.getLicenseInfo();
309 | await this.dialogsService.showAlert(JSON.stringify(result), 'License Info');
310 | }
311 |
312 | async viewOcrConfigs() {
313 | const result = await this.scanbotService.SDK.getOcrConfigs();
314 | await this.dialogsService.showAlert(JSON.stringify(result), 'OCR Configs');
315 | }
316 |
317 | async importAndDetectBarcodes() {
318 | try {
319 | if (!(await this.scanbotService.checkLicense())) {
320 | return;
321 | }
322 |
323 | const imageFileUri = await Camera.getPicture({
324 | sourceType: PictureSourceType.PHOTOLIBRARY
325 | });
326 |
327 | const loading = await this.dialogsService.createLoading('Detecting barcodes...');
328 | await loading.present();
329 | const result = await this.scanbotService.SDK.detectBarcodesOnImage({
330 | imageFileUri,
331 | barcodeFormats: BarcodeListService.getAcceptedTypes()
332 | });
333 |
334 | if (result.status !== 'OK') {
335 | await loading.dismiss();
336 | await this.dialogsService.showAlert('ERROR', '');
337 | }
338 |
339 | BarcodeListService.detectedBarcodes = [{
340 | barcodes: result.barcodes || [],
341 | snappedImage: imageFileUri
342 | }];
343 |
344 | await loading.dismiss();
345 | await this.router.navigateByUrl('/barcode-result-list');
346 | } catch (e) {
347 | await this.dialogsService.showAlert(e.message);
348 | }
349 | }
350 |
351 | async importAndRecognizeCheck() {
352 | try {
353 | if (!(await this.scanbotService.checkLicense())) {
354 | return;
355 | }
356 |
357 | const imageFileUri = await Camera.getPicture({
358 | sourceType: PictureSourceType.PHOTOLIBRARY
359 | });
360 |
361 | const loading = await this.dialogsService.createLoading('Recognizing check...');
362 | await loading.present();
363 | const result = await this.scanbotService.SDK.recognizeCheckOnImage({
364 | imageFileUri,
365 | });
366 |
367 | await loading.dismiss();
368 |
369 | if (result.status === 'OK') {
370 | ScannerResultsService.checkRecognizerResult = result;
371 | await this.router.navigateByUrl('/check-recognizer-results');
372 | } else {
373 | await this.dialogsService.showAlert(result.status, 'Check Recognition Failed');
374 | }
375 | } catch (e) {
376 | await this.dialogsService.showAlert(e.message);
377 | }
378 | }
379 |
380 | async startLicensePlateScanner(mode: LicensePlateScanStrategy) {
381 | try {
382 | if (!(await this.scanbotService.checkLicense())) {
383 | return;
384 | }
385 |
386 | const config: LicensePlateScannerConfiguration = {
387 | scanStrategy: mode,
388 | topBarBackgroundColor: '#c8193c',
389 | topBarButtonsActiveColor: '#ffffff',
390 | cancelButtonTitle: 'Cancel',
391 | finderLineColor: '#c8193c',
392 | finderLineWidth: 5,
393 | finderTextHint: 'Place the whole license plate in the frame to scan it',
394 | orientationLockMode: 'PORTRAIT',
395 | confirmationDialogConfirmButtonFilled: true,
396 | // see further configs...
397 | };
398 |
399 | const result = await this.scanbotService.SDK.UI.startLicensePlateScanner({uiConfigs: config});
400 |
401 | if (result.status === 'OK') {
402 | await this.dialogsService.showAlert(
403 | `Country Code: ${result.countryCode}
` +
404 | `License Plate: ${result.licensePlate}
` +
405 | `Confidence: ${result.confidence}
` +
406 | 'License Plate Result');
407 | }
408 | } catch (e) {
409 | await this.dialogsService.showAlert(e.message);
410 | }
411 | }
412 |
413 | async startTextDataScanner() {
414 | try {
415 | if (!(await this.scanbotService.checkLicense())) {
416 | return;
417 | }
418 |
419 | const uiConfigs: TextDataScannerConfiguration = {
420 | cancelButtonTitle: 'Cancel',
421 | topBarBackgroundColor: '#c8193c',
422 | topBarButtonsActiveColor: '#ffffff',
423 | finderLineColor: '#c8193c',
424 | orientationLockMode: 'PORTRAIT',
425 | // see further configs...
426 | };
427 |
428 | const result = await this.scanbotService.SDK.UI.startTextDataScanner({uiConfigs});
429 |
430 | if (result.status === 'OK') {
431 | await this.dialogsService.showAlert(`Value: ${result.result?.text}`, 'Scanner Result');
432 | }
433 | } catch (e) {
434 | await this.dialogsService.showAlert(e.message);
435 | }
436 | }
437 |
438 | async startMedicalCertificateScanner() {
439 | try {
440 | if (!(await this.scanbotService.checkLicense())) {
441 | return;
442 | }
443 |
444 | const config: MedicalCertificateRecognizerConfiguration = {
445 | topBarBackgroundColor: '#c8193c',
446 | userGuidanceStrings: {
447 | capturing: 'Capturing',
448 | scanning: 'Recognizing',
449 | processing: 'Processing',
450 | startScanning: 'Scanning Started',
451 | paused: 'Paused',
452 | energySaving: 'Energy Saving',
453 | },
454 | errorDialogMessage: 'Oops, something went wrong! Please, try again.',
455 | errorDialogOkButton: 'OK',
456 | errorDialogTitle: 'ERROR',
457 | cancelButtonHidden: false,
458 | recognizePatientInfo: true,
459 | };
460 | const result = await this.scanbotService.SDK.UI.startMedicalCertificateRecognizer({uiConfigs: config});
461 |
462 | if (result.status === 'OK') {
463 | ScannerResultsService.medicalCertificateScannerResult = result;
464 | await this.router.navigateByUrl('/medical-certificate-scanner-results');
465 | }
466 |
467 | } catch (e: any) {
468 | await this.dialogsService.showAlert(e.message || 'An unexpected error has occurred', 'Error');
469 | }
470 | }
471 |
472 | async startVINScanner() {
473 | try {
474 | if (!(await this.scanbotService.checkLicense())) {
475 | return;
476 | }
477 |
478 | const config: VinScannerConfiguration = {
479 | topBarBackgroundColor: '#c8193c',
480 | };
481 | const result = await this.scanbotService.SDK.UI.startVinScanner({uiConfigs: config});
482 |
483 | if (result.status === 'OK') {
484 | const message = [
485 | `- Raw Text: ${result.rawText}`,
486 | result.confidenceValue &&
487 | `- Confidence: ${(result.confidenceValue * 100).toFixed(0)}%`,
488 | `- Validation: ${
489 | result.validationSuccessful ? 'SUCCESSFUL' : 'NOT SUCCESSFUL'
490 | }`,
491 | ].join('\n\n');
492 | await this.dialogsService.showAlert(message, 'VIN Scanner Result');
493 | }
494 | } catch (e: any) {
495 | await this.dialogsService.showAlert(e.message || 'An unexpected error has occurred', 'Error');
496 | }
497 | }
498 |
499 | async applyImageFilter() {
500 | try {
501 | if (!(await this.scanbotService.checkLicense())) {
502 | return;
503 | }
504 |
505 | const imageFileUri = await Camera.getPicture({
506 | sourceType: PictureSourceType.PHOTOLIBRARY
507 | });
508 |
509 | const buttons = IMAGE_FILTER_LIST.map(imageFilter => ({
510 | text: imageFilter,
511 | handler: async () => {
512 | const result = await this.scanbotService.SDK.applyImageFilter({imageFileUri, imageFilter});
513 | if (result.imageFileUri) {
514 | const page = await this.scanbotService.SDK.createPage({originalImageFileUri: result.imageFileUri});
515 | const documentPage = await this.scanbotService.SDK.detectDocumentOnPage({page});
516 | await this.imageResultsRepository.addPages([documentPage]);
517 | await this.router.navigate(['/image-view', documentPage.pageId]);
518 | }
519 | }
520 | }));
521 |
522 | const actionSheet = await this.actionSheetController.create({
523 | header: 'Image Filters',
524 | buttons: buttons
525 | });
526 | await actionSheet.present();
527 | } catch (e) {
528 | await this.dialogsService.showAlert(e.message);
529 | }
530 | }
531 |
532 | }
533 |
--------------------------------------------------------------------------------
/src/app/image-results/image-results.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { IonicModule } from '@ionic/angular';
4 | import { FormsModule } from '@angular/forms';
5 | import { RouterModule } from '@angular/router';
6 |
7 | import { ImageResultsPage } from './image-results.page';
8 |
9 | @NgModule({
10 | imports: [
11 | CommonModule,
12 | FormsModule,
13 | IonicModule,
14 | RouterModule.forChild([
15 | {
16 | path: '',
17 | component: ImageResultsPage
18 | }
19 | ])
20 | ],
21 | declarations: [ImageResultsPage]
22 | })
23 | export class ImageResultsPageModule {}
24 |
--------------------------------------------------------------------------------
/src/app/image-results/image-results.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Image Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | Add
30 |
31 |
32 |
33 | Save
34 |
35 |
36 |
37 |
38 |
39 | Delete All
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/app/image-results/image-results.page.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/src/app/image-results/image-results.page.scss
--------------------------------------------------------------------------------
/src/app/image-results/image-results.page.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 | import {ActionSheetController, Platform} from '@ionic/angular';
3 | import {Router} from '@angular/router';
4 |
5 | import {Page} from 'cordova-plugin-scanbot-sdk';
6 |
7 | import {DialogsService} from '../services/dialogs.service';
8 | import {ScanbotSdkDemoService} from '../services/scanbot-sdk-demo.service';
9 | import {ImageResultsRepository} from '../services/image-results.repository';
10 |
11 | @Component({
12 | selector: 'app-image-results',
13 | templateUrl: 'image-results.page.html',
14 | styleUrls: ['image-results.page.scss'],
15 | })
16 | export class ImageResultsPage {
17 |
18 | public pages: Page[] = [];
19 | public rows: Array<{ pages: Page[] }> = [];
20 | public sanitizedPreviewImages = new Map();
21 |
22 | constructor(private scanbotService: ScanbotSdkDemoService,
23 | private imageResultsRepository: ImageResultsRepository,
24 | private dialogsService: DialogsService,
25 | private router: Router,
26 | private actionSheetController: ActionSheetController) {
27 | }
28 |
29 | ionViewWillEnter() {
30 | this.reloadPages();
31 | }
32 |
33 | private async reloadPages() {
34 | this.pages = this.imageResultsRepository.getPages();
35 | // build sanitizes preview image file URIs
36 | for (const page of this.pages) {
37 | const data = await this.scanbotService.fetchDataFromUri(page.documentPreviewImageFileUri);
38 | this.sanitizedPreviewImages.set(page.pageId, this.imageResultsRepository.sanitizeBase64(data));
39 | }
40 | // build rows
41 | this.rows = [];
42 | for (let i = 0; i < this.pages.length; i += 3) {
43 | this.rows.push({pages: this.pages.slice(i, i + 3)});
44 | }
45 | }
46 |
47 | async gotoImageView(page: Page) {
48 | await this.router.navigate(['/image-view', page.pageId]);
49 | }
50 |
51 | async saveAsPdf() {
52 | if (!(await this.scanbotService.checkLicense())) { return; }
53 | if (!this.checkImages()) { return; }
54 |
55 | const loading = await this.dialogsService.createLoading('Creating PDF ...');
56 | try {
57 | await loading.present();
58 | const result = await this.scanbotService.SDK.createPdf({
59 | imageFileUris: this.pages.map(p => p.originalImageFileUri),
60 | options: {
61 | pageSize: 'A4'
62 | }
63 | });
64 |
65 | await this.dialogsService.showAlert(result.pdfFileUri, 'PDF created');
66 | } catch (e: any) {
67 | console.error('Unable to create PDF.', e);
68 | await this.dialogsService.showAlert(e.message, 'ERROR');
69 | }
70 | finally {
71 | await loading.dismiss();
72 | }
73 | }
74 |
75 | async saveAsPdfWithOcr() {
76 | if (!(await this.scanbotService.checkLicense())) { return; }
77 | if (!this.checkImages()) { return; }
78 |
79 | const loading = await this.dialogsService.createLoading('Performing OCR and creating PDF ...');
80 | try {
81 | await loading.present();
82 | const result = await this.scanbotService.SDK.performOcr({
83 | imageFileUris: this.pages.map(p => p.originalImageFileUri),
84 | languages: ['en'],
85 | options: {
86 | outputFormat: 'PDF_FILE',
87 | }
88 | });
89 |
90 | if (result.pdfFileUri) {
91 | await this.dialogsService.showAlert(result.pdfFileUri, 'PDF with OCR created');
92 | }
93 |
94 | } catch (e: any) {
95 | console.error('Unable to perform OCR.', e);
96 | await this.dialogsService.showAlert(e.message, 'ERROR');
97 | }
98 | finally {
99 | await loading.dismiss();
100 | }
101 | }
102 |
103 | async saveAsBinarizedTiff() {
104 | if (!(await this.scanbotService.checkLicense())) { return; }
105 | if (!this.checkImages()) { return; }
106 |
107 | const loading = await this.dialogsService.createLoading('Creating TIFF ...');
108 | try {
109 | await loading.present();
110 | const result = await this.scanbotService.SDK.writeTiff({
111 | imageFileUris: this.pages.map(p => p.originalImageFileUri),
112 | options: {
113 | oneBitEncoded: true, // creates 1-bit binarized black and white TIFF
114 | dpi: 300, // default value is 200
115 | // compression: 'LZW' // recommended default value is 'CCITT_T6' (aka. "CCITT Fax 4")
116 | }
117 | });
118 |
119 | await this.dialogsService.showAlert(result.tiffFileUri, 'TIFF file created');
120 | } catch (e: any) {
121 | console.error('Unable to create TIFF.', e);
122 | await this.dialogsService.showAlert(e.message, 'ERROR');
123 | }
124 | finally {
125 | await loading.dismiss();
126 | }
127 | }
128 |
129 | async showSaveSelection() {
130 | const actionSheet = await this.actionSheetController.create({
131 | header: 'Save Images as',
132 | buttons: [
133 | {
134 | text: 'PDF',
135 | icon: 'document',
136 | handler: () => { this.saveAsPdf(); }
137 | },
138 | {
139 | text: 'PDF with OCR',
140 | icon: 'document',
141 | handler: () => { this.saveAsPdfWithOcr(); }
142 | },
143 | {
144 | text: 'TIFF (1-bit b&w)',
145 | icon: 'document',
146 | handler: () => { this.saveAsBinarizedTiff(); }
147 | },
148 | {
149 | text: 'Cancel',
150 | icon: 'close',
151 | role: 'cancel',
152 | handler: () => { }
153 | }
154 | ]
155 | });
156 | await actionSheet.present();
157 | }
158 |
159 |
160 | private checkImages(): boolean {
161 | if (this.pages.length > 0) {
162 | return true;
163 | }
164 | this.dialogsService.showAlert(
165 | 'Please scan some images via Document Scanner or import from Photo Library.',
166 | 'Images Required');
167 | return false;
168 | }
169 |
170 | async addScan() {
171 | if (!(await this.scanbotService.checkLicense())) { return; }
172 |
173 | const configs = this.scanbotService.globalDocScannerConfigs();
174 | // for demo purposes we want to add only one page here.
175 | configs.multiPageEnabled = false;
176 | configs.multiPageButtonHidden = true;
177 |
178 | const result = await this.scanbotService.SDK.UI.startDocumentScanner({ uiConfigs: configs });
179 |
180 | if (result.status === 'CANCELED') { return; }
181 |
182 | await this.imageResultsRepository.addPages(result.pages);
183 | this.reloadPages();
184 | }
185 |
186 | async removeAll() {
187 | await this.scanbotService.SDK.cleanup();
188 | await this.imageResultsRepository.removeAllPages();
189 | this.reloadPages();
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/src/app/image-view/image-view.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { IonicModule } from '@ionic/angular';
4 | import { FormsModule } from '@angular/forms';
5 | import { RouterModule } from '@angular/router';
6 |
7 | import { ImageViewPage } from './image-view.page';
8 |
9 | @NgModule({
10 | imports: [
11 | CommonModule,
12 | FormsModule,
13 | IonicModule,
14 | RouterModule.forChild([
15 | {
16 | path: '',
17 | component: ImageViewPage
18 | }
19 | ])
20 | ],
21 | declarations: [ImageViewPage]
22 | })
23 | export class ImageViewPageModule {}
24 |
--------------------------------------------------------------------------------
/src/app/image-view/image-view.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Image View
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Crop / Rotate
27 |
28 |
29 |
30 | Filter
31 |
32 |
33 |
34 |
35 |
36 | Delete
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/app/image-view/image-view.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { ActivatedRoute, ParamMap, Router } from '@angular/router';
3 | import { ActionSheetController } from '@ionic/angular';
4 | import { of } from 'rxjs';
5 | import { switchMap } from 'rxjs/operators';
6 |
7 | import { ImageFilterType, Page } from 'cordova-plugin-scanbot-sdk';
8 |
9 | import { DialogsService } from '../services/dialogs.service';
10 | import { ImageResultsRepository } from '../services/image-results.repository';
11 | import { ScanbotSdkDemoService } from '../services/scanbot-sdk-demo.service';
12 | import {IMAGE_FILTER_LIST} from '../../utils/image-filters';
13 |
14 | @Component({
15 | selector: 'app-image-view',
16 | templateUrl: 'image-view.page.html',
17 | })
18 | export class ImageViewPage implements OnInit {
19 |
20 | public page: Page | undefined;
21 | public sanitizedPreviewImage: string | undefined;
22 |
23 | constructor(private scanbotService: ScanbotSdkDemoService,
24 | private imageResultsRepository: ImageResultsRepository,
25 | private dialogsService: DialogsService,
26 | private router: Router,
27 | private route: ActivatedRoute,
28 | private actionSheetController: ActionSheetController) { }
29 |
30 | ngOnInit() {
31 | this.route.paramMap.pipe(
32 | switchMap((params: ParamMap) => of(params.get('pageId')))
33 | ).subscribe(pageId => {
34 | if (pageId) {
35 | this.page = this.imageResultsRepository.getPageById(pageId);
36 | }
37 | this.sanitizePreviewImage();
38 | });
39 | }
40 |
41 | private async sanitizePreviewImage() {
42 | if (this.page && this.page.documentPreviewImageFileUri) {
43 | const data = await this.scanbotService.fetchDataFromUri(this.page.documentPreviewImageFileUri);
44 | this.sanitizedPreviewImage = this.imageResultsRepository.sanitizeBase64(data);
45 | }
46 | }
47 |
48 | async startCroppingScreen() {
49 | if (!(await this.scanbotService.checkLicense()) || this.page === undefined) { return; }
50 |
51 | const result = await this.scanbotService.SDK.UI.startCroppingScreen({
52 | page: this.page,
53 | uiConfigs: {
54 | // Customize colors, text resources, behavior, etc..
55 | doneButtonTitle: 'Save',
56 | orientationLockMode: 'PORTRAIT',
57 | topBarBackgroundColor: '#c8193c',
58 | bottomBarBackgroundColor: '#c8193c',
59 | hintTitle: 'Custom hint:\nDrag the dots to the document edges.',
60 | hintTitleColor: '#0000ff'
61 | // ...
62 | }
63 | });
64 |
65 | if (result.status === 'CANCELED' || result.page === undefined) { return; }
66 |
67 | await this.updatePage(result.page);
68 | }
69 |
70 | async deletePage() {
71 | if (this.page) {
72 | await this.scanbotService.SDK.removePage({ page: this.page });
73 | await this.imageResultsRepository.removePage(this.page);
74 | await this.router.navigate(['/image-results']);
75 | }
76 | }
77 |
78 | private async updatePage(page: Page) {
79 | await this.imageResultsRepository.updatePage(page);
80 | this.page = page;
81 | this.sanitizePreviewImage();
82 | }
83 |
84 | async showFilterSelection() {
85 | const buttons = [];
86 | IMAGE_FILTER_LIST.forEach(f => {
87 | buttons.push({
88 | text: f,
89 | handler: () => { this.applyImageFilter(f); }
90 | });
91 | });
92 |
93 | buttons.push({
94 | text: 'Cancel',
95 | role: 'cancel',
96 | handler: () => { }
97 | });
98 |
99 | const actionSheet = await this.actionSheetController.create({
100 | header: 'Select an Image Filter',
101 | buttons: buttons,
102 | cssClass: "image-filters-action-sheet"
103 | });
104 | await actionSheet.present();
105 | }
106 |
107 | private async applyImageFilter(filter: ImageFilterType) {
108 | if (!(await this.scanbotService.checkLicense()) || this.page === undefined) { return; }
109 |
110 | const loading = await this.dialogsService.createLoading('Applying image filter ...');
111 | try {
112 | await loading.present();
113 | const result = await this.scanbotService.SDK.applyImageFilterOnPage({ page: this.page, imageFilter: filter });
114 | await this.updatePage(result);
115 | }
116 | finally {
117 | await loading.dismiss();
118 | }
119 | }
120 |
121 | async documentQualityAnalyzer() {
122 | if (!(await this.scanbotService.checkLicense())) { return; }
123 |
124 | const loading = await this.dialogsService.createLoading('Analyzing document ...');
125 | try {
126 | await loading.present();
127 |
128 | const scanResult = await this.scanbotService.SDK.documentQualityAnalyzer({imageFileUri: this.page.documentImageFileUri});
129 | await this.dialogsService.showAlert('Document Quality Analyzer result ' + scanResult.result);
130 | }
131 | finally {
132 | await loading.dismiss();
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/app/medical-certificate-scanner-results/medical-certificate-scanner-results-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 |
4 | import { MedicalCertificateScannerResultsPage } from './medical-certificate-scanner-results.page';
5 |
6 | const routes: Routes = [
7 | {
8 | path: '',
9 | component: MedicalCertificateScannerResultsPage
10 | }
11 | ];
12 |
13 | @NgModule({
14 | imports: [RouterModule.forChild(routes)],
15 | exports: [RouterModule],
16 | })
17 | export class MedicalCertificateScannerResultsPageRoutingModule {}
18 |
--------------------------------------------------------------------------------
/src/app/medical-certificate-scanner-results/medical-certificate-scanner-results.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { FormsModule } from '@angular/forms';
4 |
5 | import { IonicModule } from '@ionic/angular';
6 |
7 | import { MedicalCertificateScannerResultsPageRoutingModule } from './medical-certificate-scanner-results-routing.module';
8 |
9 | import { MedicalCertificateScannerResultsPage } from './medical-certificate-scanner-results.page';
10 | import {SectionListComponent} from '../section-list/section-list.component';
11 |
12 | @NgModule({
13 | imports: [
14 | CommonModule,
15 | FormsModule,
16 | IonicModule,
17 | MedicalCertificateScannerResultsPageRoutingModule,
18 | SectionListComponent
19 | ],
20 | declarations: [MedicalCertificateScannerResultsPage]
21 | })
22 | export class MedicalCertificateScannerResultsPageModule {}
23 |
--------------------------------------------------------------------------------
/src/app/medical-certificate-scanner-results/medical-certificate-scanner-results.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Medical Certificate Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/app/medical-certificate-scanner-results/medical-certificate-scanner-results.page.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/src/app/medical-certificate-scanner-results/medical-certificate-scanner-results.page.scss
--------------------------------------------------------------------------------
/src/app/medical-certificate-scanner-results/medical-certificate-scanner-results.page.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { MedicalCertificateScannerResultsPage } from './medical-certificate-scanner-results.page';
3 |
4 | describe('MedicalCertificateScannerResultsPage', () => {
5 | let component: MedicalCertificateScannerResultsPage;
6 | let fixture: ComponentFixture;
7 |
8 | beforeEach(async(() => {
9 | fixture = TestBed.createComponent(MedicalCertificateScannerResultsPage);
10 | component = fixture.componentInstance;
11 | fixture.detectChanges();
12 | }));
13 |
14 | it('should create', () => {
15 | expect(component).toBeTruthy();
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/src/app/medical-certificate-scanner-results/medical-certificate-scanner-results.page.ts:
--------------------------------------------------------------------------------
1 | import {Component, OnInit} from '@angular/core';
2 | import {ScanResultSection, ScanResultSectionList} from '../section-list/section-list.component';
3 | import {MedicalCertificateScannerResult} from 'cordova-plugin-scanbot-sdk';
4 | import {ScannerResultsService} from '../services/scanner-results.service';
5 | import {ImageResultsRepository} from '../services/image-results.repository';
6 |
7 | type PatientDataKeys = keyof MedicalCertificateScannerResult['patientData'];
8 | type DatesKeys = keyof MedicalCertificateScannerResult['dates'];
9 | type CheckBoxKeys = keyof MedicalCertificateScannerResult['checkboxes'];
10 |
11 | @Component({
12 | selector: 'app-medical-certificate-scanner-results',
13 | templateUrl: './medical-certificate-scanner-results.page.html',
14 | styleUrls: ['./medical-certificate-scanner-results.page.scss'],
15 | })
16 | export class MedicalCertificateScannerResultsPage implements OnInit {
17 |
18 | displayFields: ScanResultSectionList;
19 | medicalCertificateScannerResult: MedicalCertificateScannerResult;
20 |
21 | constructor(
22 | private imageResultsRepository: ImageResultsRepository,
23 | ) {
24 | }
25 |
26 | async ngOnInit() {
27 | this.medicalCertificateScannerResult = ScannerResultsService.medicalCertificateScannerResult;
28 | this.displayFields = await this.setupProperties();
29 | }
30 |
31 | private async setupProperties(): Promise {
32 | const commonData: ScanResultSection = {
33 | title: 'Medical Certificate Result',
34 | data: [
35 | {
36 | key: 'Form Type',
37 | value: this.medicalCertificateScannerResult.formType
38 | },
39 | ],
40 | };
41 |
42 | if (this.medicalCertificateScannerResult.imageFileUri) {
43 | commonData.data.unshift({
44 | key: 'Snapped Image',
45 | image: this.imageResultsRepository.sanitizeFileUri(this.medicalCertificateScannerResult.imageFileUri),
46 | });
47 | }
48 |
49 | return [
50 | commonData,
51 | {
52 | title: 'Patient Data',
53 | data: this.transformPatientData(),
54 | },
55 | {
56 | title: 'Dates',
57 | data: this.transformDatesData(),
58 | },
59 | {
60 | title: 'Checkboxes',
61 | data: this.transformCheckboxesData(),
62 | },
63 | ];
64 | }
65 |
66 | transformPatientData() {
67 | if (!this.medicalCertificateScannerResult.patientData) {
68 | return [];
69 | }
70 |
71 | const displayTitleMap: Record = {
72 | firstName: 'First Name',
73 | lastName: 'Last Name',
74 | insuranceProvider: 'Insurance Provider',
75 | address1: 'Address #1',
76 | address2: 'Address #2',
77 | diagnose: 'Diagnose',
78 | healthInsuranceNumber: 'Health Insurance Number',
79 | insuredPersonNumber: 'Insured Person Number',
80 | status: 'Status',
81 | placeOfOperationNumber: 'Place of Operation Number',
82 | doctorNumber: 'Doctor\'s number',
83 | unknown: 'Unknown',
84 | };
85 |
86 | return Object.keys(displayTitleMap)
87 | .filter(
88 | mapKey =>
89 | mapKey in this.medicalCertificateScannerResult.patientData &&
90 | this.medicalCertificateScannerResult.patientData[mapKey as PatientDataKeys] != null,
91 | )
92 | .map(mapKey => ({
93 | key: displayTitleMap[mapKey as PatientDataKeys],
94 | value: `${
95 | this.medicalCertificateScannerResult.patientData[mapKey as PatientDataKeys]!.value
96 | } (confidence: ${Math.round(
97 | this.medicalCertificateScannerResult.patientData[mapKey as PatientDataKeys]!
98 | .recognitionConfidence * 100,
99 | )} %)`,
100 | }));
101 | }
102 |
103 | transformDatesData = () => {
104 | if (!this.medicalCertificateScannerResult.dates) {
105 | return [];
106 | }
107 |
108 | const dates = this.medicalCertificateScannerResult.dates;
109 |
110 | const displayMap = {
111 | incapableOfWorkSince: 'Incapable of work since',
112 | incapableOfWorkUntil: 'Incapable of work until',
113 | diagnosedOn: 'Diagnosed on',
114 | childNeedsCareFrom: 'Child needs care from',
115 | childNeedsCareUntil: 'Child needs care until',
116 | birthDate: 'Patient birth date',
117 | documentDate: 'Document date',
118 | unknown: 'Unknown',
119 | };
120 |
121 | return Object.keys(dates).map(key => {
122 | const returnKey = key in displayMap ? displayMap[key as DatesKeys] : key;
123 | let confidence = dates[key as DatesKeys]?.recognitionConfidence ?? 0;
124 | confidence = Math.round(confidence * 100);
125 | const returnValue = this.medicalCertificateScannerResult.dates[key as DatesKeys]?.dateString ?? '';
126 |
127 | return {
128 | key: returnKey,
129 | value: `${returnValue} (confidence: ${confidence} %)`,
130 | };
131 | });
132 | };
133 |
134 | transformCheckboxesData = () => {
135 | const checkboxes = this.medicalCertificateScannerResult.checkboxes;
136 | if (!checkboxes) {
137 | return [];
138 | }
139 | const displayNames: Record = {
140 | initialCertificate: 'Initial Certificate',
141 | renewedCertificate: 'Renewed Certificate',
142 | workAccident: 'Work Accident',
143 | assignedToAccidentInsuranceDoctor: 'Assigned to Accident Insurance Doctor',
144 | accidentYes: 'Accident box checked Yes?',
145 | accidentNo: 'Accident box checked No?',
146 | requiresCareYes: 'Child requires care checked Yes?',
147 | requiresCareNo: 'Child requires care checked No?',
148 | insuredPayCase: 'Insurance company has to pay?',
149 | finalCertificate: 'The certificate is final?',
150 | otherAccident: 'Other Accident?',
151 | entitlementToContinuedPaymentNo: '',
152 | entitlementToContinuedPaymentYes: '',
153 | sickPayWasClaimedNo: 'Claimed sick pay No?',
154 | sickPayWasClaimedYes: 'Claimed sick play Yes?',
155 | singleParentNo: 'Single parent No?',
156 | singleParentYes: 'Single parent Yes?',
157 | unknown: 'Unknown',
158 | };
159 |
160 | return Object.keys(checkboxes).flatMap(key => {
161 | const value = checkboxes[key as CheckBoxKeys]?.isChecked;
162 | let confidence = checkboxes[key as CheckBoxKeys]?.confidence ?? 0;
163 | confidence = Math.round(confidence * 100);
164 | const displayName =
165 | key in displayNames ? displayNames[key as CheckBoxKeys] : key;
166 | return {
167 | key: displayName,
168 | value: `${value ? 'YES' : 'NO'} (confidence: ${confidence}%)`,
169 | };
170 | });
171 | };
172 | }
173 |
--------------------------------------------------------------------------------
/src/app/mrz-scanner-results/mrz-scanner-results-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 |
4 | import { MrzScannerResultsPage } from './mrz-scanner-results.page';
5 |
6 | const routes: Routes = [
7 | {
8 | path: '',
9 | component: MrzScannerResultsPage
10 | }
11 | ];
12 |
13 | @NgModule({
14 | imports: [RouterModule.forChild(routes)],
15 | exports: [RouterModule],
16 | })
17 | export class MrzScannerResultsPageRoutingModule {}
18 |
--------------------------------------------------------------------------------
/src/app/mrz-scanner-results/mrz-scanner-results.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { FormsModule } from '@angular/forms';
4 |
5 | import { IonicModule } from '@ionic/angular';
6 |
7 | import { MrzScannerResultsPageRoutingModule } from './mrz-scanner-results-routing.module';
8 |
9 | import { MrzScannerResultsPage } from './mrz-scanner-results.page';
10 | import {SectionListComponent} from '../section-list/section-list.component';
11 |
12 | @NgModule({
13 | imports: [
14 | CommonModule,
15 | FormsModule,
16 | IonicModule,
17 | MrzScannerResultsPageRoutingModule,
18 | SectionListComponent
19 | ],
20 | declarations: [MrzScannerResultsPage]
21 | })
22 | export class MrzScannerResultsPageModule {}
23 |
--------------------------------------------------------------------------------
/src/app/mrz-scanner-results/mrz-scanner-results.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | MRZ Scanner Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/app/mrz-scanner-results/mrz-scanner-results.page.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/src/app/mrz-scanner-results/mrz-scanner-results.page.scss
--------------------------------------------------------------------------------
/src/app/mrz-scanner-results/mrz-scanner-results.page.spec.ts:
--------------------------------------------------------------------------------
1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing';
2 | import { MrzScannerResultsPage } from './mrz-scanner-results.page';
3 |
4 | describe('MrzScannerResultsPage', () => {
5 | let component: MrzScannerResultsPage;
6 | let fixture: ComponentFixture;
7 |
8 | beforeEach(async(() => {
9 | fixture = TestBed.createComponent(MrzScannerResultsPage);
10 | component = fixture.componentInstance;
11 | fixture.detectChanges();
12 | }));
13 |
14 | it('should create', () => {
15 | expect(component).toBeTruthy();
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/src/app/mrz-scanner-results/mrz-scanner-results.page.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 | import {ScanResultSection, ScanResultSectionList} from '../section-list/section-list.component';
3 | import {DomSanitizer} from '@angular/platform-browser';
4 | import {ScannerResultsService} from '../services/scanner-results.service';
5 | import {GenericDocumentUtils} from '../../utils/gdr-utils';
6 | import {MrzScannerResult} from 'cordova-plugin-scanbot-sdk';
7 |
8 | @Component({
9 | selector: 'app-mrz-scanner-results',
10 | templateUrl: './mrz-scanner-results.page.html',
11 | styleUrls: ['./mrz-scanner-results.page.scss'],
12 | })
13 | export class MrzScannerResultsPage {
14 |
15 | mrzScannerResult: MrzScannerResult;
16 | displayFields: ScanResultSectionList;
17 |
18 | constructor() {
19 | this.mrzScannerResult = ScannerResultsService.mrzScannerResult;
20 | this.displayFields = this.setupProperties();
21 | }
22 |
23 | private setupProperties(): ScanResultSectionList {
24 |
25 | const commonSection: ScanResultSection = {
26 | title: 'MRZ Result',
27 | data: [
28 | GenericDocumentUtils.sectionValueItem('Document Type', this.mrzScannerResult.documentType),
29 | GenericDocumentUtils.sectionValueItem('Raw MRZ String', this.mrzScannerResult.rawString),
30 | GenericDocumentUtils.sectionValueItem(
31 | 'Recognition Successful',
32 | this.mrzScannerResult.recognitionSuccessful ? 'YES' : 'NO',
33 | ),
34 | GenericDocumentUtils.sectionValueItem(
35 | 'Check digits count',
36 | this.mrzScannerResult.checkDigitsCount.toString(),
37 | ),
38 | GenericDocumentUtils.sectionValueItem(
39 | 'Valid check digits count',
40 | this.mrzScannerResult.validCheckDigitsCount.toString(),
41 | ),
42 | ...GenericDocumentUtils.gdrCommonFields(this.mrzScannerResult.mrz),
43 | ]
44 | };
45 |
46 | const checkFieldsSection: ScanResultSection = {
47 | title: 'MRZ Document',
48 | data: GenericDocumentUtils.gdrFields(this.mrzScannerResult.mrz),
49 | };
50 |
51 | return [
52 | commonSection,
53 | checkFieldsSection
54 | ];
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/app/section-list/section-list.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 | {{data.key}}
11 | {{data.value}}
12 |
13 |
14 |
15 |
16 |
17 | {{data.key}}
18 |
19 | Value: {{data.field!.value!.text}}
20 |
21 | Confidence: {{data.field!.value!.confidence}}
22 |
23 | {{data.field!.validationStatus}}
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/app/section-list/section-list.component.scss:
--------------------------------------------------------------------------------
1 |
2 | .section-container {
3 | background-color: #e2e2e2;
4 | padding-bottom: 2%
5 | };
6 |
7 | .section-header {
8 | color: #FFFFFF;
9 | --background: #c8193c;
10 | };
11 |
12 | .section-item {
13 | padding: 0.5%;
14 | };
15 |
16 | .section-item-container {
17 | background-color: #FFFFFF;
18 | padding-left: 4%;
19 | };
20 |
--------------------------------------------------------------------------------
/src/app/section-list/section-list.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 | import { IonicModule } from '@ionic/angular';
3 |
4 | import { SectionListComponent } from './section-list.component';
5 |
6 | describe('SectionListComponent', () => {
7 | let component: SectionListComponent;
8 | let fixture: ComponentFixture;
9 |
10 | beforeEach(waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [ SectionListComponent ],
13 | imports: [IonicModule.forRoot()]
14 | }).compileComponents();
15 |
16 | fixture = TestBed.createComponent(SectionListComponent);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | }));
20 |
21 | it('should create', () => {
22 | expect(component).toBeTruthy();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/src/app/section-list/section-list.component.ts:
--------------------------------------------------------------------------------
1 | import {Component, Input, OnInit} from '@angular/core';
2 | import {Field} from 'cordova-plugin-scanbot-sdk';
3 | import {IonicModule} from '@ionic/angular';
4 | import {NgForOf, NgIf, NgOptimizedImage} from '@angular/common';
5 | import {SafeUrl} from '@angular/platform-browser';
6 |
7 |
8 | export type ScanResultSectionData = {
9 | key: string;
10 | value?: string;
11 | image?: SafeUrl;
12 | field?: Field;
13 | };
14 |
15 | export type ScanResultSection = {
16 | title: string;
17 | data: ScanResultSectionData[];
18 | };
19 |
20 | export type ScanResultSectionList = Array
21 |
22 | @Component({
23 | selector: 'app-section-list',
24 | templateUrl: './section-list.component.html',
25 | styleUrls: ['./section-list.component.scss'],
26 | imports: [
27 | IonicModule,
28 | NgForOf,
29 | NgIf,
30 | NgOptimizedImage
31 | ],
32 | standalone: true
33 | })
34 | export class SectionListComponent implements OnInit {
35 |
36 | @Input() sectionListData:ScanResultSectionList
37 |
38 | constructor() {
39 | }
40 |
41 | ngOnInit() {}
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/app/services/barcode-document-list.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { BarcodeDocumentFormat } from 'cordova-plugin-scanbot-sdk';
3 |
4 | @Injectable({
5 | providedIn: 'root',
6 | })
7 | export class BarcodeDocumentListService {
8 |
9 | public static isFilteringEnabled = false;
10 |
11 | public static list: Array<{ key: BarcodeDocumentFormat, value: boolean }> = [
12 | { key: "AAMVA", value: true },
13 | { key: "BOARDING_PASS", value: true },
14 | { key: "DE_MEDICAL_PLAN", value: true },
15 | { key: "MEDICAL_CERTIFICATE", value: true },
16 | { key: "ID_CARD_PDF_417", value: true },
17 | { key: "SEPA", value: true },
18 | { key: "SWISS_QR", value: true },
19 | { key: "VCARD", value: true },
20 | { key: "GS1", value: true },
21 | ];
22 |
23 | public static getAcceptedFormats(): BarcodeDocumentFormat[] {
24 | if (!BarcodeDocumentListService.isFilteringEnabled) {
25 | return [];
26 | }
27 |
28 | return BarcodeDocumentListService.list
29 | .filter(item => item.value)
30 | .map(item => item.key)
31 | }
32 |
33 | public static update(format: BarcodeDocumentFormat, isChecked: boolean) {
34 | const index = BarcodeDocumentListService.list.findIndex(item => item.key === format)
35 | if (index) {
36 | BarcodeDocumentListService.list[index].value = isChecked
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/app/services/barcode-list.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { BarcodeFormat } from 'cordova-plugin-scanbot-sdk';
3 |
4 | export interface BarcodesDetectionViewModel {
5 | snappedImage?: string;
6 | barcodes: {
7 | text: string,
8 | type: string,
9 | rawBytes: number[]
10 | rawBytesString?: string
11 | }[];
12 | }
13 |
14 | @Injectable({
15 | providedIn: 'root',
16 | })
17 | export class BarcodeListService {
18 |
19 | public static detectedBarcodes: BarcodesDetectionViewModel[] = [];
20 |
21 | public static items: Array<{ key: BarcodeFormat, value: boolean }> = [
22 | { key: "AZTEC", value: true },
23 | { key: "CODABAR", value: true },
24 | { key: "CODE_25", value: true },
25 | { key: "CODE_39", value: true },
26 | { key: "CODE_93", value: true },
27 | { key: "CODE_128", value: true },
28 | { key: "DATA_MATRIX", value: true },
29 | { key: "EAN_8", value: true },
30 | { key: "EAN_13", value: true },
31 | { key: "ITF", value: true },
32 | { key: "PDF_417", value: true },
33 | { key: "QR_CODE", value: true },
34 | { key: "RSS_14", value: true },
35 | { key: "RSS_EXPANDED", value: true },
36 | { key: "UPC_A", value: true },
37 | { key: "UPC_E", value: true },
38 | { key: "MSI_PLESSEY", value: true },
39 | { key: "IATA_2_OF_5", value: true },
40 | { key: "INDUSTRIAL_2_OF_5", value: true },
41 | { key: "MICRO_QR_CODE", value: true },
42 | { key: "USPS_INTELLIGENT_MAIL", value: true },
43 | { key: "ROYAL_MAIL", value: true },
44 | { key: "ROYAL_TNT_POST", value: true },
45 | { key: "JAPAN_POST", value: true },
46 | { key: "AUSTRALIA_POST", value: true },
47 | { key: "DATABAR_LIMITED", value: true },
48 | { key: "GS1_COMPOSITE", value: true },
49 | ];
50 |
51 | public static update(format: BarcodeFormat, isChecked: boolean) {
52 | const index = BarcodeListService.items.findIndex(item => item.key === format)
53 | if (index) {
54 | BarcodeListService.items[index].value = isChecked
55 | }
56 | }
57 |
58 | public static getAcceptedTypes() {
59 | return BarcodeListService.items
60 | .filter(item => item.value)
61 | .map(item => item.key)
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/app/services/dialogs.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { AlertController, LoadingController } from '@ionic/angular';
3 |
4 | @Injectable()
5 | export class DialogsService {
6 |
7 | constructor(private alertController: AlertController,
8 | private loadingController: LoadingController) { }
9 |
10 | public async showAlert(message: string, header: string = 'Info', subHeader: string = '') {
11 | const alert = await this.alertController.create({
12 | header: header,
13 | subHeader: subHeader,
14 | message: message,
15 | buttons: ['OK']
16 | });
17 |
18 | await alert.present();
19 | }
20 |
21 | public async createLoading(message: string) {
22 | return await this.loadingController.create({
23 | message: message,
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/app/services/image-results.repository.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { DomSanitizer } from '@angular/platform-browser';
3 | import { Platform } from '@ionic/angular';
4 | import { Storage } from '@ionic/storage-angular';
5 |
6 | import { Page } from 'cordova-plugin-scanbot-sdk';
7 | import { ScanbotSdkDemoService } from './scanbot-sdk-demo.service';
8 |
9 |
10 | @Injectable()
11 | export class ImageResultsRepository {
12 | private pages: Page[] = [];
13 |
14 | constructor(private sanitizer: DomSanitizer,
15 | private storage: Storage,
16 | private platform: Platform,
17 | private scanbotService: ScanbotSdkDemoService) {
18 |
19 | this.init().then(r => console.log('local storage created'));
20 |
21 | this.platform.ready().then(() => this.loadPagesFromStorage());
22 | }
23 |
24 | async init() {
25 | // create storage.
26 | await this.storage.create();
27 | }
28 |
29 | private async loadPagesFromStorage() {
30 | const val = await this.storage.get('pages');
31 | const storedPages: Page[] = val ? val as Page[] : [];
32 | if (storedPages.length === 0) {
33 | this.pages = [];
34 | return;
35 | }
36 | this.scanbotService.ready().then(async () => {
37 | const result = await this.scanbotService.SDK.refreshImageUris({pages: storedPages});
38 | this.pages = result.pages;
39 | });
40 | }
41 |
42 | private async storePagesInStorage() {
43 | await this.storage.set('pages', this.pages);
44 | }
45 |
46 | public getPages(): Page[] {
47 | return this.pages;
48 | }
49 |
50 | public getPageById(id: string) {
51 | return this.pages.find(p => p.pageId === id);
52 | }
53 |
54 | public async addPages(pages: Page[]) {
55 | this.pages = this.pages.concat(pages);
56 | await this.storePagesInStorage();
57 | }
58 |
59 | public async updatePage(page: Page) {
60 | let replaced = false;
61 | for (let i = 0; i < this.pages.length; ++i) {
62 | if (this.pages[i].pageId === page.pageId) {
63 | this.pages[i] = page;
64 | replaced = true;
65 | break;
66 | }
67 | }
68 | if (!replaced) {
69 | this.pages.push(page);
70 | }
71 | await this.storePagesInStorage();
72 | }
73 |
74 | public async removePage(page: Page) {
75 | const index = this.pages.findIndex(p => p.pageId === page.pageId);
76 | if (index > -1) {
77 | this.pages.splice(index, 1);
78 | }
79 | await this.storePagesInStorage();
80 | }
81 |
82 | public async removeAllPages() {
83 | this.pages = [];
84 | await this.storePagesInStorage();
85 | }
86 |
87 | public sanitizeFileUri(fileUri: string): string {
88 | // see https://ionicframework.com/docs/building/webview/#file-protocol
89 | const url = (window as any).Ionic.WebView.convertFileSrc(fileUri);
90 | // see https://angular.io/guide/security#bypass-security-apis
91 | return this.sanitizer.bypassSecurityTrustUrl(url) as string;
92 | }
93 |
94 | public sanitizeBase64(data: string): string {
95 | // Cf https://angular.io/guide/security#bypass-security-apis
96 | return this.sanitizer.bypassSecurityTrustResourceUrl( data) as string;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/app/services/scanbot-sdk-demo.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Platform } from '@ionic/angular';
3 | import { File } from '@awesome-cordova-plugins/file/ngx';
4 |
5 | import ScanbotSdk, {
6 | DocumentScannerConfiguration,
7 | FinderDocumentScannerConfiguration,
8 | FileEncryptionMode,
9 | StorageImageFormat,
10 | ScanbotSdkConfiguration,
11 | } from 'cordova-plugin-scanbot-sdk';
12 |
13 | import { environment } from '../../environments/environment';
14 | import { DialogsService } from './dialogs.service';
15 |
16 | @Injectable()
17 | export class ScanbotSdkDemoService {
18 |
19 | /*
20 | * TODO add the license key here.
21 | * Please note: The Scanbot SDK will run without a license key for one minute per session!
22 | * After the trial period has expired, all SDK functions and UI components will stop working.
23 | * You can get a free "no-strings-attached" trial license.
24 | * Please submit the trial license form (https://scanbot.io/trial/) on our website using
25 | * the app identifier "io.scanbot.example.sdk.cordova.ionic" of this example app
26 | * or of your app (see config.xml ).
27 | */
28 | static readonly SDK_LICENSE_KEY: string = '';
29 |
30 | /* Optional image format & quality parameters */
31 | static readonly IMAGE_FILE_FORMAT: StorageImageFormat = 'JPG';
32 | static readonly JPG_IMAGE_QUALITY = 80;
33 |
34 | public static readonly ENCRYPTION_ENABLED: boolean = false;
35 | /* Optional file encryption parameters */
36 | static readonly FILE_ENCRYPTION_PASSWORD: string = 'SomeSecretPa$$w0rdForFileEncryption';
37 | static readonly FILE_ENCRYPTION_MODE: FileEncryptionMode = 'AES256';
38 |
39 | public SDK = ScanbotSdk.promisify();
40 |
41 | private readonly sdkReady: Promise;
42 |
43 | constructor(
44 | private file: File,
45 | private platform: Platform,
46 | private dialogsService: DialogsService
47 | ) {
48 | this.sdkReady = new Promise((resolve, reject) => {
49 | this.platform.ready().then(() => {
50 | this.initScanbotSdk()
51 | .then(result => resolve(result))
52 | .catch(err => reject(err));
53 | });
54 | });
55 | }
56 |
57 | public ready() {
58 | return this.sdkReady;
59 | }
60 |
61 | private initScanbotSdk() {
62 | const config: ScanbotSdkConfiguration = {
63 | loggingEnabled: !environment.production, // Disable logging in production builds for security and performance reasons!
64 | licenseKey: ScanbotSdkDemoService.SDK_LICENSE_KEY,
65 | storageImageFormat: ScanbotSdkDemoService.IMAGE_FILE_FORMAT,
66 | storageImageQuality: ScanbotSdkDemoService.JPG_IMAGE_QUALITY,
67 | //storageBaseDirectory: this.getDemoStorageBaseDirectory(), //optional storageBaseDirectory, see comments below
68 | documentDetectorMode: 'ML_BASED',
69 | useCameraX: true,
70 | allowXnnpackAcceleration: false,
71 | allowGpuAcceleration: false,
72 | };
73 |
74 | if (ScanbotSdkDemoService.ENCRYPTION_ENABLED) {
75 | config.fileEncryptionPassword = ScanbotSdkDemoService.FILE_ENCRYPTION_PASSWORD;
76 | config.fileEncryptionMode = ScanbotSdkDemoService.FILE_ENCRYPTION_MODE;
77 | }
78 |
79 | return this.SDK.initializeSdk(config).then((result: any) => {
80 | console.log(JSON.stringify(result));
81 | }).catch((err:any) => {
82 | console.error(JSON.stringify(err));
83 | });
84 | }
85 |
86 | private getDemoStorageBaseDirectory(): string {
87 | // !! Please note !!
88 | // It is strongly recommended to use the default (secure) storage location of the Scanbot SDK.
89 | // However, for demo purposes we overwrite the "storageBaseDirectory" of the Scanbot SDK by a custom storage directory.
90 | //
91 | // On Android we use the "externalDataDirectory" which is a public(!) folder.
92 | // All image files and export files (PDF, TIFF, etc) created by the Scanbot SDK in this demo app will be stored
93 | // in this public storage directory and will be accessible for every(!) app having external storage permissions!
94 | // Again, this is only for demo purposes, which allows us to easily fetch and check the generated files
95 | // via Android "adb" CLI tools, Android File Transfer app, Android Studio, etc.
96 | //
97 | // On iOS we use the "documentsDirectory" which is accessible via iTunes file sharing.
98 | //
99 | // For more details about the storage system of the Scanbot SDK Plugin please see our docs:
100 | // - https://scanbotsdk.github.io/documentation/cordova/
101 | //
102 | // For more details about the file system on Android and iOS we also recommend to check out:
103 | // - https://developer.android.com/guide/topics/data/data-storage
104 | // - https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html
105 | // tslint:enable:max-line-length
106 |
107 | if (this.platform.is('android')) {
108 | return this.file.externalDataDirectory + 'my-custom-storage';
109 | } else if (this.platform.is('ios')) {
110 | return this.file.documentsDirectory + 'my-custom-storage';
111 | }
112 | return '';
113 | }
114 |
115 | public async checkLicense() {
116 | try {
117 | const result = await this.SDK.getLicenseInfo();
118 | if (result.isLicenseValid) {
119 | // OK - we have a trial session, a valid trial license or valid production license.
120 | return true;
121 | }
122 | await this.dialogsService.showAlert('Scanbot SDK (trial) license has expired!');
123 | return false;
124 | } catch (e) {
125 | await this.dialogsService.showAlert(e.message);
126 | return false
127 | }
128 | }
129 |
130 | public globalDocScannerConfigs(): DocumentScannerConfiguration {
131 | return {
132 | // Customize colors, text resources, behavior, etc..
133 | cameraPreviewMode: 'FIT_IN',
134 | orientationLockMode: 'PORTRAIT',
135 | pageCounterButtonTitle: '%d Page(s)',
136 | multiPageEnabled: true,
137 | ignoreBadAspectRatio: true,
138 | topBarBackgroundColor: '#c8193c',
139 | bottomBarBackgroundColor: '#c8193c',
140 | // maxNumberOfPages: 3,
141 | // documentImageSizeLimit: { width: 2000, height: 3000 },
142 | // see further configs ...
143 | };
144 | }
145 |
146 | public globalFinderDocScannerConfigs(): FinderDocumentScannerConfiguration {
147 | return {
148 | // Customize colors, text resources, behavior, etc..
149 | cameraPreviewMode: 'FILL_IN',
150 | orientationLockMode: 'PORTRAIT',
151 | ignoreBadAspectRatio: true,
152 | topBarBackgroundColor: '#c8193c',
153 | finderEnabled: true,
154 | // see further configs ...
155 | };
156 | }
157 |
158 | public async fetchDataFromUri(path: string): Promise {
159 | const result = await this.SDK.getImageData({ imageFileUri: path });
160 | const extension = ScanbotSdkDemoService.IMAGE_FILE_FORMAT === 'JPG' ? 'jpeg' : 'png';
161 | // ScanbotSDK return the raw base64 data. Add prefix to convert it to a dataUri
162 | return `data:image/${extension};base64,` + result.base64ImageData;
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/src/app/services/scanner-results.service.ts:
--------------------------------------------------------------------------------
1 | import {Injectable} from '@angular/core';
2 | import {
3 | CheckRecognizerResult,
4 | GenericDocumentRecognizerResult,
5 | MedicalCertificateScannerResult,
6 | MrzScannerResult
7 | } from 'cordova-plugin-scanbot-sdk';
8 |
9 | @Injectable({
10 | providedIn: 'root',
11 | })
12 | export class ScannerResultsService {
13 | public static genericDocumentRecognizerResult: GenericDocumentRecognizerResult | undefined;
14 | public static checkRecognizerResult: CheckRecognizerResult | undefined = undefined;
15 | public static mrzScannerResult: MrzScannerResult | undefined = undefined;
16 | public static medicalCertificateScannerResult: MedicalCertificateScannerResult | undefined = undefined;
17 | }
18 |
--------------------------------------------------------------------------------
/src/assets/icon/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic/05ce9f3aca6ac390809bcb99b2e3ba69a9e0024e/src/assets/icon/favicon.png
--------------------------------------------------------------------------------
/src/assets/shapes.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
3 | // The list of file replacements can be found in `angular.json`.
4 |
5 | export const environment = {
6 | production: false
7 | };
8 |
9 | /*
10 | * For easier debugging in development mode, you can import the following file
11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
12 | *
13 | * This import should be commented out in production mode because it will have a negative impact
14 | * on performance if an error is thrown.
15 | */
16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI.
17 |
--------------------------------------------------------------------------------
/src/global.scss:
--------------------------------------------------------------------------------
1 | // http://ionicframework.com/docs/theming/
2 | @import '~@ionic/angular/css/core.css';
3 | @import '~@ionic/angular/css/normalize.css';
4 | @import '~@ionic/angular/css/structure.css';
5 | @import '~@ionic/angular/css/typography.css';
6 |
7 | @import '~@ionic/angular/css/padding.css';
8 | @import '~@ionic/angular/css/float-elements.css';
9 | @import '~@ionic/angular/css/text-alignment.css';
10 | @import '~@ionic/angular/css/text-transformation.css';
11 | @import '~@ionic/angular/css/flex-utils.css';
12 |
13 | .ion-page {
14 | height: 100%;
15 | width: 100%;
16 | }
17 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Ionic App
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/1.0/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular-devkit/build-angular'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage-istanbul-reporter'),
13 | require('@angular-devkit/build-angular/plugins/karma')
14 | ],
15 | client: {
16 | clearContext: false // leave Jasmine Spec Runner output visible in browser
17 | },
18 | coverageIstanbulReporter: {
19 | dir: require('path').join(__dirname, '../coverage'),
20 | reports: ['html', 'lcovonly', 'text-summary'],
21 | fixWebpackSourcePaths: true
22 | },
23 | reporters: ['progress', 'kjhtml'],
24 | port: 9876,
25 | colors: true,
26 | logLevel: config.LOG_INFO,
27 | autoWatch: true,
28 | browsers: ['Chrome'],
29 | singleRun: false
30 | });
31 | };
32 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule)
12 | .catch(err => console.log(err));
13 |
--------------------------------------------------------------------------------
/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/guide/browser-support
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /** IE9, IE10, IE11, and Chrome <55 requires all of the following polyfills.
22 | * This also includes Android Emulators with older versions of Chrome and Google Search/Googlebot
23 | */
24 |
25 | // import 'core-js/es6/symbol';
26 | // import 'core-js/es6/object';
27 | // import 'core-js/es6/function';
28 | // import 'core-js/es6/parse-int';
29 | // import 'core-js/es6/parse-float';
30 | // import 'core-js/es6/number';
31 | // import 'core-js/es6/math';
32 | // import 'core-js/es6/string';
33 | // import 'core-js/es6/date';
34 | // import 'core-js/es6/array';
35 | // import 'core-js/es6/regexp';
36 | // import 'core-js/es6/map';
37 | // import 'core-js/es6/weak-map';
38 | // import 'core-js/es6/set';
39 |
40 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
41 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
42 |
43 | /** IE10 and IE11 requires the following for the Reflect API. */
44 | // import 'core-js/es6/reflect';
45 |
46 | /**
47 | * Web Animations `@angular/platform-browser/animations`
48 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
49 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
50 | */
51 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
52 |
53 | /**
54 | * By default, zone.js will patch all possible macroTask and DomEvents
55 | * user can disable parts of macroTask/DomEvents patch by setting following flags
56 | * because those flags need to be set before `zone.js` being loaded, and webpack
57 | * will put import in the top of bundle, so user need to create a separate file
58 | * in this directory (for example: zone-flags.ts), and put the following flags
59 | * into that file, and then add the following code before importing zone.js.
60 | * import './zone-flags.ts';
61 | *
62 | * The flags allowed in zone-flags.ts are listed here.
63 | *
64 | * The following flags will work for all browsers.
65 | *
66 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
67 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
68 | * (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
69 | *
70 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
71 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
72 | *
73 | * (window as any).__Zone_enable_cross_context_check = true;
74 | *
75 | */
76 |
77 | /***************************************************************************************************
78 | * Zone JS is required by default for Angular itself.
79 | */
80 | import 'zone.js/dist/zone'; // Included with Angular CLI.
81 |
82 |
83 | /***************************************************************************************************
84 | * APPLICATION IMPORTS
85 | */
86 |
--------------------------------------------------------------------------------
/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/zone-testing';
4 | import { getTestBed } from '@angular/core/testing';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting
8 | } from '@angular/platform-browser-dynamic/testing';
9 |
10 | declare const require: any;
11 |
12 | // First, initialize the Angular testing environment.
13 | getTestBed().initTestEnvironment(
14 | BrowserDynamicTestingModule,
15 | platformBrowserDynamicTesting()
16 | );
17 | // Then we find all the tests.
18 | const context = require.context('./', true, /\.spec\.ts$/);
19 | // And load the modules.
20 | context.keys().map(context);
21 |
--------------------------------------------------------------------------------
/src/theme/variables.scss:
--------------------------------------------------------------------------------
1 | // Ionic Variables and Theming. For more info, please see:
2 | // http://ionicframework.com/docs/theming/
3 |
4 | /** Ionic CSS Variables **/
5 | :root {
6 | /** primary **/
7 | --ion-color-primary: #c8193c;
8 | --ion-color-primary-rgb: 56, 128, 255;
9 | --ion-color-primary-contrast: #ffffff;
10 | --ion-color-primary-contrast-rgb: 255, 255, 255;
11 | --ion-color-primary-shade: #3171e0;
12 | --ion-color-primary-tint: #4c8dff;
13 |
14 | /** secondary **/
15 | --ion-color-secondary: #0cd1e8;
16 | --ion-color-secondary-rgb: 12, 209, 232;
17 | --ion-color-secondary-contrast: #ffffff;
18 | --ion-color-secondary-contrast-rgb: 255, 255, 255;
19 | --ion-color-secondary-shade: #0bb8cc;
20 | --ion-color-secondary-tint: #24d6ea;
21 |
22 | /** tertiary **/
23 | --ion-color-tertiary: #7044ff;
24 | --ion-color-tertiary-rgb: 112, 68, 255;
25 | --ion-color-tertiary-contrast: #ffffff;
26 | --ion-color-tertiary-contrast-rgb: 255, 255, 255;
27 | --ion-color-tertiary-shade: #633ce0;
28 | --ion-color-tertiary-tint: #7e57ff;
29 |
30 | /** success **/
31 | --ion-color-success: #10dc60;
32 | --ion-color-success-rgb: 16, 220, 96;
33 | --ion-color-success-contrast: #ffffff;
34 | --ion-color-success-contrast-rgb: 255, 255, 255;
35 | --ion-color-success-shade: #0ec254;
36 | --ion-color-success-tint: #28e070;
37 |
38 | /** warning **/
39 | --ion-color-warning: #ffce00;
40 | --ion-color-warning-rgb: 255, 206, 0;
41 | --ion-color-warning-contrast: #ffffff;
42 | --ion-color-warning-contrast-rgb: 255, 255, 255;
43 | --ion-color-warning-shade: #e0b500;
44 | --ion-color-warning-tint: #ffd31a;
45 |
46 | /** danger **/
47 | --ion-color-danger: #f04141;
48 | --ion-color-danger-rgb: 245, 61, 61;
49 | --ion-color-danger-contrast: #ffffff;
50 | --ion-color-danger-contrast-rgb: 255, 255, 255;
51 | --ion-color-danger-shade: #d33939;
52 | --ion-color-danger-tint: #f25454;
53 |
54 | /** dark **/
55 | --ion-color-dark: #222428;
56 | --ion-color-dark-rgb: 34, 34, 34;
57 | --ion-color-dark-contrast: #ffffff;
58 | --ion-color-dark-contrast-rgb: 255, 255, 255;
59 | --ion-color-dark-shade: #1e2023;
60 | --ion-color-dark-tint: #383a3e;
61 |
62 | /** medium **/
63 | --ion-color-medium: #989aa2;
64 | --ion-color-medium-rgb: 152, 154, 162;
65 | --ion-color-medium-contrast: #ffffff;
66 | --ion-color-medium-contrast-rgb: 255, 255, 255;
67 | --ion-color-medium-shade: #86888f;
68 | --ion-color-medium-tint: #a2a4ab;
69 |
70 | /** light **/
71 | --ion-color-light: #f4f5f8;
72 | --ion-color-light-rgb: 244, 244, 244;
73 | --ion-color-light-contrast: #000000;
74 | --ion-color-light-contrast-rgb: 0, 0, 0;
75 | --ion-color-light-shade: #d7d8da;
76 | --ion-color-light-tint: #f5f6f9;
77 | }
78 |
79 | .image-filters-action-sheet .action-sheet-group {
80 | overflow: scroll;
81 | }
82 |
--------------------------------------------------------------------------------
/src/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/app",
5 | "types": []
6 | },
7 | "exclude": [
8 | "test.ts",
9 | "**/*.spec.ts",
10 | "../node_modules"
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/src/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/spec",
5 | "types": [
6 | "jasmine",
7 | "node"
8 | ]
9 | },
10 | "files": [
11 | "test.ts",
12 | "polyfills.ts"
13 | ],
14 | "include": [
15 | "**/*.spec.ts",
16 | "**/*.d.ts"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/src/utils/byte-array-utils.ts:
--------------------------------------------------------------------------------
1 |
2 | export class ByteArrayUtils {
3 | static toHex(rawBytes: number[]): string {
4 | return Array.from(rawBytes, function(byte) {
5 | return ('0' + (byte & 0xFF).toString(16)).slice(-2);
6 | }).join('')
7 | }
8 |
9 | static fromHex(hex: string): number[] {
10 | let bytes = [];
11 | for (let c = 0; c < hex.length; c += 2) {
12 | bytes.push(parseInt(hex.substring(c, c + 2), 16));
13 | }
14 | return bytes;
15 | }
16 |
17 | static toBase64(rawBytes: number[]): string {
18 | const bytes = new Uint8Array(rawBytes);
19 | const len = bytes.byteLength;
20 | let binary = '';
21 | for (let i = 0; i < len; i++) {
22 | binary += String.fromCharCode(bytes[i]);
23 | }
24 | return window.btoa(binary);
25 | }
26 |
27 | static fromBase64(base64: string): number[] {
28 | let binary_string = window.atob(base64);
29 | let len = binary_string.length;
30 | let bytes = new Uint8Array(len);
31 | for (let i=0; i {
28 | return [
29 | sectionValueItem('Type', document.type.name),
30 | sectionValueItem('Confidence', document.confidence.toString()),
31 | ];
32 | }
33 |
34 | function gdrFields(document: GenericDocumentWrapper) {
35 | return Object.entries(document)
36 | .filter(([_, value]) => isGenericDocumentField(value))
37 | .map(([key, value]) => sectionFieldItem(key, value));
38 | }
39 |
40 | export const GenericDocumentUtils = {
41 | gdrCommonFields,
42 | gdrFields,
43 | sectionValueItem,
44 | sectionImageItem,
45 | sectionFieldItem,
46 | };
--------------------------------------------------------------------------------
/src/utils/image-filters.ts:
--------------------------------------------------------------------------------
1 | import {ImageFilterType} from 'cordova-plugin-scanbot-sdk';
2 |
3 | export const IMAGE_FILTER_LIST: ImageFilterType[] = [
4 | 'BINARIZED',
5 | 'BLACK_AND_WHITE',
6 | 'COLOR',
7 | 'COLOR_DOCUMENT',
8 | 'DEEP_BINARIZATION',
9 | 'EDGE_HIGHLIGHT',
10 | 'GRAYSCALE',
11 | 'LOW_LIGHT_BINARIZATION',
12 | 'LOW_LIGHT_BINARIZATION_2',
13 | 'NONE',
14 | 'OTSU_BINARIZATION',
15 | 'PURE_BINARIZED',
16 | 'PURE_GRAY',
17 | ];
18 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "outDir": "./dist/out-tsc",
6 | "sourceMap": true,
7 | "declaration": false,
8 | "module": "es2022",
9 | "moduleResolution": "node",
10 | "emitDecoratorMetadata": true,
11 | "experimentalDecorators": true,
12 | "importHelpers": true,
13 | "target": "es2022",
14 | "typeRoots": [
15 | "node_modules/@types"
16 | ],
17 | "lib": [
18 | "es2020",
19 | "dom"
20 | ]
21 | },
22 | "exclude": [
23 | "plugins/"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/typings/cordova-typings.d.ts:
--------------------------------------------------------------------------------
1 |
2 | ///
3 | ///
--------------------------------------------------------------------------------