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 { //try_setState(); //避免异常报错 try_setState() { try { setState(() {}); } catch (e) { print('setState(() {})异常:${e}'); } } Future 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().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: [ //解决 Flutter ListView 子元素 无限宽度 的问题 Container( alignment: Alignment.topCenter, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ 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: [ 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('人脸注册数据已更新')); //这样刷新有效 // }); })); } }