diff --git a/assets/images/cardid.jpg b/assets/images/cardid.jpg new file mode 100644 index 0000000..608f2d1 Binary files /dev/null and b/assets/images/cardid.jpg differ diff --git a/lib/controller/functions/camer_controller.dart b/lib/controller/functions/camer_controller.dart new file mode 100644 index 0000000..b8490a8 --- /dev/null +++ b/lib/controller/functions/camer_controller.dart @@ -0,0 +1,173 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:camera/camera.dart'; +import 'package:flutter_tesseract_ocr/flutter_tesseract_ocr.dart'; +import 'package:get/get.dart'; +import 'package:google_mlkit_text_recognition/google_mlkit_text_recognition.dart'; +import 'package:ride/constant/box_name.dart'; +import 'package:ride/views/widgets/elevated_btn.dart'; +import 'package:path_provider/path_provider.dart' as path_provider; +import 'package:path/path.dart' as path; + +import '../../main.dart'; + +class CameraClassController extends GetxController { + late CameraController cameraController; + late List cameras; + bool isCameraInitialized = false; + final TextRecognizer _textRecognizer = TextRecognizer(); + String? scannedText; + bool isloading = false; + + @override + void onInit() { + super.onInit(); + initializeCamera(); + } + + Future initializeCamera() async { + try { + cameras = await availableCameras(); + update(); + cameraController = CameraController( + cameras[0], + ResolutionPreset.max, + enableAudio: false, + ); + await cameraController.initialize(); + isCameraInitialized = true; + update(); + } catch (e) { + if (e is CameraException) { + switch (e.code) { + case 'CameraAccessDenied': + Get.defaultDialog( + title: 'Camera Access Denied.'.tr, + middleText: '', + confirm: + MyElevatedButton(title: 'Open Settings', onPressed: () {}), + ); + break; + default: + // Handle other errors here. + break; + } + } + } + } + + Future takePictureAndMLGoogleScan() async { + try { + // Construct the path for the image file + final directory = await path_provider.getTemporaryDirectory(); + final imagePath = + path.join(directory.path, '${box.read(BoxName.driverID)}.png'); + + // Capture the image and save it to the specified path + final XFile capturedImage = await cameraController.takePicture(); + + // Move the captured image to the desired path + await capturedImage.saveTo(imagePath); + + // Recognize the text in the image + final InputImage inputImage = + InputImage.fromFile(File(capturedImage.path)); + final RecognizedText recognizedText = + await _textRecognizer.processImage(inputImage); + scannedText = recognizedText.text; + + // Extract the scanned text line by line + final List> lines = []; + for (var i = 0; i < recognizedText.blocks.length; i++) { + lines.add({ + 'line_number': i, + 'text': recognizedText.blocks[i].text, + }); + } + + // Convert the list of lines to a JSON string + final String jsonOutput = jsonEncode(lines); + + update(); + + // Print the JSON output + print(jsonOutput); + + // Get.back(); + } catch (e) { + print('Error capturing image: $e'); + } + } + + String getTextAsJSON(String text) { + final lines = text.split('\n'); + final jsonList = lines.map((line) { + return { + 'line_text': line, + 'num_words': line.trim().split(' ').length, + }; + }).toList(); + + final json = { + 'lines': jsonList, + 'num_lines': lines.length, + }; + + return jsonEncode(json); + } + + List getTextBlocks(String text) { + return text.split('\n'); + } + + Future takePictureAndTesseractScan() async { + try { + // Construct the path for the image file + final directory = await path_provider.getTemporaryDirectory(); + final imagePath = + path.join(directory.path, '${box.read(BoxName.driverID)}.png'); + + // Capture the image and save it to the specified path + final XFile capturedImage = await cameraController.takePicture(); + + // Move the captured image to the desired path + await capturedImage.saveTo(imagePath); + + // Recognize the text in the image + final languages = [ + 'eng', + 'ara' + ]; // Specify the languages you want to use for text extraction + + final text = await FlutterTesseractOcr.extractText(imagePath, + language: languages.join('+'), // Combine multiple languages with '+' + args: { + "psm": "4", + "preserve_interword_spaces": "1", + // "rectangle": const Rect.fromLTWH(100, 100, 200, 200), + } // Additional options if needed + ); + isloading = false; + final jsonText = getTextAsJSON(text); + final textBlocks = getTextBlocks(text); + update(); + scannedText = + textBlocks.toString(); // Convert the extracted text to JSON. + +// Print the JSON to the console. + print(jsonText); + update(); + // print(text); + } catch (e) { + print('Error during text extraction: $e'); + scannedText = ''; + } + } + + @override + void onClose() { + cameraController.dispose(); + super.onClose(); + } +} diff --git a/lib/controller/functions/ocr_controller.dart b/lib/controller/functions/ocr_controller.dart index 67aca39..c24d212 100644 --- a/lib/controller/functions/ocr_controller.dart +++ b/lib/controller/functions/ocr_controller.dart @@ -1,6 +1,5 @@ import 'dart:convert'; import 'dart:io'; -import 'dart:ui'; import 'package:flutter_tesseract_ocr/flutter_tesseract_ocr.dart'; import 'package:get/get.dart'; diff --git a/lib/controller/payment/payment_controller.dart b/lib/controller/payment/payment_controller.dart index 9dacb20..2ef2ed3 100644 --- a/lib/controller/payment/payment_controller.dart +++ b/lib/controller/payment/payment_controller.dart @@ -97,9 +97,19 @@ class PaymentController extends GetxController { Future initializePaymentSheet(String clientSecret) async { await Stripe.instance.initPaymentSheet( paymentSheetParameters: SetupPaymentSheetParameters( - paymentIntentClientSecret: clientSecret, - merchantDisplayName: 'Sefer', - ), + paymentIntentClientSecret: clientSecret, + merchantDisplayName: 'Sefer', + billingDetails: BillingDetails( + name: box.read(BoxName.nameDriver).toString(), + email: box.read(BoxName.emailDriver).toString(), + phone: box.read(BoxName.phoneDriver).toString(), + ), + billingDetailsCollectionConfiguration: + const BillingDetailsCollectionConfiguration( + name: CollectionMode.always, + phone: CollectionMode.always, + email: CollectionMode.always, + )), ); } diff --git a/lib/main.dart b/lib/main.dart index 2b85b4d..83a11d8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:camera/camera.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; @@ -30,6 +31,7 @@ Future backgroundMessageHandler(RemoteMessage message) async { if (message.notification!.title == 'Sefer') {} } +// late List cameras; void main() async { WidgetsFlutterBinding.ensureInitialized(); await GetStorage.init(); @@ -46,10 +48,11 @@ void main() async { List initializationTasks = [ FirebaseMessagesController().getNotificationSettings(), FirebaseMessagesController().getToken(), + // availableCameras(), // FirebaseMessagesController().getTokens(), // Add more initialization tasks here ]; - + // cameras = await availableCameras(); await Future.wait(initializationTasks); } diff --git a/lib/views/home/Captin/camer_widget.dart b/lib/views/home/Captin/camer_widget.dart new file mode 100644 index 0000000..1d15cf7 --- /dev/null +++ b/lib/views/home/Captin/camer_widget.dart @@ -0,0 +1,182 @@ +import 'package:camera/camera.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:ride/constant/colors.dart'; +import 'package:ride/constant/style.dart'; +import 'package:ride/controller/functions/camer_controller.dart'; +import 'package:ride/views/widgets/elevated_btn.dart'; + +class CameraWidgetCardId extends StatelessWidget { + final CameraClassController cameraClassController = + Get.put(CameraClassController()); + + CameraWidgetCardId({super.key}); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), + child: GetBuilder( + builder: (cameraClassController) => cameraClassController + .isCameraInitialized + ? Stack( + children: [ + Container( + decoration: AppStyle.boxDecoration, + height: Get.height * .3, + width: Get.width, + child: + // Image.asset( + // 'assets/images/cardid.jpg', + // fit: BoxFit.cover, + // ) + CameraPreview( + cameraClassController.cameraController, + // child: IconButton( + // onPressed: () { + // cameraClassController.takePicture(); + // }, + // icon: const Icon(Icons.camera), + // ), + ), + ), + Positioned( + top: 50, + child: Container( + width: 230, + height: 25, + decoration: BoxDecoration( + // color: AppColor.blueColor, + border: Border.all( + color: AppColor.yellowColor, width: 2), + ), + ), + ), + Positioned( + top: 38, + right: 5, + child: Container( + width: 230, + height: 25, + decoration: BoxDecoration( + // color: AppColor.blueColor, + border: + Border.all(color: AppColor.blueColor, width: 2), + ), + ), + ), + Positioned( + top: 130, + right: 5, + child: Container( + width: 140, + height: 20, + decoration: BoxDecoration( + // color: AppColor.blueColor, + border: + Border.all(color: AppColor.blueColor, width: 2), + ), + ), + ), + Positioned( + top: 148, + right: 5, + child: Container( + width: 140, + height: 15, + decoration: BoxDecoration( + // color: AppColor.blueColor, + border: + Border.all(color: AppColor.blueColor, width: 2), + ), + ), + ), + Positioned( + top: 165, + right: 5, + child: Container( + width: 140, + height: 15, + decoration: BoxDecoration( + // color: AppColor.blueColor, + border: + Border.all(color: AppColor.blueColor, width: 2), + ), + ), + ), + Positioned( + top: 182, + right: 5, + child: Container( + width: 140, + height: 15, + decoration: BoxDecoration( + // color: AppColor.blueColor, + border: + Border.all(color: AppColor.blueColor, width: 2), + ), + ), + ), + Positioned( + top: 198, + right: 5, + child: Container( + width: 140, + height: 15, + decoration: BoxDecoration( + // color: AppColor.blueColor, + border: + Border.all(color: AppColor.blueColor, width: 2), + ), + ), + ), + Positioned( + top: 80, + left: 35, + child: Container( + width: 120, + height: 110, + decoration: BoxDecoration( + // color: AppColor.blueColor, + border: + Border.all(color: AppColor.blueColor, width: 2), + ), + ), + ), + ], + ) + : Container( + decoration: AppStyle.boxDecoration, + height: Get.height * .3, + width: Get.width, + child: Center( + child: Text( + 'Camera not initilaized yet', + style: AppStyle.title, + ), + ), + ), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + MyElevatedButton( + title: 'Scan ID MklGoogle'.tr, + onPressed: () => + cameraClassController.takePictureAndMLGoogleScan()), + MyElevatedButton( + title: 'Scan ID Tesseract'.tr, + onPressed: () => + cameraClassController.takePictureAndTesseractScan()), + ], + ), + GetBuilder( + builder: (cameraClassController) => Expanded( + child: Text(cameraClassController.scannedText.toString()))) + ], + ); + } +} diff --git a/lib/views/home/Captin/home_captin.dart b/lib/views/home/Captin/home_captin.dart index 4ec2f98..98f143e 100644 --- a/lib/views/home/Captin/home_captin.dart +++ b/lib/views/home/Captin/home_captin.dart @@ -1,3 +1,4 @@ +import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:ride/constant/colors.dart'; @@ -8,6 +9,7 @@ import 'package:ride/controller/home/captin/order_request_controller.dart'; import 'package:ride/controller/payment/payment_controller.dart'; import 'package:ride/main.dart'; import 'package:ride/views/Rate/ride_calculate_driver.dart'; +import 'package:ride/views/home/Captin/camer_widget.dart'; import 'package:ride/views/home/Captin/text_scanner.dart'; import 'package:ride/views/widgets/circle_container.dart'; import 'package:ride/views/widgets/elevated_btn.dart'; @@ -193,6 +195,17 @@ class HomeCaptain extends StatelessWidget { "Text FlutterMLGoogle", ), ), + TextButton( + onPressed: () { + Get.to(() => Scaffold( + appBar: AppBar(), + body: CameraWidgetCardId(), + )); + }, + child: const Text( + "Text IdCamera", + ), + ), TextButton( onPressed: () { PaymentController().makePayment( @@ -213,3 +226,36 @@ class HomeCaptain extends StatelessWidget { ); } } + +// class CameraContainer extends StatelessWidget { +// TextMLGoogleRecognizerController controller = +// Get.put(TextMLGoogleRecognizerController()); + +// CameraContainer({super.key}); +// @override +// Widget build(BuildContext context) { +// return Stack( +// children: [ +// // The camera preview +// SizedBox( +// height: Get.height * 0.3, +// width: Get.width * 0.9, +// child: CameraPreview(controller.imagePicker as CameraController), +// ), + +// // The lines on the side of the name and national number +// const Positioned( +// bottom: 0, +// left: 0, +// right: 0, +// child: Column( +// children: [ +// Text('Name'), +// Text('National Number'), +// ], +// ), +// ), +// ], +// ); +// } +// } diff --git a/pubspec.lock b/pubspec.lock index 8aa943a..47384bd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -49,6 +49,46 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + camera: + dependency: "direct main" + description: + name: camera + sha256: "1f9010f0689774380fbcd7d6b7820a5157e8e97685fa66d619e1d1f58b3fdf93" + url: "https://pub.dev" + source: hosted + version: "0.10.5+5" + camera_android: + dependency: transitive + description: + name: camera_android + sha256: "58463140f1b39591b8e2155861b436abad4ceb48160058be8374164ff0309ef3" + url: "https://pub.dev" + source: hosted + version: "0.10.8+13" + camera_avfoundation: + dependency: transitive + description: + name: camera_avfoundation + sha256: "9495e633cda700717bbe299b0979e6c4a08cee45f298945973dc9cf3e4c1cba5" + url: "https://pub.dev" + source: hosted + version: "0.9.13+6" + camera_platform_interface: + dependency: transitive + description: + name: camera_platform_interface + sha256: "86fd4fc597c6e455265ddb5884feb352d0171ad14b9cdf3aba30da59b25738c4" + url: "https://pub.dev" + source: hosted + version: "2.6.0" + camera_web: + dependency: transitive + description: + name: camera_web + sha256: d4c2c571c7af04f8b10702ca16bb9ed2a26e64534171e8f75c9349b2c004d8f1 + url: "https://pub.dev" + source: hosted + version: "0.3.2+3" characters: dependency: transitive description: @@ -1223,4 +1263,4 @@ packages: version: "3.1.2" sdks: dart: ">=3.1.0 <4.0.0" - flutter: ">=3.10.0" + flutter: ">=3.13.0" diff --git a/pubspec.yaml b/pubspec.yaml index 6317842..423c709 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -43,6 +43,7 @@ dependencies: flutter_tesseract_ocr: ^0.4.24 google_mlkit_text_recognition: ^0.10.0 flutter_stripe: ^9.5.0+1 + camera: ^0.10.5+5