Merge pull request #42 from FRE-Informatica/fix/fd-566
Fix/fd 566 - Detecção e Tratamento de Faces e Imagens
This commit is contained in:
commit
41abe3121b
|
@ -93,6 +93,11 @@ dependencies {
|
|||
|
||||
implementation 'androidx.window:window:1.0.0'
|
||||
implementation 'androidx.window:window-java:1.0.0'
|
||||
implementation ('com.google.firebase:firebase-messaging:24.0.0') {
|
||||
exclude group: 'com.google.firebase', module: 'firebase-iid'
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
apply plugin: 'com.google.gms.google-services'
|
|
@ -87,6 +87,7 @@
|
|||
android:name="com.google.firebase.messaging.default_notification_icon"
|
||||
android:resource="@drawable/notification_icon" />
|
||||
|
||||
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
|
|
|
@ -513,7 +513,7 @@ class _RegisiterVistorTemplateComponentWidgetState
|
|||
child: FFButtonWidget(
|
||||
onPressed: () async {
|
||||
final selectedMedia =
|
||||
await selectMediaWithSourceBottomSheet(
|
||||
await selectMediaWithSourceBottomSheetandFaceDetection(
|
||||
context: context,
|
||||
// maxWidth: 300.00,
|
||||
// maxHeight: 300.00,
|
||||
|
|
|
@ -4,7 +4,9 @@ import 'package:file_picker/file_picker.dart';
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart';
|
||||
import 'package:hub/flutter_flow/nav/nav.dart';
|
||||
import 'package:hub/shared/utils/dialog_util.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:mime_type/mime_type.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
|
@ -44,6 +46,174 @@ enum MediaSource {
|
|||
camera,
|
||||
}
|
||||
|
||||
Future<List<SelectedFile>?> selectMediaWithSourceBottomSheetandFaceDetection({
|
||||
required BuildContext context,
|
||||
String? storageFolderPath,
|
||||
double? maxWidth,
|
||||
double? maxHeight,
|
||||
int? imageQuality,
|
||||
required bool allowPhoto,
|
||||
bool allowVideo = false,
|
||||
String pickerFontFamily = 'Roboto',
|
||||
// Color textColor = const Color(0xFF111417),
|
||||
// Color backgroundColor = const Color(0xFFF5F5F5),
|
||||
bool includeDimensions = false,
|
||||
bool includeBlurHash = false,
|
||||
}) async {
|
||||
final faceDetector = FaceDetector(
|
||||
options: FaceDetectorOptions(
|
||||
enableContours: true,
|
||||
enableLandmarks: true,
|
||||
),
|
||||
);
|
||||
createUploadMediaListTile(
|
||||
String label, MediaSource mediaSource, IconData icon) =>
|
||||
ListTile(
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(icon, color: FlutterFlowTheme.of(context).primaryText),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
label,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.getFont(
|
||||
pickerFontFamily,
|
||||
color: FlutterFlowTheme.of(context).primaryText,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
tileColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||
dense: false,
|
||||
onTap: () => context.pop(mediaSource),
|
||||
);
|
||||
final mediaSource = await showModalBottomSheet<MediaSource>(
|
||||
context: context,
|
||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||
builder: (context) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (!kIsWeb) ...[
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 10),
|
||||
width: 40,
|
||||
height: 5,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 8, 0, 0),
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: "Escolha uma das opções",
|
||||
enText: "Choose one of the options"),
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.getFont(
|
||||
pickerFontFamily,
|
||||
color: FlutterFlowTheme.of(context)
|
||||
.primaryText
|
||||
.withOpacity(0.65),
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
tileColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||
dense: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
if (allowPhoto && allowVideo) ...[
|
||||
Expanded(
|
||||
child: createUploadMediaListTile(
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: "Galeria (Foto)",
|
||||
enText: "Gallery (Photo)"),
|
||||
MediaSource.photoGallery,
|
||||
Icons.camera),
|
||||
),
|
||||
Expanded(
|
||||
child: createUploadMediaListTile(
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: "Galeria (Video)",
|
||||
enText: "Gallery (Video)"),
|
||||
MediaSource.videoGallery,
|
||||
Icons.videocam),
|
||||
)
|
||||
] else if (allowPhoto)
|
||||
Expanded(
|
||||
child: createUploadMediaListTile(
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: "Galeria", enText: "Gallery"),
|
||||
MediaSource.photoGallery,
|
||||
Icons.photo))
|
||||
else
|
||||
Expanded(
|
||||
child: createUploadMediaListTile(
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: "Galeria", enText: "Gallery"),
|
||||
MediaSource.videoGallery,
|
||||
Icons.videocam),
|
||||
),
|
||||
if (!kIsWeb) ...[
|
||||
Expanded(
|
||||
child: createUploadMediaListTile(
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: "Camera", enText: "Camera"),
|
||||
MediaSource.camera,
|
||||
Icons.camera_alt),
|
||||
)
|
||||
],
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
],
|
||||
);
|
||||
});
|
||||
if (mediaSource == null) {
|
||||
return null;
|
||||
}
|
||||
final selectedMedia = await selectMedia(
|
||||
storageFolderPath: storageFolderPath,
|
||||
maxWidth: maxWidth,
|
||||
maxHeight: maxHeight,
|
||||
imageQuality: imageQuality,
|
||||
isVideo: mediaSource == MediaSource.videoGallery ||
|
||||
(mediaSource == MediaSource.camera && allowVideo && !allowPhoto),
|
||||
mediaSource: mediaSource,
|
||||
includeDimensions: includeDimensions,
|
||||
includeBlurHash: includeBlurHash,
|
||||
);
|
||||
|
||||
if (selectedMedia == null || selectedMedia.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Verifique se há faces na imagem
|
||||
for (final media in selectedMedia) {
|
||||
final inputImage = InputImage.fromFilePath(media.filePath!);
|
||||
final faces = await faceDetector.processImage(inputImage);
|
||||
if (faces.isEmpty) {
|
||||
final String message = FFLocalizations.of(context).getVariableText(
|
||||
ptText: "Nenhuma face detectada na imagem",
|
||||
enText: "No face detected in the image");
|
||||
DialogUtil.error(context, message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return selectedMedia;
|
||||
}
|
||||
|
||||
Future<List<SelectedFile>?> selectMediaWithSourceBottomSheet({
|
||||
required BuildContext context,
|
||||
String? storageFolderPath,
|
||||
|
@ -58,7 +228,8 @@ Future<List<SelectedFile>?> selectMediaWithSourceBottomSheet({
|
|||
bool includeDimensions = false,
|
||||
bool includeBlurHash = false,
|
||||
}) async {
|
||||
createUploadMediaListTile(String label, MediaSource mediaSource, IconData icon) =>
|
||||
createUploadMediaListTile(
|
||||
String label, MediaSource mediaSource, IconData icon) =>
|
||||
ListTile(
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
|
|
@ -1536,7 +1536,8 @@ Widget scheduleVisit(BuildContext context,
|
|||
|
||||
await ShareUtil.showShare(value.jsonBody);
|
||||
} else {
|
||||
await DialogUtil.errorDefault(context);
|
||||
final message = value.jsonBody['error_msg'];
|
||||
await DialogUtil.error(context, message);
|
||||
context.pop();
|
||||
}
|
||||
});
|
||||
|
|
68
pubspec.lock
68
pubspec.lock
|
@ -113,6 +113,46 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
camera:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: camera
|
||||
sha256: "26ff41045772153f222ffffecba711a206f670f5834d40ebf5eed3811692f167"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.0+2"
|
||||
camera_android_camerax:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: camera_android_camerax
|
||||
sha256: "7cd93578ad201dcc6bb5810451fb00d76a86bab9b68dceb68b8cbd7038ac5846"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.8+3"
|
||||
camera_avfoundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: camera_avfoundation
|
||||
sha256: "7c28969a975a7eb2349bc2cb2dfe3ad218a33dba9968ecfb181ce08c87486655"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.17+3"
|
||||
camera_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: camera_platform_interface
|
||||
sha256: b3ede1f171532e0d83111fe0980b46d17f1aa9788a07a2fbed07366bbdbb9061
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.8.0"
|
||||
camera_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: camera_web
|
||||
sha256: "595f28c89d1fb62d77c73c633193755b781c6d2e0ebcd8dc25b763b514e6ba8f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.5"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -701,6 +741,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.1"
|
||||
google_mlkit_commons:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_mlkit_commons
|
||||
sha256: "9990a65f407a3ef6bae646bf10143faa93fec126683771465bc6c0b43fb0e6e9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.1"
|
||||
google_mlkit_face_detection:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: google_mlkit_face_detection
|
||||
sha256: "0aeab4f39204f7a235ed4cccedfe7e61401b43f4ef139a868c01fa29fdc225ab"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.1"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1346,6 +1402,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
stream_transform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1627,5 +1691,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.2"
|
||||
sdks:
|
||||
dart: ">=3.4.0 <4.0.0"
|
||||
flutter: ">=3.22.0"
|
||||
dart: ">=3.5.0 <4.0.0"
|
||||
flutter: ">=3.24.0"
|
||||
|
|
|
@ -58,11 +58,13 @@ dependencies:
|
|||
image_picker_platform_interface: 2.10.0
|
||||
local_auth: ^2.2.0
|
||||
intl: ^0.19.0
|
||||
camera: ^0.11.0+2
|
||||
json_path: 0.7.2
|
||||
mime_type: 1.0.0
|
||||
page_transition: 2.1.0
|
||||
path_provider: 2.1.3
|
||||
path_provider_android: 2.2.5
|
||||
google_mlkit_face_detection: ^0.11.1
|
||||
path_provider_foundation: 2.4.0
|
||||
path_provider_platform_interface: 2.1.2
|
||||
percent_indicator: 4.2.2
|
||||
|
|
Loading…
Reference in New Issue