import 'package:flutter/material.dart'; import 'package:camera/camera.dart'; import 'package:teso/util/consts.dart'; import 'package:image_picker/image_picker.dart'; import 'package:page_transition/page_transition.dart'; import 'PictureReview.dart'; import 'dart:io'; // ignore: must_be_immutable class TakePicture extends StatefulWidget { List connectedCameras; TakePicture({Key key, this.connectedCameras}) : super(key: key); @override _TakePictureState createState() => _TakePictureState(); } class _TakePictureState extends State with TickerProviderStateMixin { CameraController _controller; int selectedCamera = 0; bool flash = false; bool frontFlash = false; double _currentScale = 1.0; double _baseScale = 1.0; double _minAvailableZoom; double _maxAvailableZoom; int _pointers = 0; final picker = ImagePicker(); setCamera(int camera) async { _controller = CameraController(widget.connectedCameras[camera], ResolutionPreset.max); _controller.initialize().then((_) { _controller.setFocusMode(FocusMode.auto); if (!mounted) { return; } setState(() {}); }); } void onViewFinderTap(TapDownDetails details, BoxConstraints constraints) { final offset = Offset( details.localPosition.dx / constraints.maxWidth, details.localPosition.dy / constraints.maxHeight, ); _controller.setExposurePoint(offset); _controller.setFocusPoint(offset); } @override void initState() { if (widget.connectedCameras == null || widget.connectedCameras.length == 0) { availableCameras().then((value) { widget.connectedCameras = value; }); setCamera(0); } else { setCamera(0); } super.initState(); } sayCheese() async { try { final image = await _controller.takePicture(); bool result = false; result = await Navigator.push( context, PageTransition( type: PageTransitionType.leftToRight, child: PictureReview( image: image.path, ), )); if (result) Navigator.pop(context, image); } catch (e) { print(e); } } void _handleScaleStart(ScaleStartDetails details) { _baseScale = _currentScale; } Future _handleScaleUpdate(ScaleUpdateDetails details) async { // When there are not exactly two fingers on screen don't scale if (_pointers != 2) { return; } _currentScale = (_baseScale * details.scale) .clamp(_minAvailableZoom, _maxAvailableZoom); await _controller.setZoomLevel(_currentScale); } @override void dispose() { _controller?.dispose(); super.dispose(); } @override Widget build(BuildContext context) { if (_controller == null || !_controller.value.isInitialized) { return Container(); } else { return Scaffold( body: Stack( children: [ cameraWidget(context), Visibility( visible: frontFlash, child: Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, decoration: BoxDecoration( color: Colors.white.withOpacity(0.4), ), ), ), Align( alignment: Alignment.topRight, child: Container( margin: EdgeInsets.symmetric( horizontal: MediaQuery.of(context).size.width * 0.06, vertical: MediaQuery.of(context).size.width * 0.11, ), child: InkWell( onTap: () { if (flash && _controller.description.lensDirection == CameraLensDirection.back) { _controller.setFlashMode(FlashMode.off); setState(() { flash = false; }); } else { setState(() { flash = false; frontFlash = false; }); } selectedCamera++; if (selectedCamera < widget.connectedCameras.length) { setCamera(selectedCamera); } else { selectedCamera = 0; setCamera(selectedCamera); } }, child: Icon( Icons.camera_alt, color: Colors.white, size: 40, ), ), ), ), Align( alignment: Alignment.topRight, child: Container( margin: EdgeInsets.symmetric( horizontal: MediaQuery.of(context).size.width * 0.07, vertical: MediaQuery.of(context).size.width * 0.25, ), child: InkWell( onTap: () { try { if (!flash && _controller.description.lensDirection == CameraLensDirection.back) { _controller.setFlashMode(FlashMode.torch); setState(() { flash = true; }); } else if (!flash && _controller.description.lensDirection == CameraLensDirection.front) { setState(() { flash = true; frontFlash = true; }); } else if (flash && _controller.description.lensDirection == CameraLensDirection.back) { _controller.setFlashMode(FlashMode.off); setState(() { flash = false; }); } else { setState(() { flash = false; frontFlash = false; }); } } catch (e) {} }, child: Icon( flash ? Icons.flash_on : Icons.flash_off, color: flash ? tesoGold : Colors.white, size: 30, ), ), ), ), Align( alignment: Alignment.topLeft, child: InkWell( onTap: () { Navigator.pop(context); }, child: Container( margin: EdgeInsets.symmetric( horizontal: MediaQuery.of(context).size.width * 0.08, vertical: MediaQuery.of(context).size.width * 0.11, ), height: 35, width: 35, decoration: BoxDecoration( color: Color.fromRGBO(0, 0, 0, 0.4), shape: BoxShape.circle), child: Icon( Icons.arrow_back_ios, color: Colors.white, ), ), ), ), Align( alignment: Alignment.bottomCenter, child: InkWell( onTap: sayCheese, child: Container( margin: EdgeInsets.symmetric( vertical: MediaQuery.of(context).size.width * 0.11, ), height: 70, width: 70, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: Colors.white, width: 3, ), ), child: Icon( Icons.camera_alt, color: Colors.white, size: 40, ), ), ), ), Align( alignment: Alignment.bottomLeft, child: InkWell( onTap: imgFromGallery, child: Container( margin: EdgeInsets.symmetric( horizontal: MediaQuery.of(context).size.width * 0.05, vertical: MediaQuery.of(context).size.width * 0.11, ), height: 70, width: 70, child: Icon( Icons.photo, color: Colors.white, size: 27, ), ), ), ), ], ), ); } } imgFromGallery() async { final pickedFile = await picker.pickImage(source: ImageSource.gallery, imageQuality: 70); if (pickedFile != null) { final image = File(pickedFile.path); bool result; result = await Navigator.push( context, PageTransition( type: PageTransitionType.leftToRight, child: PictureReview( image: image.path, ), )); if (result) Navigator.pop(context, image); } else { print('No image selected.'); } return; } Widget cameraWidget(context) { var camera = _controller.value; final size = MediaQuery.of(context).size; var scale = size.aspectRatio * camera.aspectRatio; if (scale < 1) scale = 1 / scale; return Transform.scale( scale: scale, child: Center( child: CameraPreview( _controller, child: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { return GestureDetector( behavior: HitTestBehavior.opaque, onScaleStart: _handleScaleStart, onScaleUpdate: _handleScaleUpdate, onTapDown: (details) => onViewFinderTap(details, constraints), ); }), ), ), ); } }