Erstellen einer Emirates ID Card Scanner App mit Flutter und Google ML Kit

Apr 19 2023
Das Erstellen einer Emirates ID Card Scanner App mit Flutter und Google ML Kit kann eine nützliche und praktische Anwendung für Einzelpersonen oder Organisationen in den Vereinigten Arabischen Emiraten (VAE) sein. Diese App kann Informationen aus Emirates-ID-Karten wie Name, Nationalität, Geschlecht, ID-Nummer, Geburtsdatum, Ausstellungsdatum und Ablaufdatum des Inhabers extrahieren.
Google bilden

Das Erstellen einer Emirates ID Card Scanner App mit Flutter und Google ML Kit kann eine nützliche und praktische Anwendung für Einzelpersonen oder Organisationen in den Vereinigten Arabischen Emiraten (VAE) sein. Diese App kann Informationen aus Emirates-ID-Karten wie Name, Nationalität, Geschlecht, ID-Nummer, Geburtsdatum, Ausstellungsdatum und Ablaufdatum des Inhabers extrahieren. Die App kann die Kamera verwenden, um ein Bild des Emirates-Ausweis aufzunehmen und das Bild dann mit Google ML Kit zu verarbeiten, um die relevanten Informationen aus der Karte zu extrahieren. Dies kann Zeit und Mühe für Organisationen sparen, die eine Emirates-ID-Überprüfung benötigen, und kann auch eine bequeme Möglichkeit für Einzelpersonen sein, ihre ID-Informationen bei Bedarf abzurufen. In diesem Projekt verwenden wir Flutter, ein beliebtes plattformübergreifendes mobiles Entwicklungsframework, und Google ML Kit, eine Bibliothek für maschinelles Lernen.

Um zu beginnen, müssen wir unser Flutter-Projekt einrichten und das Google ML Kit zu unseren Abhängigkeiten hinzufügen. Wir können dies tun, indem wir der Datei pubspec.yaml unseres Projekts die folgenden Zeilen hinzufügen:

dependencies:
  flutter:
    sdk: flutter
  google_ml_kit: ^0.3.0

Als Nächstes müssen wir die Benutzeroberfläche für unsere App erstellen. Wir können das Paket in Flutter verwenden, ImagePickerum ein Kameravorschau-Widget und eine Schaltfläche zu erstellen, die den Scanvorgang der EID-Karte auslöst. Wenn der Benutzer auf die Schaltfläche klickt, erfasst die App mit der Kamera des Geräts ein Bild der EID-Karte und verwendet dann Google ML Kit, um die biometrischen Daten aus dem erfassten Bild zu extrahieren.

Hier ist ein Beispielcode für die Benutzeroberfläche:

import 'package:flutter/material.dart';
import 'package:google_ml_kit/google_ml_kit.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('EID Card Scanner'),
        ),
        body: Center(
                child: ElevatedButton(
                  onPressed: _scanEIDCard,
                  child: Text('Scan EID Card'),
            ),
         ),
      ),
    );
  }
  void _scanEIDCard() async {
    try {
      final image = await ImagePicker.pickImage(source: ImageSource.camera);
      final data = await EIDScanner.scanEmirateId(image: File(img.path));
        if (data != null) {
          print(data.toString());
        }
    } catch (e) {
      print(e);
    }
  }
}

Schließlich können wir die biometrischen Daten aus dem IdCardObjekt extrahieren und für die weitere Verarbeitung verwenden, z. B. zur Überprüfung der Identität des Benutzers oder zur Durchführung der Authentifizierung.

EIDScanner-Klassendienst

Klasse EIDScannerund eine Datenmodellklasse EmirateIdModelfür eine App, die Ausweise der Emirate in den Vereinigten Arabischen Emiraten mit Flutter und Google ML Kit scannt.

Die EIDScannerKlasse verfügt über eine statische Methode scanEmirateId(), die ein Objekt nimmt File, das ein Bild einer Emirat-ID-Karte darstellt, und ein EmirateIdModelObjekt mit den aus der Karte extrahierten Informationen zurückgibt.

