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

336 lines
10 KiB

3 years ago
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<CameraDescription> connectedCameras;
TakePicture({Key key, this.connectedCameras}) : super(key: key);
@override
_TakePictureState createState() => _TakePictureState();
}
class _TakePictureState extends State<TakePicture>
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<void> _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),
);
}),
),
),
);
}
}