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.
335 lines
10 KiB
335 lines
10 KiB
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),
|
|
);
|
|
}),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|