splicerai 0.0.8
splicerai: ^0.0.8 copied to clipboard
Developer Friendly Document Automation plugin for document classification,Masking,extraction & verification From Extrieve.
example/lib/main.dart
/// Sample Flutter application demonstrating the use of the SplicerAi Flutter plugin.
///
/// This application allows users to:
/// - Attach an image from the gallery.
/// - Mask Aadhaar card details in the image.
/// - Detect KYC documents.
/// - Extract information from KYC documents.
/// - Verify KYC documents by selecting a document type from a list.
///
/// The application showcases how to integrate and use various features of the SplicerAi plugin.
///
/// Author: Extrieve Technologies
/// Website: https://www.extrieve.com
/// Extrieve Technologies - Your Expert in Document Management & AI Solutions
library;
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:splicerai/splicerai.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'dart:io';
import 'dart:convert';
import 'dart:typed_data';
void main() {
runApp(const MyApp());
}
/// The root widget of the application.
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'SplicerAi Flutter Plugin Example',
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
/// The home page widget that displays the main functionality.
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
HomePageState createState() => HomePageState();
}
/// The state class for the home page widget.
class HomePageState extends State<HomePage> {
// Image picker for selecting images from the gallery
final ImagePicker _picker = ImagePicker();
// Path to the original selected image
String? _selectedImagePath;
// Path to the processed image (e.g., masked Aadhaar)
String? _processedImagePath;
// Stores the KYC response data as a JSON string
String? _kycResponseData;
// Indicates whether a process is currently loading
bool _isLoading = false;
// List of supported KYC documents
List<String> _supportedKYCDocs = [];
@override
void initState() {
super.initState();
// Activate the SplicerAi license
activateLicense();
// Fetch the list of supported KYC documents
fetchSupportedKYCDocList();
}
/// Activates the SplicerAi license.
/// In production, ensure that license keys are securely managed.
Future<void> activateLicense() async {
// TODO: Securely fetch license keys from a secure source.
String androidLicense = "<Your Android License Key>";
String iosLicense = "<Your iOS License Key>";
try {
bool? isActivated = await SplicerAi().activateLicense(
android: androidLicense,
ios: iosLicense,
);
if (isActivated == true) {
_showToast("License activated successfully", isSuccess: true);
} else {
_showToast("License activation failed. Please check your license.",
isSuccess: false);
// Optionally disable functionality or exit the app.
}
} catch (e) {
_showToast("Error activating license: ${e.toString()}", isSuccess: false);
}
}
/// Fetches the list of supported KYC documents from SplicerAi.
/// The list is stored in [_supportedKYCDocs] state variable.
Future<void> fetchSupportedKYCDocList() async {
try {
String? jsonString = await SplicerAi.getSupportedKYCDocList();
if (jsonString != null && jsonString.isNotEmpty) {
// Parse the JSON string to a List<String>
List<dynamic> jsonList = jsonDecode(jsonString);
List<String> docs = jsonList.map((item) => item.toString()).toList();
setState(() {
_supportedKYCDocs = docs;
});
} else {
_showSnackBar('No supported KYC documents found.');
}
} catch (e) {
_showSnackBar('Error fetching KYC documents: ${e.toString()}');
}
}
/// Picks an image from the gallery using [ImagePicker].
/// The selected image path is stored in [_selectedImagePath].
Future<void> _pickImage() async {
try {
final XFile? pickedFile =
await _picker.pickImage(source: ImageSource.gallery);
if (pickedFile != null) {
setState(() {
_selectedImagePath = pickedFile.path;
_processedImagePath = null; // Reset the processed image
_kycResponseData = null; // Clear previous KYC data
});
} else {
_showSnackBar('No image selected');
}
} catch (e) {
_showSnackBar('Error picking image: ${e.toString()}');
}
}
/// Processes the selected image to mask Aadhaar details using SplicerAi.
/// The processed image path is stored in [_processedImagePath].
Future<void> _processAadhaarMask() async {
if (_selectedImagePath == null) {
_showSnackBar('Please attach an image first');
return;
}
setState(() => _isLoading = true);
try {
String? result = await SplicerAi.maskAadhaar(_selectedImagePath!);
if (result != null) {
// Generate a new file path for the processed image
String newPath = _selectedImagePath!.replaceFirstMapped(
RegExp(r'(\.\w+)$'), // Matches the file extension
(Match match) => '_masked${match.group(1)}',
);
// Copy the processed image to the new path
await File(result).copy(newPath);
setState(() {
_processedImagePath = newPath;
});
_showSnackBar('Aadhaar masked successfully');
// Debugging: print the paths
print('Original image path: $_selectedImagePath');
print('Processed image path: $_processedImagePath');
if (await File(_processedImagePath!).exists()) {
print('Processed image saved successfully at $_processedImagePath');
} else {
print('Processed image file does not exist at $_processedImagePath');
}
} else {
_showSnackBar('Failed to mask Aadhaar');
}
} catch (e) {
_showSnackBar('Error in Aadhaar masking: ${e.toString()}');
} finally {
setState(() => _isLoading = false);
}
}
/// Processes the KYC document based on the specified [type].
/// [type] can be 'detect' or 'extract'.
Future<void> _processKYC(String type) async {
if (_selectedImagePath == null) {
_showSnackBar('Please attach an image first');
return;
}
setState(() => _isLoading = true);
try {
String? result;
if (type == 'detect') {
result = await SplicerAi.detectKYCDocument(_selectedImagePath!);
} else if (type == 'extract') {
result = await SplicerAi.extractKYCDocument(_selectedImagePath!);
}
if (result != null) {
setState(() {
_kycResponseData = result; // Store the JSON response
});
_showSnackBar('KYC $type processed successfully');
} else {
_showSnackBar('Failed to process KYC: $type');
}
} catch (e) {
_showSnackBar('Error in KYC $type processing: ${e.toString()}');
} finally {
setState(() => _isLoading = false);
}
}
/// Opens a dialog for KYC verification.
/// The user can select a document type from a dropdown list.
void _openKYCVerifyDialog() {
if (_selectedImagePath == null) {
_showSnackBar('Please attach an image first');
return;
}
if (_supportedKYCDocs.isEmpty) {
_showSnackBar('No supported KYC documents available');
return;
}
String? selectedDoc; // Variable to hold the selected document
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('KYC Verify'),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min, // Allow the column to shrink
children: [
// Display the image with constrained height
FutureBuilder<Uint8List>(
future: File(_selectedImagePath!).readAsBytes(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
return Image.memory(
snapshot.data!,
fit: BoxFit.contain,
width: MediaQuery.of(context).size.width * 0.8,
height: MediaQuery.of(context).size.height * 0.4,
);
} else {
return const CircularProgressIndicator();
}
},
),
const SizedBox(height: 20),
// Dropdown to select the document
DropdownButtonFormField<String>(
decoration: const InputDecoration(
labelText: 'Select Document',
border: OutlineInputBorder(),
),
items: _supportedKYCDocs.map((String doc) {
return DropdownMenuItem<String>(
value: doc,
child: Text(doc),
);
}).toList(),
onChanged: (String? newValue) {
selectedDoc = newValue;
},
),
],
),
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(); // Close the dialog
},
child: const Text('Cancel'),
),
ElevatedButton(
onPressed: () {
if (selectedDoc != null) {
Navigator.of(context).pop(); // Close the dialog
_verifyKYC(selectedDoc!);
} else {
_showSnackBar('Please select a document');
}
},
child: const Text('Verify'),
),
],
);
},
);
}
/// Verifies the selected KYC document using SplicerAi.
/// [documentType] is the type of document selected by the user.
Future<void> _verifyKYC(String documentType) async {
setState(() => _isLoading = true);
try {
String? result = await SplicerAi.verifyKYCDocument(
_selectedImagePath!,
documentType,
);
if (result != null) {
setState(() {
_kycResponseData = result; // Store the JSON response
});
_showSnackBar('KYC verification successful');
} else {
_showSnackBar('KYC verification failed');
}
} catch (e) {
_showSnackBar('Error during KYC verification: ${e.toString()}');
} finally {
setState(() => _isLoading = false);
}
}
/// Displays a SnackBar with the provided [message].
void _showSnackBar(String message) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message)),
);
}
/// Displays a Toast message.
/// [isSuccess] determines the background color of the Toast.
void _showToast(String message, {required bool isSuccess}) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
backgroundColor: isSuccess ? Colors.green : Colors.red,
textColor: Colors.white,
fontSize: 16.0,
);
}
/// Builds the UI of the application.
@override
Widget build(BuildContext context) {
// Determine which image to display
String? displayImagePath = _processedImagePath ?? _selectedImagePath;
return Scaffold(
appBar: AppBar(
title: const Text('SplicerAi Flutter Plugin Example'),
),
body: Stack(
children: [
SingleChildScrollView(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.center, // Center all widgets horizontally
children: [
const SizedBox(height: 20),
// Center the Attach Image button
Center(
child: ElevatedButton(
onPressed: _pickImage,
child: const Text('Attach Image'),
),
),
const SizedBox(height: 20),
if (displayImagePath != null) ...[
// Display the image
Column(
children: [
const Text(
'Selected Image',
style: TextStyle(
fontSize: 16, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
FutureBuilder<Uint8List>(
future: File(displayImagePath).readAsBytes(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
return Image.memory(
snapshot.data!,
fit: BoxFit.contain,
width: MediaQuery.of(context).size.width * 0.8,
);
} else {
return const CircularProgressIndicator();
}
},
),
],
),
const SizedBox(height: 20),
// Action Buttons
Wrap(
spacing: 10,
runSpacing: 10,
alignment: WrapAlignment.center, // Center the buttons
children: [
ElevatedButton(
onPressed: _processAadhaarMask,
child: const Text('Aadhaar Mask'),
),
ElevatedButton(
onPressed: () => _processKYC('detect'),
child: const Text('KYC Detect'),
),
ElevatedButton(
onPressed: () => _processKYC('extract'),
child: const Text('KYC Extract'),
),
ElevatedButton(
onPressed: _openKYCVerifyDialog,
child: const Text('KYC Verify'),
),
],
),
],
if (_kycResponseData != null) ...[
const SizedBox(height: 20),
const Text(
'Response Data:',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
),
Container(
margin: const EdgeInsets.all(10),
padding: const EdgeInsets.all(10),
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width *
0.9, // Limit the width
maxHeight: MediaQuery.of(context).size.height * 0.4,
),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(8),
),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Text(
const JsonEncoder.withIndent(' ')
.convert(jsonDecode(_kycResponseData!)),
style: const TextStyle(fontSize: 14),
),
),
),
],
],
),
),
if (_isLoading)
// Display a modal progress indicator
Container(
color: Colors.black.withOpacity(0.5),
child: const Center(child: CircularProgressIndicator()),
),
],
),
);
}
}