splicerai 0.0.8 copy "splicerai: ^0.0.8" to clipboard
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()),
            ),
        ],
      ),
    );
  }
}
4
likes
160
points
168
downloads

Publisher

verified publisherextrieve.com

Weekly Downloads

Developer Friendly Document Automation plugin for document classification,Masking,extraction & verification From Extrieve.

Homepage

Documentation

API reference

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on splicerai