You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

400 lines
17 KiB
Dart

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import 'dart:io';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter_drag_scale/core/drag_scale_widget.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hyzp_ybqx04_changning/components/customDialogFaceReg.dart';
import 'package:hyzp_ybqx04_changning/components/dioFun.dart';
import 'package:image_picker/image_picker.dart';
import '../../components/commonFun.dart';
import '../../services/EventBus.dart';
class FaceReg extends StatefulWidget {
FaceReg({this.arguments, Key key}) : super(key: key);
var arguments;
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<FaceReg> {
//try_setState(); //避免异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
Future<void> camerasInit() async {
try {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
print(cameras.toString());
} on CameraException catch (e) {
//logError(e.code, e.description);
}
}
String imagePath = '';
Size imageSize;
String _username;
//人脸注册页面,这里建议自动填入当前登录用户名
TextEditingController _controller = TextEditingController(text: g_userInfo.username);
@override
void initState() {
camerasInit();
//监听人脸注册数据更新事件
eventBus.on<FaceRegUpdateEvent>().listen((event) async {
print(event.str);
try_setState();
});
super.initState();
}
//监听登录页面销毁的事件
dispose() {
super.dispose();
eventBus.fire(new UserEvent('登录成功...'));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text("人脸注册",
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 50),
],
),
),
),
),
body: Container(
padding: EdgeInsets.all(ScreenUtil().setWidth(20)),
child: ListView(
children: <Widget>[
//解决 Flutter ListView 子元素 无限宽度 的问题
Container(
alignment: Alignment.topCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(
child: Container(
margin: EdgeInsets.only(top: 20, bottom: 5, left: 0, right: 0),
height: ScreenUtil().setHeight(200),
width: ScreenUtil().setWidth(260),
child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(width: 10),
Container(
padding: EdgeInsets.only(top: 16),
child: Text('用户名: ', style: TextStyle(fontSize: 18)),
),
Container(
height: ScreenUtil().setHeight(160),
width: ScreenUtil().setWidth(500),
child: TextField(
//textAlign: TextAlign.right,
textAlignVertical: TextAlignVertical.center,
maxLines: 1,
style: TextStyle(fontSize: 18),
decoration: InputDecoration(
hintText: '請輸入用户名',
//border: InputBorder.none, //TextField去掉下划线
contentPadding: EdgeInsets.only(right: 0),
enabledBorder: new UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue)),
focusedBorder: new UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue)),
),
controller: _controller,
//利用控制器初始化文本
onChanged: (value) {
_username = value;
},
),
),
SizedBox(width: 10),
Container(
width: ScreenUtil().setWidth(220),
padding: EdgeInsets.only(top: 16),
child: FlatButton(
color: Colors.black12,
child: Text('本人', style: TextStyle(color: Colors.blue, fontSize: 18)),
onPressed: () {
_controller.text = g_userInfo.username;
},
),
),
],
),
//SizedBox(height: 30),
SizedBox(height: 10),
//480*720
Text(null == imageSize ? '' : '宽高:${imageSize.width}x${imageSize.height}',
style: TextStyle(fontSize: 18)),
SizedBox(height: 5),
Container(
alignment: Alignment(0, 0),
width: ScreenUtil().setWidth(980),
height: ScreenUtil().setHeight(760),
decoration: BoxDecoration(
border: Border.all(color: Colors.orange, width: 1.0),
borderRadius: BorderRadius.circular(5),
),
child: _getImage(imagePath),
),
SizedBox(height: 25),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
getBtnSizeX(
width: 90,
text: "拍照",
onPressedFun: () {
//Navigator.pushNamed(context, '/faceReg_take_pictuer', arguments: 'FaceLogin');
_username = _controller.text;
Navigator.pushNamed(context, '/faceReg_take_pictuer',
arguments: 'FaceReg')
.then((_imagePath) {
_controller.text = _username;
imagePath = _imagePath as String;
if (imagePath.isNotEmpty) {
print('imagePath = $imagePath');
//imageSize = Size(480, 720);
getImageSize(imagePath);
//eventBus.fire(FaceRegUpdateEvent('人脸注册数据已更新'));
}
});
}),
getBtnSizeX(
width: 90,
text: "选择图片",
onPressedFun: () {
//Navigator.pushNamed(context, '/faceReg_take_pictuer', arguments: 'FaceLogin');
_getImageGallery();
}),
getBtnSizeX(
width: 90,
text: "人脸注册",
onPressedFun: (_controller.text.isEmpty && imagePath.isEmpty)
? null
: () {
//人脸注册username 用户名filePath 人脸图片路径
if (_controller.text.isNotEmpty && imagePath.isNotEmpty) {
print('等待人脸注册或更新确认');
Navigator.of(context)
.push(
PageRouteBuilder(
opaque: false,
pageBuilder: (context, animation, secondaryAnimation) =>
CustomDialogFaceReg(
title: '人脸注册或更新确认',
username: _username,
imagePath: imagePath,
imageSize: imageSize,
),
),
)
.then((ret) async {
print('value = $ret');
if (ret) {
print('用户已确认,开始处理人脸注册或更新!');
faceRegFun(
username: _username,
filePath: imagePath,
context: context);
} else {
print('用户取消了人脸注册或更新');
}
});
} else if (_controller.text.isEmpty) {
Fluttertoast.showToast(
msg: "用户名不能为空!",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
} else if (imagePath.isEmpty) {
Fluttertoast.showToast(
msg: "请选择用户人脸图片!",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
}),
],
),
// RaisedButton(
// child: Text('人脸登录'),
// onPressed: () {
// Navigator.pushNamed(context, '/faceReg_take_pictuer', arguments: 'FaceLogin');
// }),
SizedBox(height: 10),
],
),
),
],
)),
);
}
//从相册选取图片
Future _getImageGallery() async {
final imagePicker = ImagePicker();
_username = _controller.text;
//final pickedFile = await imagePicker.getImage(source: ImageSource.gallery, maxWidth: 400);
imagePicker.getImage(source: ImageSource.gallery, maxWidth: 480).then((pickedFile) {
if (pickedFile != null) {
print('pickedFile = ${pickedFile.path}');
imagePath = pickedFile.path;
getImageSize(imagePath);
} else {
print('No image selected.');
}
_controller.text = _username;
});
}
//定义一个组件显示图片
_getImage(String filePath) {
print('filePath = $filePath');
if (null == imageSize || filePath.isEmpty) {
return Text("注意:\n1、请输入“已注册”的用户名\n2、请选择包含“用户人脸”的图片\n3、两样都选好后再进行注册不然可能失败");
}
double _width = ScreenUtil().setWidth(980);
double _heigth = _width * (imageSize.height / imageSize.width);
final _image = Image.file(File(filePath));
// 预先获取图片信息
return SingleChildScrollView(
//滑动的方向 Axis.vertical为垂直方向滑动Axis.horizontal 为水平方向
scrollDirection: Axis.vertical,
//true 滑动到底部
reverse: false,
padding: EdgeInsets.all(0.0),
//滑动到底部回弹效果
physics: BouncingScrollPhysics(),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: _width,
height: _heigth,
// child: PinchZoomImage( //不好用
// //image: Image.network('https://i.imgur.com/tKg0XEb.jpg'),
// image: _image,
// zoomedBackgroundColor: Color.fromRGBO(240, 240, 240, 1.0),
// hideStatusBarWhileZooming: true,
// onZoomStart: () {
// print('Zoom started');
// },
// onZoomEnd: () {
// print('Zoom finished');
// },
// ),
//DragScaleContainer 插件只能放大,不能缩小到比原始尺寸小
child: DragScaleContainer(doubleTapStillScale: true, child: _image
// child: Image(
// image: NetworkImage(
// 'http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c086e06f06c.jpg'),
// ),
),
//child: _image,
//一个大坑:用 AssetImage(filePath) 方式,首次加载拍照返回的照片,始终报错,刷新后则能够正常加载。
// 用 Container 的 child 方式解决
// decoration: BoxDecoration(
// image: DecorationImage(image: AssetImage(filePath), fit: BoxFit.cover),
// ),
)
],
),
);
}
// 预先获取图片信息
Future getImageSize(String filePath) async {
Image image = Image.file(File.fromUri(Uri.parse(filePath)));
image.image
.resolve(new ImageConfiguration())
.addListener(new ImageStreamListener((ImageInfo info, bool _) {
imageSize = Size(
info.image.width.toDouble(),
info.image.height.toDouble(),
);
print('imageSize = $imageSize');
//必须延迟刷新否则启动App后第一次进行拍照返回会抛异常无法显示返回的照片
//启动App后第一次进行拍照返回在 AS Terminal 按 R 刷新可以显示图片。
//暂存,后续解决
try_setState();
// Future.delayed(const Duration(milliseconds: 3000), () {
// //try_setState();
//eventBus.fire(FaceRegUpdateEvent('人脸注册数据已更新')); //这样刷新有效
// });
}));
}
}