docutain_sdk 1.3.2
docutain_sdk: ^1.3.2 copied to clipboard
Flutter plugin of the Docutain Document Scanner SDK for Android and iOS. High quality document scanning, data extraction, text recognition and PDF creation for your apps. Easily scan documents in your app.
example/lib/main.dart
import 'dart:io';
import 'package:docutain_sdk/docutain_sdk_document_datareader.dart';
import 'package:docutain_sdk/docutain_sdk_logger.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:docutain_sdk/docutain_sdk.dart';
import 'package:docutain_sdk/docutain_sdk_ui.dart';
import 'package:docutain_sdk/docutain_sdk_document.dart';
import 'package:tuple/tuple.dart';
import 'package:open_file_plus/open_file_plus.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(const MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _isDocutainPluginInitialized = false;
@override
void initState() {
// TODO: implement initState
super.initState();
initDocutainSdk();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('DocutainSDK'),
),
body: Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () async {
var traceFile = await DocutainSdkLogger.getTraceFile();
OpenFile.open(traceFile?.path);
},
child: const Text('GET TRACE FILE')),
ElevatedButton(
onPressed: () async {
//do not access sdk methods if it is not yet successfully initialized
if (!_isDocutainPluginInitialized) {
_showSnackbar(
"Docutain SDK not initialized. Reason:\n${await DocutainSdk.getLastError()}");
return;
}
var scanConfig = DocumentScannerConfiguration();
//instead of using the device's camera to scan documents (default), you can also run the
//Document Scanner on imported images, for example images picked by the user from the photo gallery
//scanConfig.source = Source.galleryMultiple;
//color theming
/*scanConfig.colorConfig.colorPrimary =
const Tuple2<Color, Color>(
Colors.purple, Colors.purple);
scanConfig.colorConfig.colorSecondary =
const Tuple2<Color, Color>(
Colors.purple, Colors.purple);
scanConfig.colorConfig.colorOnSecondary =
const Tuple2<Color, Color>(
Colors.white, Colors.black);
scanConfig.colorConfig.colorScanButtonsLayoutBackground =
const Tuple2<Color, Color>(
Colors.white, Colors.black);
scanConfig.colorConfig.colorScanButtonsForeground =
const Tuple2<Color, Color>(
Colors.black, Colors.white);
scanConfig.colorConfig.colorScanPolygon =
const Tuple2<Color, Color>(
Colors.purple, Colors.purple);
scanConfig.colorConfig.colorBottomBarBackground =
const Tuple2<Color, Color>(
Colors.purple, Colors.black);
scanConfig.colorConfig.colorBottomBarForeground =
const Tuple2<Color, Color>(
Colors.white, Colors.white);
scanConfig.colorConfig.colorTopBarBackground =
const Tuple2<Color, Color>(
Colors.purple, Colors.black);
scanConfig.colorConfig.colorTopBarForeground =
const Tuple2<Color, Color>(
Colors.white, Colors.white);*/
//optionally enable/disable editing possibilities depending on your needs
//check out https://docs.docutain.com/docs/Flutter/docScan for a complete list
//of currently supported configuration values
//scanConfig.allowCaptureModeSetting = true;
//scanConfig.pageEditConfig.allowPageFilter = false;
//scanConfig.pageEditConfig.allowPageRotation = false;
//scanConfig.autoCapture = false;
//scanConfig.defaultScanFilter = ScanFilter.auto;
//...
// scanConfig.allowPageEditing = false;
//start the document scanner and wait for the result
//true if user finished the scan process successfully, false if user canceled
bool rcScan =
await DocutainSdkUi.scanDocument(scanConfig);
if (!rcScan) {
_showSnackbar("User canceled scan process.");
return;
}
//You can also import files into the backend (no UI) and run OCR text recognition,
//data analysis and PDF creation on it
/*
FilePickerResult? result = await FilePicker.platform
.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpg', 'pdf']);
if (result == null) {
//user canceled the file picker
return;
}
try {
bool rcImport =
await DocutainSdkDocumentDataReader.loadFile(
result.files.single.path!,
password: "Password1+");
if (!rcImport) {
//an error occured
var error = await DocutainSdk.getLastError();
return;
}
} on PlatformException catch (exception) {
if (exception.code == "SecurityException") {
//file is encrypted and password was wrong or empty
return;
}
}
*/
//get the page count of the currently scanned document
final pageCount = await DocutainSdkDocument.pageCount();
//get the detected text of the currently scanned document, if any available
final text =
await DocutainSdkDocumentDataReader.getText();
//get the detected data of the currently scanned document, if any available
final data =
await DocutainSdkDocumentDataReader.analyze();
//get the application documents directory where we want to save the pdf or image file
final directory =
await getApplicationDocumentsDirectory();
//you can export the scanned pages as local JPG files
/*
for (var i = 1; i <= pageCount; i++) {
var fileReturn = await DocutainSdkDocument.writeImage(
i, directory.path, "Image$i.jpg");
}
*/
//You can also get the scanned pages as JPG Uint8List
//which you can use for further processing, for example wrapping it in ByteData
/*
for (var i = 1; i <= pageCount; i++) {
var bytes = await DocutainSdkDocument.getImageBytes(i,
pageSourceType: PageSourceType.cutFilter);
}
*/
//generate the pdf from the scanned document
//returns the file if pdf was successfully generated, returns null if pdf creation failed
File? pdfFile = await DocutainSdkDocument.writePDF(
directory.path, "testPDF");
if (pdfFile != null) {
//open the generated pdf file for demonstration purposes
OpenFile.open(pdfFile.path);
} else {
//pdf creation failed, get the last error
_showSnackbar(
"PDF creation failed. Reason:\n${await DocutainSdk.getLastError()}");
}
},
child: const Text('START SCAN'))
])),
);
}
void initDocutainSdk() async {
//initialize the sdk with your key
const licenseKey = "YOUR_LICENSE_KEY_HERE";
bool isDocutainPluginInitialized = await DocutainSdk.initSDK(licenseKey);
if (!isDocutainPluginInitialized) {
if (licenseKey == "YOUR_LICENSE_KEY_HERE") {
_showLicenseEmptyDialog();
} else {
_showLicenseErrorDialog(licenseKey);
}
//get the last error message
String error = await DocutainSdk.getLastError();
//implement handling to avoid accessing Docutain SDK when it is not initialized
}
//Reading payment state and BIC when getting the analyzed data is disabled by default
//If you want to analyze these 2 fields as well, you need to set the AnalyzeConfig accordingly
//A good place to do this, is right after initializing the Docutain SDK
var analyzeConfig = AnalyzeConfiguration();
analyzeConfig.readBIC = true;
analyzeConfig.readPaymentState = true;
if (!await DocutainSdkDocumentDataReader.setAnalyzeConfiguration(
analyzeConfig)) {
//get the last error message
String error = await DocutainSdk.getLastError();
}
//set the log level depending on your needs
await DocutainSdkLogger.setLogLevel(Level.verbose);
if (!mounted) return;
setState(() {
_isDocutainPluginInitialized = isDocutainPluginInitialized;
});
}
void _showSnackbar(String message) {
SnackBar snackBar = SnackBar(
content: Text(message),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
Future<void> _showLicenseEmptyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: const Text('License needed'),
content: const SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(
'You need a trial license in order to run this example. You can generate a trial license key on our website for free.'),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('Get trial license'),
onPressed: () async {
await launchUrl(Uri.parse(
'https://sdk.docutain.com/TrialLicense?Source=3277320'));
},
),
],
);
},
);
}
Future<void> _showLicenseErrorDialog(String licenseKey) async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: const Text('License error'),
content: const SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(
'A valid license key is required. Please contact our support to get an extended trial license.'),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('Contact Support'),
onPressed: () async {
await launchUrl(Uri.parse(
'mailto:support.sdk@Docutain.com?subject=Trial License Error&body=Please keep your following trial license key in this e-mail: $licenseKey'));
},
),
],
);
},
);
}
}