/// this method will process the images and extract information from the card
  static Future<EmirateIdModel?> scanEmirateId({
    required File image,
  }) async {
    List<String> eIdDates = [];
    // GoogleMlKit.vision.languageModelManager();
    TextRecognizer textDetector = GoogleMlKit.vision.textRecognizer();
    final RecognizedText recognisedText = await textDetector.processImage(
      InputImage.fromFilePath(image.path),
    );

    // to check it is Emirate Card
    if (!recognisedText.text
            .toString()
            .toLowerCase()
            .contains("Resident ldentity Card".toLowerCase()) &&
        !recognisedText.text
            .toString()
            .toLowerCase()
            .contains("UNITED ARAB EMIRATES".toLowerCase())) {
      //throw "Invalid Emirate Card";
      return null;
    }

    final listText = recognisedText.text.split('\n');

    // attributes
    String? name;
    String? number;
    String? nationality;
    String? sex;

    listText.forEach((element) {
      if (_isDate(text: element.trim())) {
        eIdDates.add(element.trim());
      } else if (_isName(text: element.trim()) != null) {
        name = _isName(text: element.trim());
      } else if (_isNationality(text: element.trim()) != null) {
        nationality = _isNationality(text: element.trim());
      } else if (_isSex(text: element.trim()) != null) {
        sex = _isSex(text: element.trim());
      } else if (_isNumberID(text: element.trim())) {
        number = element.trim();
      }
    });

    eIdDates = _sortDateList(dates: eIdDates);

    textDetector.close();

    return EmirateIdModel(
      name: name!,
      number: number!,
      nationality: nationality,
      sex: sex,
      dateOfBirth: eIdDates.length == 3 ? eIdDates[0] : null,
      issueDate: eIdDates.length == 3 ? eIdDates[1] : null,
      expiryDate: eIdDates.length == 3 ? eIdDates[2] : null,
    );
  }

/// it will sort the dates
  static List<String> _sortDateList({required List<String> dates}) {
    List<DateTime> tempList = [];
    DateFormat format = DateFormat("dd/MM/yyyy");
    for (int i = 0; i < dates.length; i++) {
      tempList.add(format.parse(dates[i]));
    }
    tempList.sort((a, b) => a.compareTo(b));
    dates.clear();
    for (int i = 0; i < tempList.length; i++) {
      dates.add(format.format(tempList[i]));
    }
    return dates;
  }

  /// it will sort the dates
  static bool _isDate({required String text}) {
    RegExp pattern = RegExp(r'^\d{2}/\d{2}/\d{4}$');
    return pattern.hasMatch(text);
  }

  /// it will get the value of sex
  static String? _isSex({required String text}) {
    return text.startsWith("Sex:") ? text.split(":").last.trim() : null;
  }

  /// it will get the value of name
  static String? _isName({required String text}) {
    return text.startsWith("Name:") ? text.split(":").last.trim() : null;
  }

  /// it will get the value of Nationality
  static String? _isNationality({required String text}) {
    return text.startsWith("Nationality:") ? text.split(":").last.trim() : null;
  }

  /// it will get the value of Number ID
  static bool _isNumberID({required String text}) {
    RegExp pattern = RegExp(r'^\d{3}-\d{4}-\d{7}-\d{1}$');
    return pattern.hasMatch(text);
  }

Klassendienst-Implementierung

import 'dart:developer';
import 'dart:io';
import 'package:google_ml_kit/google_ml_kit.dart';
import 'package:intl/intl.dart';

