Page 1 | Top packages
flutter_bdface_collect
第一步
flutter_bdface_collect: 1.1.8
Android
在 Android 项目的app/src/main/assets 目录下放入百度离线采集SDK的Android授权文件,文件名固定为 idl-license.face-android SDK 会校验 apk 签名,请使用申请授权相符的签名证书
iOS
在 Info.plist 的 dict 标签内添加以下内容
<key>NSCameraUsageDescription</key>
<string>使用相机</string>
第二步
在百度云申请账号 人脸识别入口。
第三步
android
入百度离线采集SDK的Android授权文件,文件名固定为 idl-license.face-android SDK 会校验 apk 签名,请使用申请授权相符的签名证书。
android > app > src > assets > idl-license.face-android
ios
在 iOS 项目的 Runner 目录下放入百度离线采集SDK的iOS授权文件,文件名固定为 idl-license.face-ios,并将文件加入资源。
第四步
import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bdface_collect/flutter_bdface_collect.dart'; import 'package:flutter_bdface_collect/model.dart'; import 'package:inroad_flutter_new/generated/l10n.dart'; import 'package:inroad_flutter_new/pages/base/base_page_widget.dart'; import 'package:path_provider/path_provider.dart' as syspaths; import '../../configs/global_conf.dart'; import '../../configs/preference_conf.dart'; class FaceCollectPage extends BasePageWidget { FaceCollectPage({Key key}) : super(key: key); @override State<FaceCollectPage> createState() => _FaceCollectState(); } class _FaceCollectState extends State<FaceCollectPage> { Uint8List imageBytes; String _facePath = PreferenceConf.sharedPreferences.getString('userFacePath'); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( elevation: 0, iconTheme: IconThemeData(color: Colors.black), centerTitle: true, backgroundColor: Colors.white, title: GestureDetector( onTap: () { print('导航栏被点击-----'); }, child: Row( children: [ Expanded(child: Container()), Text( '面容ID查看', style: TextStyle( fontSize: 16, color: Colors.black, fontWeight: FontWeight.w500), ), Image.asset( GlobalConf.INROAD_COMMON_PATH + "images/top_title.png", width: 20, height: 20, ), Expanded(child: Container()), ], ), ), actions: [ Container( width: 40, height: 40, color: Colors.transparent, ) ], ), body: Center( child: _facePath == null ? const Text('暂无面容ID') : Image(image: FileClearCache(File(_facePath))), ), floatingActionButton: FloatingActionButton( tooltip: 'Increment', onPressed: _faceCollect, child: const Icon(Icons.face), ), ); } Future<void> _faceCollect() async { String licenseId; if (Platform.isAndroid) { licenseId = 'inroad-new-face-android'; } else if (Platform.isIOS) { licenseId = 'inroad-new-face-ios'; } var err = await FlutterBdfaceCollect.instance.init(licenseId); if (err != null) print('百度人脸采集初始化失败:$err'); var liveNessTypeList = LivenessType.all.sublist(3); var config = FaceConfig(livenessTypes: Set.from(liveNessTypeList)); CollectResult res = await FlutterBdfaceCollect.instance.collect(config); print( "百度人脸采集结果:error:${res.error} imageSrcBase64 isEmpty:${res.imageSrcBase64.isEmpty}"); if (res.imageSrcBase64.isEmpty) return setState(() => imageBytes = null); getMediaFile(res.imageSrcBase64); } Future<void> getMediaFile(String imageSrcBase64) async { imageBytes = base64Decode(imageSrcBase64); Directory temp = await syspaths.getTemporaryDirectory(); File imageFile = File('${temp.path}/images/face.jpg'); Uint8List decodedImage = imageBytes; await imageFile.create(recursive: true); await imageFile.writeAsBytes(decodedImage); setState(() { _facePath = imageFile.path; PreferenceConf.sharedPreferences .setString('userFacePath', imageFile.path); }); } } class FileClearCache extends FileImage { int fileSize; FileClearCache(File file, {double scale = 1.0}) : assert(file != null), assert(scale != null), super(file, scale: scale) { fileSize = file.lengthSync(); } @override bool operator ==(dynamic other) { if (other.runtimeType != runtimeType) return false; final FileClearCache typedOther = other; return file?.path == typedOther.file?.path && scale == typedOther.scale && fileSize == typedOther.fileSize; } @override // TODO: implement hashCode int get hashCode => super.hashCode; }