flutter_face_api 5.2.3 flutter_face_api: ^5.2.3 copied to clipboard
This is a flutter module for compairing faces using phone`s camera.
import 'dart:convert';
import 'dart:io' as io;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'package:flutter_face_api/face_api.dart' as Regula;
import 'package:image_picker/image_picker.dart';
void main() => runApp(new MaterialApp(home: new MyApp()));
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
var image1 = new Regula.MatchFacesImage();
var image2 = new Regula.MatchFacesImage();
var img1 = Image.asset('assets/images/portrait.png');
var img2 = Image.asset('assets/images/portrait.png');
String _similarity = "nil";
String _liveness = "nil";
@override
void initState() {
super.initState();
initPlatformState();
const EventChannel('flutter_face_api/event/video_encoder_completion')
.receiveBroadcastStream()
.listen((event) {
var completion = Regula.VideoEncoderCompletion.fromJson(json.decode(event))!;
print("VideoEncoderCompletion:");
print(" success: ${completion.success}");
print(" transactionId: ${completion.transactionId}");
});
const EventChannel('flutter_face_api/event/onCustomButtonTappedEvent')
.receiveBroadcastStream()
.listen((event) {
print("Pressed button with id: $event");
});
const EventChannel('flutter_face_api/event/livenessNotification')
.receiveBroadcastStream()
.listen((event) {
var notification = Regula.LivenessNotification.fromJson(json.decode(event));
print("LivenessProcessStatus: ${notification!.status}");
});
}
Future<void> initPlatformState() async {
Regula.FaceSDK.init().then((json) {
var response = jsonDecode(json);
if (!response["success"]) {
print("Init failed: ");
print(json);
}
});
}
showAlertDialog(BuildContext context, bool first) => showDialog(
context: context,
builder: (BuildContext context) =>
AlertDialog(title: Text("Select option"), actions: [
// ignore: deprecated_member_use
TextButton(
child: Text("Use gallery"),
onPressed: () {
Navigator.of(context, rootNavigator: true).pop();
ImagePicker()
.pickImage(source: ImageSource.gallery)
.then((value) => {
setImage(
first,
io.File(value!.path).readAsBytesSync(),
Regula.ImageType.PRINTED)
});
}),
// ignore: deprecated_member_use
TextButton(
child: Text("Use camera"),
onPressed: () {
Regula.FaceSDK.presentFaceCaptureActivity().then((result) {
var response = Regula.FaceCaptureResponse.fromJson(
json.decode(result))!;
if (response.image != null &&
response.image!.bitmap != null)
setImage(
first,
base64Decode(
response.image!.bitmap!.replaceAll("\n", "")),
Regula.ImageType.LIVE);
});
Navigator.pop(context);
})
]));
setImage(bool first, Uint8List? imageFile, int type) {
if (imageFile == null) return;
setState(() => _similarity = "nil");
if (first) {
image1.bitmap = base64Encode(imageFile);
image1.imageType = type;
setState(() {
img1 = Image.memory(imageFile);
_liveness = "nil";
});
} else {
image2.bitmap = base64Encode(imageFile);
image2.imageType = type;
setState(() => img2 = Image.memory(imageFile));
}
}
clearResults() {
setState(() {
img1 = Image.asset('assets/images/portrait.png');
img2 = Image.asset('assets/images/portrait.png');
_similarity = "nil";
_liveness = "nil";
});
image1 = new Regula.MatchFacesImage();
image2 = new Regula.MatchFacesImage();
}
matchFaces() {
if (image1.bitmap == null ||
image1.bitmap == "" ||
image2.bitmap == null ||
image2.bitmap == "") return;
setState(() => _similarity = "Processing...");
var request = new Regula.MatchFacesRequest();
request.images = [image1, image2];
Regula.FaceSDK.matchFaces(jsonEncode(request)).then((value) {
var response = Regula.MatchFacesResponse.fromJson(json.decode(value));
Regula.FaceSDK.matchFacesSimilarityThresholdSplit(
jsonEncode(response!.results), 0.75)
.then((str) {
var split = Regula.MatchFacesSimilarityThresholdSplit.fromJson(
json.decode(str));
setState(() => _similarity = split!.matchedFaces.length > 0
? ((split.matchedFaces[0]!.similarity! * 100).toStringAsFixed(2) +
"%")
: "error");
});
});
}
liveness() => Regula.FaceSDK.startLiveness().then((value) {
var result = Regula.LivenessResponse.fromJson(json.decode(value));
if(result!.bitmap == null) return;
setImage(true, base64Decode(result.bitmap!.replaceAll("\n", "")),
Regula.ImageType.LIVE);
setState(() => _liveness =
result.liveness == Regula.LivenessStatus.PASSED
? "passed"
: "unknown");
});
Widget createButton(String text, VoidCallback onPress) => Container(
// ignore: deprecated_member_use
child: TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(Colors.blue),
backgroundColor: MaterialStateProperty.all<Color>(Colors.black12),
),
onPressed: onPress,
child: Text(text)),
width: 250,
);
Widget createImage(image, VoidCallback onPress) => Material(
child: InkWell(
onTap: onPress,
child: Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Image(height: 150, width: 150, image: image),
),
),
));
@override
Widget build(BuildContext context) => Scaffold(
body: Container(
margin: EdgeInsets.fromLTRB(0, 0, 0, 100),
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
createImage(img1.image, () => showAlertDialog(context, true)),
createImage(
img2.image, () => showAlertDialog(context, false)),
Container(margin: EdgeInsets.fromLTRB(0, 0, 0, 15)),
createButton("Match", () => matchFaces()),
createButton("Liveness", () => liveness()),
createButton("Clear", () => clearResults()),
Container(
margin: EdgeInsets.fromLTRB(0, 15, 0, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Similarity: " + _similarity,
style: TextStyle(fontSize: 18)),
Container(margin: EdgeInsets.fromLTRB(20, 0, 0, 0)),
Text("Liveness: " + _liveness,
style: TextStyle(fontSize: 18))
],
))
])),
);
}