Skip to content

Commit f6e09b0

Browse files
committed
feat: show photo with date of ml kit
1 parent 6eaf293 commit f6e09b0

File tree

5 files changed

+241
-156
lines changed

5 files changed

+241
-156
lines changed

android/app/build.gradle

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@ android {
2828
compileSdkVersion 30
2929

3030
defaultConfig {
31-
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
3231
applicationId "com.tiagodanin.example.flutter_face_detection"
33-
minSdkVersion 16
32+
minSdkVersion 24
3433
targetSdkVersion 30
3534
versionCode flutterVersionCode.toInteger()
3635
versionName flutterVersionName

lib/main.dart

Lines changed: 2 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,19 @@
11
import 'package:flutter/material.dart';
2+
import 'package:flutter_face_detection/screens/HomeView.dart';
23

34
void main() {
45
runApp(MyApp());
56
}
67

78
class MyApp extends StatelessWidget {
8-
// This widget is the root of your application.
99
@override
1010
Widget build(BuildContext context) {
1111
return MaterialApp(
1212
title: 'Flutter Demo',
1313
theme: ThemeData(
14-
// This is the theme of your application.
15-
//
16-
// Try running your application with "flutter run". You'll see the
17-
// application has a blue toolbar. Then, without quitting the app, try
18-
// changing the primarySwatch below to Colors.green and then invoke
19-
// "hot reload" (press "r" in the console where you ran "flutter run",
20-
// or simply save your changes to "hot reload" in a Flutter IDE).
21-
// Notice that the counter didn't reset back to zero; the application
22-
// is not restarted.
2314
primarySwatch: Colors.blue,
2415
),
25-
home: MyHomePage(title: 'Flutter Demo Home Page'),
26-
);
27-
}
28-
}
29-
30-
class MyHomePage extends StatefulWidget {
31-
MyHomePage({Key key, this.title}) : super(key: key);
32-
33-
// This widget is the home page of your application. It is stateful, meaning
34-
// that it has a State object (defined below) that contains fields that affect
35-
// how it looks.
36-
37-
// This class is the configuration for the state. It holds the values (in this
38-
// case the title) provided by the parent (in this case the App widget) and
39-
// used by the build method of the State. Fields in a Widget subclass are
40-
// always marked "final".
41-
42-
final String title;
43-
44-
@override
45-
_MyHomePageState createState() => _MyHomePageState();
46-
}
47-
48-
class _MyHomePageState extends State<MyHomePage> {
49-
int _counter = 0;
50-
51-
void _incrementCounter() {
52-
setState(() {
53-
// This call to setState tells the Flutter framework that something has
54-
// changed in this State, which causes it to rerun the build method below
55-
// so that the display can reflect the updated values. If we changed
56-
// _counter without calling setState(), then the build method would not be
57-
// called again, and so nothing would appear to happen.
58-
_counter++;
59-
});
60-
}
61-
62-
@override
63-
Widget build(BuildContext context) {
64-
// This method is rerun every time setState is called, for instance as done
65-
// by the _incrementCounter method above.
66-
//
67-
// The Flutter framework has been optimized to make rerunning build methods
68-
// fast, so that you can just rebuild anything that needs updating rather
69-
// than having to individually change instances of widgets.
70-
return Scaffold(
71-
appBar: AppBar(
72-
// Here we take the value from the MyHomePage object that was created by
73-
// the App.build method, and use it to set our appbar title.
74-
title: Text(widget.title),
75-
),
76-
body: Center(
77-
// Center is a layout widget. It takes a single child and positions it
78-
// in the middle of the parent.
79-
child: Column(
80-
// Column is also a layout widget. It takes a list of children and
81-
// arranges them vertically. By default, it sizes itself to fit its
82-
// children horizontally, and tries to be as tall as its parent.
83-
//
84-
// Invoke "debug painting" (press "p" in the console, choose the
85-
// "Toggle Debug Paint" action from the Flutter Inspector in Android
86-
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
87-
// to see the wireframe for each widget.
88-
//
89-
// Column has various properties to control how it sizes itself and
90-
// how it positions its children. Here we use mainAxisAlignment to
91-
// center the children vertically; the main axis here is the vertical
92-
// axis because Columns are vertical (the cross axis would be
93-
// horizontal).
94-
mainAxisAlignment: MainAxisAlignment.center,
95-
children: <Widget>[
96-
Text(
97-
'You have pushed the button this many times:',
98-
),
99-
Text(
100-
'$_counter',
101-
style: Theme.of(context).textTheme.headline4,
102-
),
103-
],
104-
),
105-
),
106-
floatingActionButton: FloatingActionButton(
107-
onPressed: _incrementCounter,
108-
tooltip: 'Increment',
109-
child: Icon(Icons.add),
110-
), // This trailing comma makes auto-formatting nicer for build methods.
16+
home: HomePage(),
11117
);
11218
}
11319
}

lib/screens/HomeView.dart

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import 'dart:ui';
2+
import 'dart:ui' as ui show Image;
3+
4+
import 'package:flutter/material.dart';
5+
import 'package:google_ml_kit/google_ml_kit.dart';
6+
import 'package:image_picker/image_picker.dart';
7+
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
8+
9+
class HomePage extends StatefulWidget {
10+
HomePage({Key key}) : super(key: key);
11+
12+
@override
13+
HomePageWithState createState() => HomePageWithState();
14+
}
15+
16+
class HomePageWithState extends State<HomePage> {
17+
ui.Image imageSelected = null;
18+
List<Face> faces = [];
19+
20+
void getImage() async {
21+
final PickedFile pickedFile = await ImagePicker().getImage(source: ImageSource.gallery);
22+
if (pickedFile != null) {
23+
var imageFile = await pickedFile.readAsBytes();
24+
ui.Image imageFile2 = await decodeImageFromList(imageFile);
25+
26+
final InputImage inputImage = InputImage.fromFilePath(pickedFile.path);
27+
final FaceDetector faceDetector = GoogleMlKit.vision.faceDetector(FaceDetectorOptions(
28+
enableClassification: true,
29+
enableTracking: true,
30+
));
31+
32+
final List<Face> outputFaces = await faceDetector.processImage(inputImage);
33+
34+
setState(() {
35+
imageSelected = imageFile2;
36+
faces = outputFaces;
37+
});
38+
}
39+
}
40+
41+
@override
42+
Widget build(BuildContext context) {
43+
return Scaffold(
44+
appBar: AppBar(
45+
title: Text("ML Kit Face Detection"),
46+
),
47+
body: Center(
48+
child: InteractiveViewer(
49+
panEnabled: true,
50+
boundaryMargin: EdgeInsets.all(1000),
51+
minScale: 0.1,
52+
maxScale: 3,
53+
child: Column(
54+
children: [
55+
if (imageSelected != null)
56+
Container(
57+
height: imageSelected.height.toDouble(),
58+
width: imageSelected.width.toDouble(),
59+
child: CustomPaint(
60+
painter: FaceDraw(faces: faces, image: imageSelected),
61+
),
62+
)
63+
],
64+
),
65+
),
66+
),
67+
floatingActionButton: FloatingActionButton(
68+
onPressed: getImage,
69+
tooltip: 'Select',
70+
child: Icon(MdiIcons.image),
71+
),
72+
);
73+
}
74+
}
75+
76+
class FaceDraw extends CustomPainter {
77+
List<Face> faces;
78+
ui.Image image;
79+
80+
FaceDraw({@required this.faces, @required this.image});
81+
82+
@override
83+
void paint(Canvas canvas, Size size) {
84+
canvas.drawImage(image, Offset.zero, Paint());
85+
86+
for (Face face in faces) {
87+
canvas.drawRect(
88+
face.boundingBox,
89+
Paint()
90+
..style = PaintingStyle.stroke
91+
..color = Colors.blueAccent
92+
..strokeWidth = 4,
93+
);
94+
95+
canvas.drawLine(
96+
Offset(face.boundingBox.left + 5, face.boundingBox.top - 12),
97+
Offset(face.boundingBox.right - 5, face.boundingBox.top - 12),
98+
Paint()
99+
..color = Colors.white.withOpacity(0.8)
100+
..strokeWidth = 18
101+
..style = PaintingStyle.fill);
102+
103+
TextPainter paintSpanId = new TextPainter(
104+
text: TextSpan(
105+
style: new TextStyle(
106+
color: Colors.black,
107+
fontSize: 15,
108+
fontWeight: FontWeight.w400,
109+
fontFamily: 'Roboto',
110+
),
111+
text: "ID::${face.trackingId}",
112+
),
113+
textAlign: TextAlign.center,
114+
textDirection: TextDirection.ltr,
115+
);
116+
117+
paintSpanId.layout();
118+
paintSpanId.paint(canvas, new Offset(face.boundingBox.left + 10, face.boundingBox.top - 20));
119+
120+
canvas.drawLine(
121+
Offset(face.boundingBox.left, face.boundingBox.bottom + 14),
122+
Offset(face.boundingBox.right, face.boundingBox.bottom + 14),
123+
Paint()
124+
..color = Colors.black.withOpacity(0.7)
125+
..strokeWidth = 20
126+
..style = PaintingStyle.fill);
127+
128+
TextPainter paintSmilingStatus = new TextPainter(
129+
text: TextSpan(
130+
style: TextStyle(
131+
color: Colors.white,
132+
fontSize: 15,
133+
fontWeight: FontWeight.w700,
134+
fontFamily: 'Roboto',
135+
),
136+
text: "Smiling::${face.smilingProbability >= 0.5 ? "Yes" : "No"}",
137+
),
138+
textAlign: TextAlign.center,
139+
textDirection: TextDirection.ltr,
140+
);
141+
142+
paintSmilingStatus.layout();
143+
paintSmilingStatus.paint(canvas, new Offset(face.boundingBox.left + 3, face.boundingBox.bottom + 5));
144+
}
145+
}
146+
147+
@override
148+
bool shouldRepaint(CustomPainter oldDelegate) {
149+
return false;
150+
}
151+
}

pubspec.lock

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,86 @@ packages:
6262
description: flutter
6363
source: sdk
6464
version: "0.0.0"
65+
flutter_plugin_android_lifecycle:
66+
dependency: transitive
67+
description:
68+
name: flutter_plugin_android_lifecycle
69+
url: "https://pub.dartlang.org"
70+
source: hosted
71+
version: "2.0.2"
6572
flutter_test:
6673
dependency: "direct dev"
6774
description: flutter
6875
source: sdk
6976
version: "0.0.0"
77+
flutter_web_plugins:
78+
dependency: transitive
79+
description: flutter
80+
source: sdk
81+
version: "0.0.0"
82+
google_ml_kit:
83+
dependency: "direct main"
84+
description:
85+
name: google_ml_kit
86+
url: "https://pub.dartlang.org"
87+
source: hosted
88+
version: "0.6.0"
89+
http:
90+
dependency: transitive
91+
description:
92+
name: http
93+
url: "https://pub.dartlang.org"
94+
source: hosted
95+
version: "0.13.3"
96+
http_parser:
97+
dependency: transitive
98+
description:
99+
name: http_parser
100+
url: "https://pub.dartlang.org"
101+
source: hosted
102+
version: "4.0.0"
103+
image_picker:
104+
dependency: "direct main"
105+
description:
106+
name: image_picker
107+
url: "https://pub.dartlang.org"
108+
source: hosted
109+
version: "0.8.0+1"
110+
image_picker_for_web:
111+
dependency: transitive
112+
description:
113+
name: image_picker_for_web
114+
url: "https://pub.dartlang.org"
115+
source: hosted
116+
version: "2.0.0"
117+
image_picker_platform_interface:
118+
dependency: transitive
119+
description:
120+
name: image_picker_platform_interface
121+
url: "https://pub.dartlang.org"
122+
source: hosted
123+
version: "2.1.0"
124+
js:
125+
dependency: transitive
126+
description:
127+
name: js
128+
url: "https://pub.dartlang.org"
129+
source: hosted
130+
version: "0.6.3"
70131
matcher:
71132
dependency: transitive
72133
description:
73134
name: matcher
74135
url: "https://pub.dartlang.org"
75136
source: hosted
76137
version: "0.12.10"
138+
material_design_icons_flutter:
139+
dependency: "direct main"
140+
description:
141+
name: material_design_icons_flutter
142+
url: "https://pub.dartlang.org"
143+
source: hosted
144+
version: "4.0.5955"
77145
meta:
78146
dependency: transitive
79147
description:
@@ -88,6 +156,20 @@ packages:
88156
url: "https://pub.dartlang.org"
89157
source: hosted
90158
version: "1.8.0"
159+
pedantic:
160+
dependency: transitive
161+
description:
162+
name: pedantic
163+
url: "https://pub.dartlang.org"
164+
source: hosted
165+
version: "1.11.0"
166+
plugin_platform_interface:
167+
dependency: transitive
168+
description:
169+
name: plugin_platform_interface
170+
url: "https://pub.dartlang.org"
171+
source: hosted
172+
version: "2.0.0"
91173
sky_engine:
92174
dependency: transitive
93175
description: flutter
@@ -151,3 +233,4 @@ packages:
151233
version: "2.1.0"
152234
sdks:
153235
dart: ">=2.12.0 <3.0.0"
236+
flutter: ">=2.0.0"

0 commit comments

Comments
 (0)