思路
UI视图
上传身份证照片可以选择拍照方式上传,相册选择方式上传即可
身份证照片进行认证功能实现
对身份证照片进行认证,包括正面认证和反面认证即可上传给后端
使用第三方插件
image_picker: ^0.8.4
Future<XFile> _getCameraImage() async {
final cameraImages = await picker.pickImage(source: ImageSource.camera);
return cameraImages;
}
Future _getImage() async {
final pickerImages = await picker.pickImage(source: ImageSource.gallery);
return pickerImages;
}
click(int index) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
10,
),
),
clipBehavior: Clip.antiAlias,
builder: (context) {
return SingleImageDialog(arrList: [
{'text': '拍照'},
{'text': '从相册选取'},
{'text': '取消'}
]);
},
).then((value) async {
if (value != null) {
var pickerImage =
value == 0 ? await _getCameraImage() : await _getImage();
if (pickerImage != null) {
//此处修改
int result = await _getInfo(File(pickerImage.path), index);
switch (result) {
case 0:
showToast('图片检测失败请重新选择');
break;
case 1:
if (index == 0) {
_userFrontImage = File(pickerImage.path);
print('图片路径:${_userFrontImage.toString()}');
CommonViewModel().uploadFile(_userFrontImage.path, (path) {
if (path.length > 0) {
imageFrontUrl = path;
} else {
showToast('上传失败');
_userFrontImage = null;
}
if (this.mounted) setState(() {});
});
}
if (index == 1) {
_userBackImage = File(pickerImage.path);
print('图片路径:${_userBackImage.toString()}');
CommonViewModel().uploadFile(_userBackImage.path, (path) {
if (path.length > 0) {
imageBackUrl = path;
} else {
showToast('上传失败');
_userBackImage = null;
}
if (this.mounted) setState(() {});
});
}
if (index == 2) {
_userImageTo = File(pickerImage.path);
print('图片路径:${_userImageTo.toString()}');
CommonViewModel().uploadFile(_userImageTo.path, (path) {
if (path.length > 0) {
peopleImageUrl = path;
} else {
showToast('上传失败');
_userImageTo = null;
}
if (this.mounted) setState(() {});
});
}
break;
case 2:
showToast('未检测到信息,请重新选择清晰的图片');
break;
case 3:
showToast('请注意拍摄角度正确,照片文字清晰');
break;
}
}
}
});
}
Future<int> _getInfo(File img, int type) async {
if (type == 2) return 1;
try {
List<int> imageBytes = img.readAsBytesSync();
print(imageBytes);
//将字节列表转为base64格式
String base64Image = base64Encode(imageBytes);
// Dio dio = new Dio(BaseOptions(
// connectTimeout: 30000,
// receiveTimeout: 30000,
// // contentType:
// ));
// dio.interceptors.add(LogInterceptor(responseBody: false)); //开启请求日志
EasyLoading.show(dismissOnTap: false);
if (accessToken == null) {
String tokenUrl = baiduApi +
"grant_type=" +
baiduGrantType +
"&client_id=" +
baiduClientId +
"&client_secret=" +
baiduClientSecret;
Response response = await DioUtil().getDio().post(tokenUrl);
accessToken = response.data['access_token'].toString();
}
String ocrUrl = baiduRestApi + "access_token=" + accessToken;
Response res = await DioUtil().getDio().post(ocrUrl,
data: {"image": base64Image},
options: new Options(
contentType:
ContentType.parse("application/x-www-form-urlencoded")
.toString()));
EasyLoading.dismiss();
int wordsNum = int.parse(res.data["words_result_num"].toString());
String ocrContent = '';
if (wordsNum > 0) {
var array = res.data["words_result"];
for (var ar in array) {
ocrContent += ar["words"].toString();
// ocrContent += ar["words"].toString()+"\n";
}
print(ocrContent);
print('-=-=-=-=-=-=-=-=');
if (type == 0) {
frontInfo = ocrContent;
return frontInfo.contains('姓名') &&
frontInfo.contains('性别') &&
frontInfo.contains('民族') &&
frontInfo.contains('出生') &&
frontInfo.contains('年') &&
frontInfo.contains('月') &&
frontInfo.contains('日') &&
frontInfo.contains('住址') &&
frontInfo.contains('公民身份号码')
? 1
: 3;
} else {
return ocrContent.contains('中华人民共和国居民身份证') &&
ocrContent.contains('签发机关') &&
ocrContent.contains('有效期限')
? 1
: 3;
}
} else {
return 2;
}
} catch (e) {
print('$e-------------------------------------------------------');
EasyLoading.dismiss();
return 0;
}
}