674 lines
22 KiB
Dart
674 lines
22 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'dart:typed_data';
|
|
import 'package:camera/camera.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:image_picker/image_picker.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:SEFER/constant/api_key.dart';
|
|
import 'package:SEFER/constant/colors.dart';
|
|
import 'package:SEFER/constant/info.dart';
|
|
import 'package:SEFER/constant/style.dart';
|
|
import 'package:SEFER/constant/table_names.dart';
|
|
import 'package:SEFER/main.dart';
|
|
import 'package:SEFER/views/widgets/elevated_btn.dart';
|
|
|
|
import '../../constant/box_name.dart';
|
|
import '../../constant/links.dart';
|
|
import '../auth/captin/register_captin_controller.dart';
|
|
import 'launch.dart';
|
|
|
|
//
|
|
// class TextExtractionController extends GetxController {
|
|
// String extractedText = '';
|
|
// bool isloading = false;
|
|
// File? _scannedImage;
|
|
// // Convert the extracted text to JSON
|
|
// // Convert the extracted text to JSON
|
|
// 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);
|
|
// }
|
|
//
|
|
// // Convert the extracted text to blocks by line
|
|
// List<String> getTextBlocks(String text) {
|
|
// return text.split('\n');
|
|
// }
|
|
//
|
|
// // Future<void> pickAndExtractText() async {
|
|
// // final pickedImage = await ImagePicker().pickImage(
|
|
// // source: ImageSource.camera,
|
|
// // preferredCameraDevice: CameraDevice.rear,
|
|
// // maxHeight: Get.height * .3,
|
|
// // maxWidth: Get.width * .8,
|
|
// // imageQuality: 99,
|
|
// // );
|
|
// // if (pickedImage != null) {
|
|
// // isloading = true;
|
|
// // update();
|
|
// // final imagePath = pickedImage.path;
|
|
// // final languages = [
|
|
// // 'eng',
|
|
// // 'ara'
|
|
// // ]; // Specify the languages you want to use for text extraction
|
|
//
|
|
// // try {
|
|
// // 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();
|
|
// // extractedText =
|
|
// // 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');
|
|
// // extractedText = '';
|
|
// // }
|
|
// // }
|
|
// // }
|
|
// }
|
|
|
|
// class TextMLGoogleRecognizerController extends GetxController {
|
|
// @override
|
|
// void onInit() {
|
|
// scanText();
|
|
// super.onInit();
|
|
// }
|
|
//
|
|
// // The ImagePicker instance
|
|
// final ImagePicker _imagePicker = ImagePicker();
|
|
//
|
|
// // The GoogleMlKit TextRecognizer instance
|
|
// final TextRecognizer _textRecognizer = TextRecognizer();
|
|
//
|
|
// // The scanned text
|
|
// String? scannedText;
|
|
// String? jsonOutput;
|
|
// final List<Map<String, dynamic>> lines = [];
|
|
//
|
|
// Map decode = {};
|
|
//
|
|
// Future<void> scanText() async {
|
|
// // Pick an image from the camera or gallery
|
|
// final XFile? image =
|
|
// await _imagePicker.pickImage(source: ImageSource.gallery);
|
|
//
|
|
// // If no image was picked, return
|
|
// if (image == null) {
|
|
// return;
|
|
// }
|
|
//
|
|
// // Convert the XFile object to an InputImage object
|
|
// final InputImage inputImage = InputImage.fromFile(File(image.path));
|
|
//
|
|
// // Recognize the text in the image
|
|
// final RecognizedText recognizedText =
|
|
// await _textRecognizer.processImage(inputImage);
|
|
// scannedText = recognizedText.text;
|
|
// Map extractedData = {};
|
|
// // Extract the scanned text line by line
|
|
// for (var i = 0; i < recognizedText.blocks.length; i++) {
|
|
// final block = recognizedText.blocks[i];
|
|
// for (final line in block.lines) {
|
|
// final lineText = line.text;
|
|
//
|
|
// if (lineText.contains('DL')) {
|
|
// final dlNumber = lineText.split('DL')[1].trim();
|
|
// extractedData['dl_number'] = dlNumber;
|
|
// }
|
|
// if (lineText.contains('USA')) {
|
|
// final usa = lineText.split('USA')[1].trim();
|
|
// extractedData['USA'] = usa;
|
|
// }
|
|
// if (lineText.contains('DRIVER LICENSE')) {
|
|
// final driverl = lineText;
|
|
// extractedData['DRIVER_LICENSE'] = driverl;
|
|
// }
|
|
//
|
|
// if (lineText.contains('EXP')) {
|
|
// final expiryDate = lineText.split('EXP')[1].trim();
|
|
// extractedData['expiry_date'] = expiryDate;
|
|
// }
|
|
//
|
|
// if (lineText.contains('DOB')) {
|
|
// final dob = lineText.split('DOB')[1].trim();
|
|
// extractedData['dob'] = dob;
|
|
// }
|
|
//
|
|
// if (lineText.contains("LN")) {
|
|
// if ((lineText.indexOf("LN") == 0)) {
|
|
// final lastName = lineText.split('LN')[1].trim();
|
|
// extractedData['lastName'] = lastName;
|
|
// }
|
|
// }
|
|
// if (lineText.contains("FN")) {
|
|
// final firstName = lineText.split('FN')[1].trim();
|
|
// extractedData['firstName'] = firstName;
|
|
// }
|
|
// if (lineText.contains("RSTR")) {
|
|
// final rstr = lineText.split('RSTR')[1].trim();
|
|
// extractedData['rstr'] = rstr;
|
|
// }
|
|
// if (lineText.contains("CLASS")) {
|
|
// final class1 = lineText.split('CLASS')[1].trim();
|
|
// extractedData['class'] = class1;
|
|
// }
|
|
// if (lineText.contains("END")) {
|
|
// final end = lineText.split('END')[1].trim();
|
|
// extractedData['end'] = end;
|
|
// }
|
|
// if (lineText.contains("DD")) {
|
|
// final dd = lineText.split('DD')[1].trim();
|
|
// extractedData['dd'] = dd;
|
|
// }
|
|
// if (lineText.contains("EYES")) {
|
|
// final eyes = lineText.split('EYES')[1].trim();
|
|
// extractedData['eyes'] = eyes;
|
|
// }
|
|
// if (lineText.contains("SEX")) {
|
|
// final parts = lineText.split("SEX ")[1];
|
|
// extractedData['sex'] = parts[0];
|
|
// }
|
|
// if (lineText.contains("HAIR")) {
|
|
// final hair = lineText.split('HAIR')[1].trim();
|
|
// extractedData['hair'] = hair;
|
|
// }
|
|
//
|
|
// if (lineText.contains('STREET') || lineText.contains(',')) {
|
|
// final address = lineText;
|
|
// extractedData['address'] = address;
|
|
// }
|
|
//
|
|
// // Repeat this process for other relevant data fields
|
|
// }
|
|
// }
|
|
//
|
|
// // Convert the list of lines to a JSON string
|
|
// jsonOutput = jsonEncode(extractedData);
|
|
// decode = jsonDecode(jsonOutput!);
|
|
//
|
|
// update();
|
|
// print('jsonOutput------------------------------');
|
|
// print(scannedText);
|
|
// }
|
|
// }
|
|
|
|
class ScanDocumentsByApi extends GetxController {
|
|
bool isLoading = false;
|
|
Map<String, dynamic> responseMap = {};
|
|
final ImagePicker imagePicker = ImagePicker();
|
|
late Uint8List imagePortrait;
|
|
late Uint8List imageSignature;
|
|
late Uint8List imageDocumentFrontSide;
|
|
XFile? image;
|
|
XFile? imagePortraitFile;
|
|
XFile? imageFace;
|
|
late File tempFile;
|
|
late String imagePath;
|
|
DateTime now = DateTime.now();
|
|
late String name;
|
|
late String licenseClass;
|
|
late String documentNo;
|
|
late String address;
|
|
late String stateCode;
|
|
late String height;
|
|
late String sex;
|
|
late String postalCode;
|
|
late String dob;
|
|
late String expireDate;
|
|
|
|
// ///////////////////////
|
|
// late CameraController cameraController;
|
|
// late List<CameraDescription> cameras;
|
|
// bool isCameraInitialized = false;
|
|
// // final TextRecognizer _textRecognizer = TextRecognizer();
|
|
// String? scannedText;
|
|
|
|
// Future<void> initializeCamera(int cameraID) async {
|
|
// try {
|
|
// cameras = await availableCameras();
|
|
// //update();
|
|
// cameraController = CameraController(
|
|
// cameras[cameraID],
|
|
// ResolutionPreset.medium,
|
|
// 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<void> scanDocumentsByApi() async {
|
|
// String? visionApi = await storage.read(key: BoxName.visionApi);
|
|
// String? visionApi = AK.visionApi;
|
|
// Pick an image from the camera or gallery
|
|
// print(visionApi);
|
|
image = await imagePicker.pickImage(source: ImageSource.camera); //
|
|
|
|
// If no image was picked, return
|
|
if (image == null) {
|
|
return;
|
|
}
|
|
|
|
isLoading = true;
|
|
update();
|
|
var headers = {'X-BLOBR-KEY': AK.visionApi};
|
|
var request = http.MultipartRequest('POST',
|
|
Uri.parse('https://api.faceonlive.com/j2y3q25y1b6maif1/api/iddoc'));
|
|
request.files.add(await http.MultipartFile.fromPath('image', image!.path));
|
|
request.headers.addAll(headers);
|
|
|
|
http.StreamedResponse response = await request.send();
|
|
|
|
if (response.statusCode == 200) {
|
|
String responseString = await response.stream.bytesToString();
|
|
responseMap = jsonDecode(responseString);
|
|
var ocrData = responseMap['data']['ocr'];
|
|
name = ocrData['name'].toString();
|
|
licenseClass = ocrData['dlClass'].toString();
|
|
documentNo = ocrData['documentNumber'].toString();
|
|
address = ocrData['address'].toString();
|
|
height = ocrData['height'].toString();
|
|
postalCode = ocrData['addressPostalCode'].toString();
|
|
sex = ocrData['sex'].toString();
|
|
stateCode = ocrData['addressJurisdictionCode'].toString();
|
|
expireDate = ocrData['dateOfExpiry'].toString();
|
|
dob = ocrData['dateOfBirth'].toString();
|
|
if (responseMap['data'] != null &&
|
|
responseMap['data']['image'] != null &&
|
|
responseMap['data']['image']['portrait'] != null) {
|
|
imagePortrait = base64Decode(responseMap['data']['image']['portrait']);
|
|
String tempPath = Directory.systemTemp.path;
|
|
tempFile = File('$tempPath/image.jpg');
|
|
await tempFile.writeAsBytes(imagePortrait);
|
|
|
|
imagePath = tempFile.path;
|
|
// imagePortraitFile=File(imagePath) ;
|
|
update();
|
|
} else {
|
|
// Handle error or provide a default value
|
|
}
|
|
|
|
if (responseMap['data']['image']['signature'] != null) {
|
|
imageSignature =
|
|
base64Decode(responseMap['data']['image']['signature']);
|
|
} else {
|
|
imageSignature = imagePortrait;
|
|
// Handle error or provide a default value
|
|
}
|
|
|
|
if (responseMap['data'] != null &&
|
|
responseMap['data']['image'] != null &&
|
|
responseMap['data']['image']['documentFrontSide'] != null) {
|
|
imageDocumentFrontSide =
|
|
base64Decode(responseMap['data']['image']['documentFrontSide']);
|
|
} else {
|
|
// Handle error or provide a default value
|
|
}
|
|
|
|
// print(responseMap);
|
|
isLoading = false;
|
|
update();
|
|
} else {
|
|
print(response.reasonPhrase);
|
|
}
|
|
}
|
|
|
|
late int times;
|
|
Future checkMatchFaceApi() async {
|
|
sql.getAllData(TableName.faceDetectTimes).then((value) {
|
|
if (value.isEmpty || value == null) {
|
|
sql.insertData({'faceDetectTimes': 1}, TableName.faceDetectTimes);
|
|
sql.getAllData(TableName.faceDetectTimes).then((value) {
|
|
times = value[0]['faceDetectTimes'];
|
|
update();
|
|
});
|
|
} else {
|
|
if (times < 4) {
|
|
times++;
|
|
matchFaceApi();
|
|
sql.updateData(
|
|
{'faceDetectTimes': times}, TableName.faceDetectTimes, 1);
|
|
} else {
|
|
Get.defaultDialog(
|
|
barrierDismissible: false,
|
|
title: 'You have finished all times '.tr,
|
|
titleStyle: AppStyle.title,
|
|
middleText: 'if you want help you can email us here'.tr,
|
|
middleTextStyle: AppStyle.title,
|
|
cancel: MyElevatedButton(
|
|
title: 'Thanks'.tr,
|
|
kolor: AppColor.greenColor,
|
|
onPressed: () => Get.back(),
|
|
),
|
|
confirm: MyElevatedButton(
|
|
title: 'Email Us'.tr,
|
|
kolor: AppColor.yellowColor, //
|
|
onPressed: () {
|
|
launchCommunication('email', 'support@mobile-app.store',
|
|
'${'Hi'.tr} ${AppInformation.appName}\n${'I cant register in your app in face detection '.tr}');
|
|
Get.back();
|
|
},
|
|
));
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
Map res = {};
|
|
Future matchFaceApi() async {
|
|
// String? visionApi = await storage.read(key: BoxName.visionApi);
|
|
imageFace = await imagePicker.pickImage(
|
|
source: ImageSource.camera,
|
|
preferredCameraDevice: CameraDevice.front,
|
|
);
|
|
|
|
// If no image was picked, return
|
|
if (image == null) {
|
|
return;
|
|
}
|
|
final imageFile = File(imageFace!.path);
|
|
// Uint8List imageBytes = await imageFile.readAsBytes();
|
|
var headers = {'X-BLOBR-KEY': AK.visionApi};
|
|
var request = http.MultipartRequest(
|
|
'POST',
|
|
Uri.parse(
|
|
'https://api.faceonlive.com/sntzbspfsdupgid1/api/face_compare'));
|
|
request.files
|
|
.add(await http.MultipartFile.fromPath('image1', imageFile.path));
|
|
request.files.add(await http.MultipartFile.fromPath('image2', imagePath));
|
|
request.headers.addAll(headers);
|
|
|
|
http.StreamedResponse response = await request.send();
|
|
print('Request: ${request.toString()}');
|
|
print('Response Status Code: ${response.statusCode}');
|
|
print('Response Reason Phrase: ${response.reasonPhrase}');
|
|
|
|
if (response.statusCode == 200) {
|
|
res = jsonDecode(await response.stream.bytesToString());
|
|
print(res);
|
|
|
|
update();
|
|
res['data']['result'].toString().contains('No face detected in image')
|
|
? Get.defaultDialog(
|
|
barrierDismissible: false,
|
|
title: 'No face detected'.tr,
|
|
middleText: ''.tr,
|
|
titleStyle: AppStyle.title,
|
|
confirm: MyElevatedButton(
|
|
kolor: AppColor.yellowColor,
|
|
title: 'Back'.tr,
|
|
onPressed: () {
|
|
Get.back();
|
|
},
|
|
)) //
|
|
: Get.defaultDialog(
|
|
// barrierDismissible: false,
|
|
title: 'Image detecting result is '.tr,
|
|
titleStyle: AppStyle.title,
|
|
content: Column(
|
|
children: [
|
|
Text(
|
|
res['data']['result'].toString(),
|
|
style: res['data']['result'].toString() == 'Different'
|
|
? AppStyle.title.copyWith(color: AppColor.redColor)
|
|
: AppStyle.title.copyWith(color: AppColor.greenColor),
|
|
),
|
|
res['data']['result'].toString() == 'Different'
|
|
? Text(
|
|
'${'Be sure for take accurate images please\nYou have'.tr} $times ${'from 3 times Take Attention'.tr}',
|
|
style: AppStyle.title,
|
|
)
|
|
: Text(
|
|
'image verified'.tr,
|
|
style: AppStyle.title,
|
|
)
|
|
],
|
|
),
|
|
confirm: res['data']['result'].toString() == 'Different'
|
|
? MyElevatedButton(
|
|
title: 'Back'.tr,
|
|
onPressed: () => Get.back(),
|
|
kolor: AppColor.redColor,
|
|
)
|
|
: MyElevatedButton(
|
|
title: 'Next'.tr,
|
|
onPressed: () async {
|
|
RegisterCaptainController registerCaptainController =
|
|
Get.put(RegisterCaptainController());
|
|
|
|
await registerCaptainController.register();
|
|
await registerCaptainController.addLisence();
|
|
await uploadImagePortrate();
|
|
// Get.to(() => CarLicensePage());
|
|
},
|
|
// {
|
|
// await uploadImage(
|
|
// tempFile, AppLink.uploadImagePortrate);
|
|
// Get.to(() => CarLicensePage());
|
|
// },
|
|
kolor: AppColor.greenColor,
|
|
));
|
|
} else {
|
|
print(response.reasonPhrase);
|
|
}
|
|
}
|
|
|
|
// Todo upload images and fields
|
|
Future<String> uploadImagePortrate() async {
|
|
isLoading = true;
|
|
update();
|
|
|
|
var request = http.MultipartRequest(
|
|
'POST',
|
|
Uri.parse(AppLink.uploadImagePortrate),
|
|
);
|
|
|
|
request.files.add(
|
|
http.MultipartFile.fromBytes('image', imagePortrait),
|
|
);
|
|
|
|
request.headers.addAll({
|
|
"Content-Type": "multipart/form-data",
|
|
'Authorization':
|
|
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
|
|
});
|
|
request.fields['driverID'] = box.read(BoxName.driverID).toString();
|
|
|
|
var response = await request.send();
|
|
|
|
var responseData = await response.stream.toBytes();
|
|
var responseString = String.fromCharCodes(responseData);
|
|
|
|
isLoading = false;
|
|
update();
|
|
|
|
// Print the response string
|
|
print(responseString);
|
|
|
|
return responseString;
|
|
}
|
|
|
|
@override
|
|
void onInit() {
|
|
// scanDocumentsByApi();
|
|
// initializeCamera(0);
|
|
sql.getAllData(TableName.faceDetectTimes).then((value) {
|
|
if (value.isEmpty) {
|
|
print(value);
|
|
times = 0;
|
|
print(times);
|
|
update();
|
|
// sql.insertData({'faceDetectTimes': 1}, TableName.faceDetectTimes);
|
|
} else {
|
|
times = value[0]['faceDetectTimes'];
|
|
}
|
|
});
|
|
super.onInit();
|
|
}
|
|
}
|
|
|
|
// class PassportDataExtractor extends GetxController {
|
|
// @override
|
|
// void onInit() {
|
|
// extractPassportData();
|
|
// super.onInit();
|
|
// }
|
|
//
|
|
// final ImagePicker _imagePicker = ImagePicker();
|
|
// late final XFile? image;
|
|
// final TextRecognizer _textRecognizer = TextRecognizer();
|
|
//
|
|
// Future<Map<String, dynamic>> extractPassportData() async {
|
|
// image = await _imagePicker.pickImage(source: ImageSource.gallery);
|
|
// update();
|
|
// if (image == null) {
|
|
// throw Exception('No image picked');
|
|
// }
|
|
//
|
|
// final InputImage inputImage = InputImage.fromFile(File(image!.path));
|
|
// final RecognizedText recognisedText =
|
|
// await _textRecognizer.processImage(inputImage);
|
|
//
|
|
// final Map<String, dynamic> extractedData = {};
|
|
// final List<Map<String, dynamic>> extractedTextWithCoordinates = [];
|
|
//
|
|
// for (TextBlock block in recognisedText.blocks) {
|
|
// for (TextLine line in block.lines) {
|
|
// final String lineText = line.text;
|
|
// final Rect lineBoundingBox = line.boundingBox!;
|
|
//
|
|
// extractedTextWithCoordinates.add({
|
|
// 'text': lineText,
|
|
// 'boundingBox': {
|
|
// 'left': lineBoundingBox.left,
|
|
// 'top': lineBoundingBox.top,
|
|
// 'width': lineBoundingBox.width,
|
|
// 'height': lineBoundingBox.height,
|
|
// },
|
|
// });
|
|
//
|
|
// // if (lineText.contains('Passport Number')) {
|
|
// // final String passportNumber =
|
|
// // lineText.split('Passport Number')[1].trim();
|
|
// // extractedData['passportNumber'] = passportNumber;
|
|
// // }
|
|
// // if (lineText.contains('Given Names')) {
|
|
// // final String givenNames = lineText.split('Given Names')[1].trim();
|
|
// // extractedData['givenNames'] = givenNames;
|
|
// // }
|
|
// // if (lineText.contains('Surname')) {
|
|
// // final String surname = lineText.split('Surname')[1].trim();
|
|
// // extractedData['surname'] = surname;
|
|
// // }
|
|
// // if (lineText.contains('Nationality')) {
|
|
// // final String nationality = lineText.split('Nationality')[1].trim();
|
|
// // extractedData['nationality'] = nationality;
|
|
// // }
|
|
// // if (lineText.contains('Date of Birth')) {
|
|
// // final String dob = lineText.split('Date of Birth')[1].trim();
|
|
// // extractedData['dateOfBirth'] = dob;
|
|
// // }
|
|
// // Add more field extraction conditions as needed
|
|
// }
|
|
// }
|
|
//
|
|
// extractedData['extractedTextWithCoordinates'] =
|
|
// extractedTextWithCoordinates;
|
|
// print(jsonEncode(extractedData));
|
|
// return extractedData;
|
|
// }
|
|
// }
|
|
//
|
|
// class PassportDataController extends GetxController {
|
|
// PassportDataExtractor passportDataExtractor = PassportDataExtractor();
|
|
// List<Map<String, dynamic>> extractedTextWithCoordinates = [];
|
|
//
|
|
// Future<void> extractDataAndDrawBoundingBoxes() async {
|
|
// try {
|
|
// Map<String, dynamic> extractedData =
|
|
// await passportDataExtractor.extractPassportData();
|
|
// extractedTextWithCoordinates =
|
|
// extractedData['extractedTextWithCoordinates'];
|
|
// update(); // Notify GetX that the state has changed
|
|
// print(extractedTextWithCoordinates);
|
|
// } catch (e) {
|
|
// print('Passport data extraction failed: $e');
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// class BoundingBoxPainter extends CustomPainter {
|
|
// final List<Map<String, dynamic>> boundingBoxes;
|
|
//
|
|
// BoundingBoxPainter(this.boundingBoxes);
|
|
//
|
|
// @override
|
|
// void paint(Canvas canvas, Size size) {
|
|
// final Paint paint = Paint()
|
|
// ..color = Colors.red
|
|
// ..style = PaintingStyle.stroke
|
|
// ..strokeWidth = 2.0;
|
|
//
|
|
// for (Map<String, dynamic> boundingBox in boundingBoxes) {
|
|
// double left = boundingBox['left'];
|
|
// double top = boundingBox['top'];
|
|
// double width = boundingBox['width'];
|
|
// double height = boundingBox['height'];
|
|
//
|
|
// Rect rect = Rect.fromLTWH(left, top, width, height);
|
|
// canvas.drawRect(rect, paint);
|
|
// }
|
|
// }
|
|
//
|
|
// @override
|
|
// bool shouldRepaint(covariant CustomPainter oldDelegate) {
|
|
// return false;
|
|
// }
|
|
// }
|