TIF_E41201615/lib/components/camera/custom_camera.dart

251 lines
7.3 KiB
Dart

library camera_with_files;
import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'package:camera/camera.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:image_picker/image_picker.dart';
import "package:intl/intl.dart";
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
class CustomCameraWidget extends StatefulWidget {
final int? compressionQuality;
const CustomCameraWidget({Key? key, this.compressionQuality = 100}) : super(key: key);
@override
CustomCameraWidgetState createState() => CustomCameraWidgetState();
}
class CustomCameraWidgetState extends State<CustomCameraWidget> {
CameraController? controller;
late List<CameraDescription> cameras;
bool flashOn = false;
bool showPerformance = false;
@override
void initState() {
super.initState();
cameraLoad();
}
cameraLoad() async {
cameras = await availableCameras();
controller = CameraController(cameras[0], ResolutionPreset.max,
imageFormatGroup: Platform.isIOS ? ImageFormatGroup.bgra8888 : null);
controller!.initialize().then((_) {
if (!mounted) {
return;
}
_promptPermissionSetting().then((_) {
if (_) {}
setState(() {});
});
setState(() {});
});
}
Future<bool> _promptPermissionSetting() async {
if (kIsWeb) {
return true;
} else if (Platform.isIOS) {
PermissionStatus status = await Permission.storage.request();
PermissionStatus status2 = await Permission.photos.request();
PermissionStatus status3 = await Permission.mediaLibrary.request();
return status.isGranted && status2.isGranted && status3.isGranted;
} else if (Platform.isAndroid) {
PermissionStatus status = await Permission.storage.request();
return status.isGranted;
}
return false;
}
@override
void dispose() {
controller!.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (controller == null) {
return Container();
}
var camera = controller!.value;
final size = MediaQuery.of(context).size;
var scale = 0.0;
try {
scale = size.aspectRatio * camera.aspectRatio;
} catch (e) {
debugPrint(e.toString());
}
if (scale < 1) scale = 1 / scale;
if (!controller!.value.isInitialized) {
return Container();
}
return WillPopScope(
onWillPop: () {
return Future.value(true);
},
child: Scaffold(
body: Stack(
children: [
GestureDetector(
onVerticalDragStart: (e) {},
child: Transform.scale(
scale: scale,
child: Center(
child: CameraPreview(controller!),
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: MediaQuery.of(context).size.width,
height: 215,
color: Colors.transparent,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_galleryButton(),
_cameraButton(),
SizedBox(width: 25,)
],
),
),
),
SafeArea(
child: Align(
alignment: Alignment.topCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {
setState(() {
flashOn = !flashOn;
if (flashOn) {
controller!.setFlashMode(FlashMode.torch);
} else {
controller!.setFlashMode(FlashMode.off);
}
});
},
icon: const Icon(Icons.flash_off,
size: 30, color: Colors.white)),
IconButton(
onPressed: () {
compress(null);
},
icon: const Icon(
Icons.close_rounded,
color: Colors.white,
))
],
)),
),
],
),
),
);
}
Widget _galleryButton(){
return IconButton(
onPressed: () async {
final ImagePicker picker0 =
ImagePicker();
final XFile? image =
await picker0.pickImage(
source: ImageSource.gallery);
if (image == null) {
return;
}
File file = File(image.path);
compress(file);
},
icon: const Icon(Icons.photo_library,
size: 30, color: Colors.white),
);
}
Widget _cameraButton(){
return GestureDetector(
onTap: () async {
XFile file2 = await controller!.takePicture();
File file = File(file2.path);
compress(file);
},
child: Container(
width: 75,
height: 75,
decoration: BoxDecoration(
// color: Colors.white,
borderRadius: const BorderRadius.all(
Radius.circular(
50)
),
border: Border.all(
color: Colors.white, width: 3)),
),
);
}
void onSettingCallback() {
setState(() {
showPerformance = !showPerformance;
});
}
void compress(File? file) async {
if (file == null) {
Navigator.of(context).pop(null);
}
File? files2;
Uint8List? blobBytes = await compressFile(file!);
var dir = await getTemporaryDirectory();
String trimmed = dir.absolute.path;
String dateTimeString = DateTime.now().millisecondsSinceEpoch.toString();
String pathString = "$trimmed/$dateTimeString.jpg";
File fileNew = File(pathString);
fileNew.writeAsBytesSync(List.from(blobBytes!));
files2 = fileNew;
if (context.mounted) {
Navigator.of(context).pop(files2);
}
}
String dateTimeToString(DateTime dateTime, String pattern) {
final format = DateFormat(pattern);
return format.format(dateTime);
}
Future<Uint8List?> compressFile(File file) async {
var decodedImage = await decodeImageFromList(file.readAsBytesSync());
print("Image compress Before: " +
getFileSizeString(bytes: file.lengthSync()));
var result = await FlutterImageCompress.compressWithFile(file.absolute.path,
minHeight: decodedImage.height,
minWidth: decodedImage.width,
quality: widget.compressionQuality!);
print("Image compress After: " +
getFileSizeString(bytes: result!.lengthInBytes));
return result;
}
String getFileSizeString({required int bytes, int decimals = 0}) {
const suffixes = ["b", "kb", "mb", "gb", "tb"];
var i = (log(bytes) / log(1024)).floor();
return ((bytes / pow(1024, i)).toStringAsFixed(decimals)) + suffixes[i];
}
}