face_capture 0.0.1 copy "face_capture: ^0.0.1" to clipboard
face_capture: ^0.0.1 copied to clipboard

A neww Flutter plugin project face_capture.

example/lib/main.dart

// ignore_for_file: depend_on_referenced_packages

import 'package:face_capture_example/splash_screen.dart';
import 'package:face_capture_example/web_view_container.dart';
import 'package:flutter/material.dart';
import 'package:face_capture/face_capture.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:permission_handler/permission_handler.dart';

import 'package:http/http.dart';

import 'fc_about.dart';
import 'fc_settings.dart';
import 'globals.dart';
import 'globals.dart' as globals;
import 'init.dart';
import 'liveness_json.dart';
import 'capture_page.dart';


void main() async {
  if (Globals.faceCaptureLibrary != null) {
    Globals.faceCaptureLibrary!.dispose();
    debugPrint("MainPage DESTROY.....");
  } else {
    Globals.faceCaptureLibrary = null;
    Globals.faceCaptureWorkflow = null;

    Globals.profiles = [];

    Globals.userName = "";
    Globals.cameraPosition = "";
    Globals.screenOrientation = Orientation.portrait;
    Globals.packageType = "";
    Globals.livenessUrl = "";
    Globals.workflow = "";
    Globals.captureTimeout = "";
    Globals.profile = "";
    Globals.livenessServerVersion = "";
    Globals.faceCaptureVersion = "";
    Globals.livenessServerStatus = false;
  }

  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyState createState() => _MyState();
}

class _MyState extends State<MyApp> with WidgetsBindingObserver {
  final Future _initFuture = Init.initialize();

  @override
  void initState() {
    super.initState();

    // Add the observer.
    WidgetsBinding.instance!.addObserver(this);

    checkPermission();
  }

  @override
  void dispose() {
    // Remove the observer
    WidgetsBinding.instance!.removeObserver(this);

    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);

    // These are the callbacks
    switch (state) {
      case AppLifecycleState.resumed:
      // widget is resumed
        debugPrint("MainPage On-Resumed.....");
        break;
      case AppLifecycleState.inactive:
      // widget is inactive
        debugPrint("MainPage On-Inactive.....");
        break;
      case AppLifecycleState.paused:
      // widget is paused
        debugPrint("MainPage On-Paused.....");
        break;
      case AppLifecycleState.detached:
      // widget is detached
      Globals.faceCaptureLibrary?.dispose();
        debugPrint("MainPage On-Detached.....");
        break;
    }
  }

  checkPermission() async {
    if (await Permission.camera.request().isGranted) {
      // Either the permission was already granted before or the user just granted it.
    }
  }

  @override
  Widget build(BuildContext context) {
    //Set the fit size (fill in the screen size of the device in the design) The design is based on the size of the Pixel4a (1080x2340)
    return ScreenUtilInit(
      designSize: const Size(1080, 2340),
      builder: () => MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Flutter_ScreenUtil',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          textTheme: TextTheme(button: TextStyle(fontSize: 45.sp)),
        ),
        builder: (context, widget) {
          return MediaQuery(
            //Setting font does not change with system font size
            data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
            child: widget!,
          );
        },
        // home: ActionButton(),
        home: FutureBuilder(
          future: _initFuture,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              if (snapshot.hasData) {
                globals.InitializeResult? responseData =
                globals.InitializeResult(0, "msg");
                responseData = snapshot.data as globals.InitializeResult?;
                var err = responseData?.err;
                var msg = responseData?.msg;

                debugPrint("Initialization error = $err, $msg");
              }
              return const ActionButton();
            } else {
              return const SplashScreen();
            }
          },
        ),
      ),
    );
  }
}

class ActionButton extends StatefulWidget {
  const ActionButton({Key? key}) : super(key: key);

  @override
  State<ActionButton> createState() => _ActionButtonState();
}

class CameraList {
  String number;
  int index;
  CameraList({required this.number, required this.index});
}

class _ActionButtonState extends State<ActionButton> {
  String _livenessResult = "";

  // Default Radio Button Selected Item.
  String radioItemHolder = "";

  // Group Value for Radio Button.
  int id = 0;

  List<CameraList> camList = [];

  Future<void> makePostRequest() async {
    PackageType pkgType = PackageType.highUsability;

    if (Globals.packageType == "High Usability") {
      pkgType = PackageType.highUsability;
    } else if (Globals.packageType == "Balanced") {
      pkgType = PackageType.balanced;
    } else {
      pkgType = PackageType.highSecurity;
    }

    debugPrint('packageType = $pkgType');

    String serverPackageJson = Globals.faceCaptureLibrary!
        .getServerPackage(Globals.faceCaptureWorkflow!, pkgType);

    String urlPrefix = Globals.livenessUrl;
    final url = Uri.parse('$urlPrefix/checkLiveness');
    final headers = {"Content-type": "application/json"};

    final response = await post(url, headers: headers, body: serverPackageJson);
    debugPrint('Status code: ${response.statusCode}');
    debugPrint('Body: ${response.body}');

    final welcome = welcomeFromJson(response.body);

    String decision = welcome.video.livenessResult.decision;

    setState(() {
      _livenessResult = decision;
      _showMyDialog();
    });
  }

