FarisaRahmaSari_E31222327/BBS/lib/view/home/camera_page.dart

255 lines
8.4 KiB
Dart

import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart';
//import 'package:lottie/lottie.dart';
import 'package:qyuota/util/google_ml_kit.dart';
import 'package:qyuota/view/home/clockin_view.dart';
class CameraAbsenPage extends StatefulWidget {
const CameraAbsenPage({super.key});
@override
State<CameraAbsenPage> createState() => _State();
}
class _State extends State<CameraAbsenPage> with TickerProviderStateMixin {
FaceDetector faceDetector = GoogleMlKit.vision.faceDetector(
FaceDetectorOptions(
enableContours: true,
enableClassification: true,
enableTracking: true,
enableLandmarks: true,
),
);
List<CameraDescription>? cameras;
CameraController? controller;
XFile? image;
bool isBusy = false;
@override
void initState() {
super.initState();
loadCamera();
}
loadCamera() async {
cameras = await availableCameras();
if (cameras != null) {
controller = CameraController(cameras![1], ResolutionPreset.max);
controller!.initialize().then((_) {
if (!mounted) {
return;
}
setState(() {});
});
} else {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Row(
children: [
Icon(
Icons.camera_enhance_outlined,
color: Colors.white,
),
SizedBox(width: 10),
Text("Ups, kamera tidak ditemukan!",
style: TextStyle(color: Colors.white))
],
),
backgroundColor: Colors.redAccent,
shape: StadiumBorder(),
behavior: SnackBarBehavior.floating,
));
}
}
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
showLoaderDialog(BuildContext context) {
AlertDialog alert = AlertDialog(
content: Row(
children: [
const CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
Color(0xFF0077B6),
)),
Container(
margin: const EdgeInsets.only(left: 20),
child: const Text("Sedang memeriksa data...")),
],
),
);
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: const Color(0xFF0077B6),
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios, color: Colors.white),
onPressed: () => Navigator.of(context).pop(),
),
title: const Text(
"Foto Selfie",
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white),
),
),
body: Stack(
children: [
SizedBox(
height: size.height,
width: size.width,
child: controller == null
? const Center(
child: Text("Ups, kamera bermasalah!",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold)))
: !controller!.value.isInitialized
? const Center(child: CircularProgressIndicator())
: CameraPreview(controller!)),
// Padding(
// padding: const EdgeInsets.only(top: 40),
// child: Lottie.asset(
// "assets/raw/face_id_ring.json",
// fit: BoxFit.cover,
// ),
// ),
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: size.width,
height: 200,
padding: const EdgeInsets.symmetric(horizontal: 30),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(28),
topRight: Radius.circular(28),
),
),
child: Column(
children: [
const SizedBox(
height: 20,
),
const Text(
"Pastikan Anda berada di tempat terang, agar wajah terlihat jelas.",
style: TextStyle(fontSize: 16, color: Colors.black),
),
Padding(
padding: const EdgeInsets.only(top: 40),
child: ClipOval(
child: Material(
color: const Color(0xFF0077B6),
child: InkWell(
splashColor: const Color(0xFF0077B6),
onTap: () async {
try {
if (controller != null) {
if (controller!.value.isInitialized) {
controller!.setFlashMode(FlashMode.off);
image = await controller!.takePicture();
final inputImage =
InputImage.fromFilePath(image!.path);
showLoaderDialog(context);
processImage(inputImage);
}
}
} catch (e) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(
content: Row(
children: [
const Icon(
Icons.error_outline,
color: Colors.white,
),
const SizedBox(width: 10),
Text(
"Ups, $e",
style:
const TextStyle(color: Colors.white),
)
],
),
backgroundColor: Colors.redAccent,
shape: const StadiumBorder(),
behavior: SnackBarBehavior.floating,
));
}
},
child: const SizedBox(
width: 56,
height: 56,
child: Icon(
Icons.camera_enhance_outlined,
color: Colors.white,
),
),
),
),
),
),
],
),
),
),
],
),
);
}
Future<void> processImage(InputImage inputImage) async {
if (isBusy) return;
isBusy = true;
final faces = await faceDetector.processImage(inputImage);
isBusy = false;
if (mounted) {
setState(() {
Navigator.of(context).pop(true);
if (faces.isNotEmpty) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => ClockinView(image: image),
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Row(
children: [
Icon(
Icons.face_retouching_natural_outlined,
color: Colors.white,
),
SizedBox(width: 10),
Expanded(
child: Text(
"Ups, pastikan wajah Anda terlihat jelas dengan cahaya yang cukup!",
style: TextStyle(color: Colors.white),
),
)
],
),
backgroundColor: Colors.redAccent,
shape: StadiumBorder(),
behavior: SnackBarBehavior.floating,
));
}
});
}
}
}