last63

CameraPage

Mar 10th, 2025
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.21 KB | None | 0 0
  1. import 'dart:io';
  2.  
  3. import 'package:firebase_test/ui/ui/attedance/attendance/attendance_page.dart';
  4. import 'package:firebase_test/utils/facedection/google_ml_kit.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart';
  7. import 'package:image_picker/image_picker.dart';
  8. import 'package:lottie/lottie.dart';
  9. import 'package:geolocator/geolocator.dart';
  10. import 'package:camera/camera.dart';
  11.  
  12. class CameraPage extends StatefulWidget {
  13. const CameraPage({super.key});
  14.  
  15. @override
  16. State<CameraPage> createState() => _CameraPageState();
  17. }
  18.  
  19. class _CameraPageState extends State<CameraPage> with TickerProviderStateMixin {
  20. //set face detection
  21. FaceDetector faceDetector = GoogleMLKit.vision.faceDetector(FaceDetectorOptions(
  22. enableContours: true,
  23. enableClassification: true,
  24. enableTracking: true,
  25. enableLandmarks: true
  26. ));
  27.  
  28. List<CameraDescription>? cameras;
  29. CameraController? controller;
  30. XFile? image;
  31. bool isBusy = false;
  32.  
  33. @override
  34. void initState() {
  35. loadCamera();
  36. super.initState();
  37. }
  38.  
  39. loadCamera() async {
  40. cameras = await availableCameras();
  41. if (cameras != null) {
  42. controller = CameraController(cameras![1], ResolutionPreset.max);
  43. controller!.initialize().then((_) {
  44. if (!mounted) {
  45. return;
  46. }
  47. setState(() {});
  48. });
  49. } else {
  50. ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
  51. content: Row(
  52. children: [
  53. Icon(
  54. Icons.camera_enhance_outlined,
  55. color: Colors.white,
  56. ),
  57. SizedBox(width: 10),
  58. Text("Ups, camera not found!", style: TextStyle(color: Colors.white))
  59. ],
  60. ),
  61. backgroundColor: Colors.blueGrey,
  62. shape: StadiumBorder(),
  63. behavior: SnackBarBehavior.floating,
  64. ));
  65. }
  66. }
  67.  
  68. @override
  69. Widget build(BuildContext context) {
  70. Size size = MediaQuery.of(context).size;
  71.  
  72. //set loading
  73. showLoaderDialog(BuildContext context) {
  74. AlertDialog alert = AlertDialog(
  75. content: Row(
  76. children: [
  77. const CircularProgressIndicator(valueColor:
  78. AlwaysStoppedAnimation<Color>(Colors.blueAccent)),
  79. Container(
  80. margin: const EdgeInsets.only(left: 20),
  81. child: const Text("Checking the data...")
  82. ),
  83. ],
  84. ),
  85. );
  86. showDialog(
  87. barrierDismissible: false,
  88. context: context,
  89. builder: (BuildContext context) {
  90. return alert;
  91. },
  92. );
  93. }
  94. return Scaffold(
  95. appBar: AppBar(
  96. elevation: 0,
  97. backgroundColor: Colors.blueAccent,
  98. leading: IconButton(
  99. icon: const Icon(Icons.arrow_back_ios, color: Colors.white),
  100. onPressed: () => Navigator.of(context).pop(),
  101. ),
  102. title: const Text(
  103. "Capture a selfie image",
  104. style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white),
  105. ),
  106. ),
  107. body: Stack(
  108. children: [
  109. SizedBox(
  110. height: size.height,
  111. width: size.width,
  112. child: controller == null
  113. ? const Center(child: Text("Ups, camera error!",
  114. style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)))
  115. : !controller!.value.isInitialized
  116. ? const Center(child: CircularProgressIndicator())
  117. : CameraPreview(controller!)
  118. ),
  119. Padding(
  120. padding: const EdgeInsets.only(top: 40),
  121. child: Lottie.asset(
  122. "assets/raw/face_id_ring.json",
  123. fit: BoxFit.cover,
  124. ),
  125. ),
  126. Align(
  127. alignment: Alignment.bottomCenter,
  128. child: Container(
  129. width: size.width,
  130. height: 200,
  131. padding: const EdgeInsets.symmetric(horizontal: 30),
  132. decoration: const BoxDecoration(
  133. color: Colors.white,
  134. borderRadius: BorderRadius.only(
  135. topLeft: Radius.circular(28),
  136. topRight: Radius.circular(28),
  137. ),
  138. ),
  139. child: Column(
  140. children: [
  141. const SizedBox(
  142. height: 20,
  143. ),
  144. const Text(
  145. "Make sure you're in a well-lit area so your face is clearly visible.",
  146. style: TextStyle(fontSize: 16, color: Colors.black),
  147. ),
  148. Padding(
  149. padding: const EdgeInsets.only(top: 40),
  150. child: ClipOval(
  151. child: Material(
  152. color: Colors.blueAccent, // Button color
  153. child: InkWell(
  154. splashColor: Colors.blue, // Splash color
  155. onTap: () async {
  156. final hasPermission = await handleLocationPermission();
  157. try {
  158. if (controller != null) {
  159. if (controller!.value.isInitialized) {
  160. controller!.setFlashMode(FlashMode.off);
  161. image = await controller!.takePicture();
  162. setState(() {
  163. if (hasPermission) {
  164. showLoaderDialog(context);
  165. final inputImage = InputImage.fromFilePath(image!.path);
  166. Platform.isAndroid ? processImage(inputImage) : Navigator.push(context,
  167. MaterialPageRoute(builder: (context) => AttendancePage(image: image)));
  168. }
  169. else {
  170. ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
  171. content: Row(
  172. children: [
  173. Icon(
  174. Icons.location_on_outlined,
  175. color: Colors.white,
  176. ),
  177. SizedBox(width: 10),
  178. Text("Please allow the permission first!",
  179. style: TextStyle(color: Colors.white),
  180. )
  181. ],
  182. ),
  183. backgroundColor: Colors.blueGrey,
  184. shape: StadiumBorder(),
  185. behavior: SnackBarBehavior.floating,
  186. ));
  187. }
  188. });
  189. }
  190. }
  191. } catch (e) {
  192. ScaffoldMessenger.of(context).showSnackBar(SnackBar(
  193. content: Row(
  194. children: [
  195. const Icon(
  196. Icons.error_outline,
  197. color: Colors.white,
  198. ),
  199. const SizedBox(width: 10),
  200. Text("Ups, $e",
  201. style: const TextStyle(color: Colors.white),
  202. )
  203. ],
  204. ),
  205. backgroundColor: Colors.blueGrey,
  206. shape: const StadiumBorder(),
  207. behavior: SnackBarBehavior.floating,
  208. ));
  209. }
  210. },
  211. child: const SizedBox(
  212. width: 56,
  213. height: 56,
  214. child: Icon(
  215. Icons.camera_enhance_outlined,
  216. color: Colors.white,
  217. ),
  218. ),
  219. ),
  220. ),
  221. ),
  222. ),
  223. ],
  224. ),
  225. ),
  226. ),
  227. ],
  228. ),
  229. );
  230. }
  231.  
  232. //permission location
  233. Future<bool> handleLocationPermission() async {
  234. bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
  235. if (!serviceEnabled) {
  236. ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
  237. content: Row(
  238. children: [
  239. Icon(
  240. Icons.location_off,
  241. color: Colors.white,
  242. ),
  243. SizedBox(width: 10),
  244. Text("Location services are disabled. Please enable the services.",
  245. style: TextStyle(color: Colors.white),
  246. )
  247. ],
  248. ),
  249. backgroundColor: Colors.blueGrey,
  250. shape: StadiumBorder(),
  251. behavior: SnackBarBehavior.floating,
  252. ));
  253. return false;
  254. }
  255.  
  256. LocationPermission permission = await Geolocator.checkPermission();
  257. if (permission == LocationPermission.denied) {
  258. permission = await Geolocator.requestPermission();
  259. if (permission == LocationPermission.denied) {
  260. ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
  261. content: Row(
  262. children: [
  263. Icon(
  264. Icons.location_off,
  265. color: Colors.white,
  266. ),
  267. SizedBox(width: 10),
  268. Text("Location permission denied.",
  269. style: TextStyle(color: Colors.white),
  270. )
  271. ],
  272. ),
  273. backgroundColor: Colors.blueGrey,
  274. shape: StadiumBorder(),
  275. behavior: SnackBarBehavior.floating,
  276. ));
  277. return false;
  278. }
  279. }
  280.  
  281. if (permission == LocationPermission.deniedForever) {
  282. ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
  283. content: Row(
  284. children: [
  285. Icon(
  286. Icons.location_off,
  287. color: Colors.white,
  288. ),
  289. SizedBox(width: 10),
  290. Text("Location permission denied forever, we cannot access.",
  291. style: TextStyle(color: Colors.white),
  292. )
  293. ],
  294. ),
  295. backgroundColor: Colors.blueGrey,
  296. shape: StadiumBorder(),
  297. behavior: SnackBarBehavior.floating,
  298. ));
  299. return false;
  300. }
  301. return true;
  302. }
  303.  
  304. //face detection
  305. Future<void> processImage(InputImage inputImage) async {
  306. if (isBusy) return;
  307. isBusy = true;
  308. final faces = await faceDetector.processImage(inputImage);
  309. isBusy = false;
  310.  
  311. if (mounted) {
  312. setState(() {
  313. Navigator.of(context).pop(true);
  314. if (faces.length > 0) {
  315. Navigator.pushReplacement(context,
  316. MaterialPageRoute(builder: (context) => AttendancePage(image: image)));
  317. } else {
  318. ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
  319. content: Row(
  320. children: [
  321. Icon(
  322. Icons.face_retouching_natural_outlined,
  323. color: Colors.white,
  324. ),
  325. SizedBox(width: 10),
  326. Expanded(
  327. child: Text(
  328. "Ups, make sure that you're face is clearly visible!",
  329. style: TextStyle(color: Colors.white),
  330. ),
  331. )
  332. ],
  333. ),
  334. backgroundColor: Colors.blueGrey,
  335. shape: StadiumBorder(),
  336. behavior: SnackBarBehavior.floating,
  337. ));
  338. }
  339. });
  340. }
  341. }
  342.  
  343. }
  344.  
Advertisement
Add Comment
Please, Sign In to add comment