  void _awaitReturnValueFromCapturePage(BuildContext context) async {
    // start the SecondScreen and wait for it to finish with a result
    final result = await Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => const CapturePage(),
        ));

    debugPrint("......Result=$result");
    if (result == 1) {
      //Get the liveness result.
      makePostRequest();
    }
  }

  Widget _portraitMode() {

    captureButtonPressed() {
      //Get cameras.
      int len = Globals.cameras.length;
      if(len == 1) {
        Future<int> result = _startFaceCapture(0);

        _awaitReturnValueFromCapturePage(context);

        return;
      }
      id = 0;
      camList.clear();
      for (int i = 0; i < len; i++) {
        camList.add(
          CameraList(
            number: Globals.cameras[i].getName(),
            index: i,
          ),
        );
      }
      showDialog<void>(
        context: context,
        barrierDismissible: false, // user must tap button!
        builder: (BuildContext context) {
          return AlertDialog(
            title: Center(
                child: Text('Select camera',
                    style: TextStyle(fontSize: 75.0.sp))),
            content: StatefulBuilder(
              builder: (BuildContext context,
                  StateSetter setState) =>
                  SizedBox(
                    height: 460.h,
                    child: Column(
                      children: <Widget>[
                        SizedBox(
                          height: 460.h,
                          child: Column(
                            children: camList
                                .map((data) => RadioListTile(
                              title: Text(data.number),
                              groupValue: id,
                              value: data.index,
                              onChanged: (val) {
                                setState(() {
                                  radioItemHolder =
                                      data.number;
                                  id = data.index;
                                  debugPrint(
                                      "id=$id name=$radioItemHolder");
                                });
                              },
                            ))
                                .toList(),
                          ),
                        ),
                      ],
                    ),
                  ),
            ),
            actions: <Widget>[
              Center(
                child: ElevatedButton(
                  child: const Text('OK'),
                  style: TextButton.styleFrom(
                    padding: EdgeInsets.all(12.0.w),
                    primary: Colors.white,
                    textStyle: TextStyle(fontSize: 40.0.sp),
                    backgroundColor: Colors.blue,
                  ),
                  onPressed: () {
                    Navigator.pop(context);

                    Future<int> result = _startFaceCapture(id);

                    _awaitReturnValueFromCapturePage(context);
                  },
                ),
              ),
            ],
          );
        },
      );
    }

    return SafeArea(
      child: Scaffold(
          backgroundColor: Colors.white,
          body: Center(
            child: Column(
              children: <Widget>[
                SizedBox(
                  height: 100.h,
                ),
                Image.asset(
                  'assets/aware_social.png',
                  height: 450.h,
                  width: 450.w,
                ),
                SizedBox(
                  height: 100.h,
                ),
                Text(
                  'Face Capture SDK',
                  style: TextStyle(fontSize: 75.0.sp, height: 1.0.h),
                ),
                SizedBox(
                  //Use of SizedBox
                  height: 120.h,
                ),
                Text(
                  'Sample Application',
                  style: TextStyle(fontSize: 50.0.sp, height: 1.0.h),
                ),
                SizedBox(
                  height: 150.h,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    ElevatedButton(
                      child: const Text('Capture'),
                      onPressed: Globals.livenessServerStatus ? ()=> captureButtonPressed() : null,
                    ),
                  ],
                ),
                SizedBox(
                  height: 150.h,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Text('Username:',
                        style: TextStyle(fontSize: 60.0.sp, height: null)),
                    Text(Globals.userName,
                        style: TextStyle(fontSize: 60.0.sp, height: null)),
                  ],
                ),
                SizedBox(
                  height: 50.h,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Text('Workflow:',
                        style: TextStyle(fontSize: 60.0.sp, height: null)),
                    Text(Globals.workflow,
                        style: TextStyle(fontSize: 60.0.sp, height: null)),
                  ],
                ),
                SizedBox(
                  height: 50.h,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Text('Server Status:',
                        style: TextStyle(fontSize: 60.0.sp, height: null)),
                    if (Globals.livenessServerStatus)
                      Image.asset(
                        'assets/check_icon.png',
                        height: 80.h,
                        width: 80.w,
                      )
                    else
                      Image.asset(
                        'assets/delete_icon.png',
                        height: 80.h,
                        width: 80.w,
                      ),
                  ],
                ),
              ],
            ),
          )),
    );
  }

  Widget _landscapeMode() {
    double sb1h = 150;
    double sb2h = 100;
    double sb3h = 120;
    double sb4h = 120;
    double sb5h = 120;
    double sb6h = 50;
    double sb7h = 50;
    double sb8h = 460;

    double img1h = 375;
    double img1w = 375;

    double fs1 = 90;
    double fs2 = 65;
    double fs3 = 75;

    // Adjust widgets based on if we are a tablet or phone.
    if (MediaQuery.of(context).size.height > 600) {
      //isLargeScreen = true;
      sb1h = 150;
      sb2h = 100;
      sb3h = 120;
      sb4h = 120;
      sb5h = 120;
      sb6h = 50;
      sb7h = 50;
      sb8h = 460;

      img1h = 375;
      img1w = 375;

      fs1 = 90;
      fs2 = 65;
      fs3 = 75;
    } else {
      //isLargeScreen = false;
      sb1h = 10;
      sb2h = 60;
      sb3h = 75;
      sb4h = 20;
      sb5h = 20;
      sb6h = 20;
      sb7h = 20;
      sb8h = 400;

      img1h = 175;
      img1w = 175;

      fs1 = 85;
      fs2 = 60;
      fs3 = 70;
    }

    captureButtonPressed() {
      //Get cameras.
      int len = Globals.cameras.length;
      if(len == 1) {
        Future<int> result = _startFaceCapture(0);

        _awaitReturnValueFromCapturePage(context);

        return;
      }
      id = 0;
      camList.clear();
      for (int i = 0; i < len; i++) {
        camList.add(
          CameraList(
            number: Globals.cameras[i].getName(),
            index: i,
          ),
        );
      }
      showDialog<void>(
        context: context,
        barrierDismissible: false, // user must tap button!
        builder: (BuildContext context) {
          return AlertDialog(
            title: Center(
                child: Text('Select camera',
                    style: TextStyle(fontSize: 75.0.sp))),
            content: StatefulBuilder(
              builder: (BuildContext context,
                  StateSetter setState) =>
                  SizedBox(
                    height: sb8h.h,
                    child: Column(
                      children: <Widget>[
                        SizedBox(
                          height: sb8h.h,
                          child: Column(
                            children: camList
                                .map((data) => RadioListTile(
                              title: Text(data.number),
                              groupValue: id,
                              value: data.index,
                              onChanged: (val) {
                                setState(() {
                                  radioItemHolder =
                                      data.number;
                                  id = data.index;
                                  debugPrint(
                                      "id=$id name=$radioItemHolder");
                                });
                              },
                            ))
                                .toList(),
                          ),
                        ),
                      ],
                    ),
                  ),
            ),
            actions: <Widget>[
              Center(
                child: ElevatedButton(
                  child: const Text('OK'),
                  style: TextButton.styleFrom(
                    padding: EdgeInsets.all(12.0.w),
                    primary: Colors.white,
                    textStyle: TextStyle(fontSize: 40.0.sp),
                    backgroundColor: Colors.blue,
                  ),
                  onPressed: () {
                    Navigator.pop(context);

                    Future<int> result = _startFaceCapture(id);

                    _awaitReturnValueFromCapturePage(context);
                  },
                ),
              ),
            ],
          );
        },
      );
    }

    return SafeArea(
      child: Scaffold(
          backgroundColor: Colors.white,
          body: Center(
            child: Column(
              children: <Widget>[
                SizedBox(
                  height: sb1h.h,
                ),
                Image.asset(
                  'assets/aware_social.png',
                  height: img1h.h,
                  width: img1w.w,
                ),
                SizedBox(
                  height: sb2h.h,
                ),
                Text(
                  'Face Capture SDK',
                  style: TextStyle(fontSize: fs1.sp, height: 1.0.h),
                ),
                SizedBox(
                  //Use of SizedBox
                  height: sb3h.h,
                ),
                Text(
                  'Sample Application',
                  style: TextStyle(fontSize: fs2.sp, height: 1.0.h),
                ),
                SizedBox(
                  height: sb4h.h,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    ElevatedButton(
                      child: Text(
                        'Capture',
                        style: TextStyle(fontSize: fs2.sp),
                      ),
                      onPressed: Globals.livenessServerStatus ? ()=> captureButtonPressed() : null,
                    ),
                  ],
                ),
                SizedBox(
                  height: sb5h.h,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Text('Username:',
                        style: TextStyle(fontSize: fs3.sp, height: null)),
                    Text(Globals.userName,
                        style: TextStyle(fontSize: fs3.sp, height: null)),
                  ],
                ),
                SizedBox(
                  height: sb6h.h,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Text('Workflow:',
                        style: TextStyle(fontSize: fs3.sp, height: null)),
                    Text(Globals.workflow,
                        style: TextStyle(fontSize: fs3.sp, height: null)),
                  ],
                ),
                SizedBox(
                  height: sb7h.h,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Text('Server Status:',
                        style: TextStyle(fontSize: fs3.sp, height: null)),
                    if (Globals.livenessServerStatus)
                      Image.asset(
                        'assets/check_icon.png',
                        height: 80.h,
                        width: 80.w,
                      )
                    else
                      Image.asset(
                        'assets/delete_icon.png',
                        height: 80.h,
                        width: 80.w,
                      ),
                  ],
                ),
              ],
            ),
          )),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: const Text('Face Capture Demo'),
        actions: [
          PopupMenuButton(
            itemBuilder: (BuildContext bc) => [
              const PopupMenuItem(child: Text("Settings"), value: "/settings"),
              const PopupMenuItem(child: Text("Privacy"), value: "/privacy"),
              const PopupMenuItem(child: Text("Licenses"), value: "/licenses"),
              const PopupMenuItem(child: Text("About"), value: "/about"),
            ],
            onSelected: (route) {
              debugPrint(route.toString());
              if (route == "/settings") {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => const Settings()),
                );
              }
              if (route == "/privacy") {
                Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (context) => const WebViewContainer(
                            'https://www.aware.com/privacy/mobileapps')));
              }
              if (route == "/licenses") {
                showLicensePage(context: context);
              }
              if (route == "/about") {
                showDialog(
                    context: context,
                    builder: (BuildContext context) => const About());
              }
            },
          ),
        ],
      ),
      body: OrientationBuilder(
        builder: (context, orientation) {
          if (orientation == Orientation.portrait) {
            Globals.screenOrientation = Orientation.portrait;
            return _portraitMode();
          } else {
            // Adjust widgets based on if we are a tablet or phone.
            //Only do landscape on large devices.
            if (MediaQuery.of(context).size.height > 600) {
              //isLargeScreen = true;
              Globals.screenOrientation = Orientation.landscape;
              return _landscapeMode();
            } else {
              Globals.screenOrientation = Orientation.portrait;
              SystemChrome.setPreferredOrientations(
                  [DeviceOrientation.portraitUp]
              );
              return _portraitMode();
            }
          }
        },
      ),
    );
  }

  Future<int> _startFaceCapture(int cameraId) async {
    try {
      int len = Globals.cameras.length;
      for (int i = 0; i < len; i++) {
        String name = Globals.cameras[i].getName();
        debugPrint("......_startFaceCapture-camera name$i=$name");
      }

      Globals.faceCaptureLibrary!.startCaptureSession(
          Globals.faceCaptureWorkflow!, Globals.cameras[cameraId]);

      if (Globals.screenOrientation == Orientation.portrait) {
        Globals.captureRegion = Globals.faceCaptureLibrary!.captureSessionGetCaptureRegion();
      } else {
        Globals.captureRegion = Globals.faceCaptureLibrary!.captureSessionGetCaptureRegion();
      }
      debugPrint("Capture Region = " + Globals.captureRegion.toString());
    } on FaceCaptureException catch (e) {
      debugPrint("Start Capture error-errorCode=${e.errorCode}");
    }

    return 0;
  }

  Future<void> _showMyDialog() async {
    return showDialog<void>(
      context: context,
      barrierDismissible: false, // user must tap button!
      builder: (BuildContext context) {
        return AlertDialog(
          title: Center(
              child: Text('CAPTURE', style: TextStyle(fontSize: 75.0.sp))),
          content: SingleChildScrollView(
            child: Column(
              children: <Widget>[
                Text("Video - " + _livenessResult,
                    style: TextStyle(fontSize: 68.0.sp)),
                SizedBox(
                  height: 20.h,
                ),
                Image.memory(imgBuf, scale: 3),
              ],
            ),
          ),
          actions: <Widget>[
            Center(
              child: ElevatedButton(
                child: const Text('OK'),
                style: TextButton.styleFrom(
                  padding: EdgeInsets.all(12.0.w),
                  primary: Colors.white,
                  textStyle: TextStyle(fontSize: 40.0.sp),
                  backgroundColor: Colors.blue,
                ),
                onPressed: () {
                  Navigator.pop(context);
                },
              ),
            ),
          ],
        );
      },
    );
  }
}
1
likes
100
points
20
downloads

Publisher

unverified uploader

Weekly Downloads

A neww Flutter plugin project face_capture.

Documentation

API reference

License

unknown (license)

Dependencies

ffi, flutter, plugin_platform_interface

More

Packages that depend on face_capture

Packages that implement face_capture