class EIDScanner {
  /// this method will process the images and extract information from the card
  static Future<EmirateIdModel?> scanEmirateId({
    required File image,
  }) async {
    List<String> eIdDates = [];
    // GoogleMlKit vision languageModelManager
    TextRecognizer textDetector = GoogleMlKit.vision.textRecognizer();
    final RecognizedText recognisedText = await textDetector.processImage(
      InputImage.fromFilePath(image.path),
    );

    // to check it is Emirate Card
    if (!recognisedText.text
            .toString()
            .toLowerCase()
            .contains("Resident ldentity Card".toLowerCase()) &&
        !recognisedText.text
            .toString()
            .toLowerCase()
            .contains("UNITED ARAB EMIRATES".toLowerCase())) {
      //throw "Invalid Emirate Card";
      return null;
    }

    final listText = recognisedText.text.split('\n');

    // attributes
    String? name;
    String? number;
    String? nationality;
    String? sex;

    listText.forEach((element) {
      if (_isDate(text: element.trim())) {
        eIdDates.add(element.trim());
      } else if (_isName(text: element.trim()) != null) {
        name = _isName(text: element.trim());
      } else if (_isNationality(text: element.trim()) != null) {
        nationality = _isNationality(text: element.trim());
      } else if (_isSex(text: element.trim()) != null) {
        sex = _isSex(text: element.trim());
      } else if (_isNumberID(text: element.trim())) {
        number = element.trim();
      }
    });

    eIdDates = _sortDateList(dates: eIdDates);

    textDetector.close();

    return EmirateIdModel(
      name: name!,
      number: number!,
      nationality: nationality,
      sex: sex,
      dateOfBirth: eIdDates.length == 3 ? eIdDates[0] : null,
      issueDate: eIdDates.length == 3 ? eIdDates[1] : null,
      expiryDate: eIdDates.length == 3 ? eIdDates[2] : null,
    );
  }

  /// it will sort the dates
  static List<String> _sortDateList({required List<String> dates}) {
    List<DateTime> tempList = [];
    DateFormat format = DateFormat("dd/MM/yyyy");
    for (int i = 0; i < dates.length; i++) {
      tempList.add(format.parse(dates[i]));
    }
    tempList.sort((a, b) => a.compareTo(b));
    dates.clear();
    for (int i = 0; i < tempList.length; i++) {
      dates.add(format.format(tempList[i]));
    }
    return dates;
  }

  /// it will sort the dates
  static bool _isDate({required String text}) {
    RegExp pattern = RegExp(r'^\d{2}/\d{2}/\d{4}$');
    return pattern.hasMatch(text);
  }

  /// it will get the value of sex
  static String? _isSex({required String text}) {
    return text.startsWith("Sex:") ? text.split(":").last.trim() : null;
  }

  /// it will get the value of name
  static String? _isName({required String text}) {
    return text.startsWith("Name:") ? text.split(":").last.trim() : null;
  }

  /// it will get the value of Nationality
  static String? _isNationality({required String text}) {
    return text.startsWith("Nationality:") ? text.split(":").last.trim() : null;
  }

  /// it will get the value of Number ID
  static bool _isNumberID({required String text}) {
    RegExp pattern = RegExp(r'^\d{3}-\d{4}-\d{7}-\d{1}$');
    return pattern.hasMatch(text);
  }
}

/// this class is used to store data from package and display data on user screen

class EmirateIdModel {
  late String name;
  late String number;
  late String? issueDate;
  late String? expiryDate;
  late String? dateOfBirth;
  late String? nationality;
  late String? sex;

  EmirateIdModel({
    required this.name,
    required this.number,
    this.issueDate,
    this.expiryDate,
    this.dateOfBirth,
    this.nationality,
    this.sex,
  });

  @override
  String toString() {
    var string = '';
    string += name.isEmpty ? "" : 'Holder Name = $name\n';
    string += number.isEmpty ? "" : 'Number = $number\n';
    string += expiryDate == null ? "" : 'Expiry Date = $expiryDate\n';
    string += issueDate == null ? "" : 'Issue Date = $issueDate\n';
    string += expiryDate == null ? "" : 'Cnic Holder DoB = $expiryDate\n';
    string += nationality == null ? "" : 'Nationality = $nationality\n';
    string += sex == null ? "" : 'Sex = $sex\n';
    return string;
  }
}

Ich hoffe, dass euch allen dieser Blog gefallen hat und er euch beim Einstieg in Flutter geholfen hat! Vergessen Sie nicht, diesen Clap-Button zu zerschlagen und unten einen Kommentar zu hinterlassen.

Wir treffen uns beim nächsten.