@@ -20,6 +20,7 @@ import 'package:cloud_firestore/cloud_firestore.dart';
20
20
import 'package:firebase_storage/firebase_storage.dart' ;
21
21
import 'package:flutter/material.dart' ;
22
22
import 'package:path_provider/path_provider.dart' ;
23
+ import 'package:multi_media_picker/multi_media_picker.dart' ;
23
24
24
25
import 'countdown_timer.dart' ;
25
26
import 'models.dart' ;
@@ -38,14 +39,21 @@ class Camera extends StatefulWidget {
38
39
final String label;
39
40
final String labelKey;
40
41
final UserModel userModel;
41
-
42
- Camera (this .dataset, this .label, this .labelKey, this .userModel);
42
+ final bool isUploading;
43
+ List <File > resultList;
44
+ Camera (this .dataset, this .label, this .labelKey, this .userModel,
45
+ this .isUploading);
43
46
44
47
Future init () async {
45
- try {
46
- cameras = await availableCameras ();
47
- } on CameraException catch (e) {
48
- logError (e.code, e.description);
48
+ if (! isUploading) {
49
+ try {
50
+ cameras = await availableCameras ();
51
+ } on CameraException catch (e) {
52
+ logError (e.code, e.description);
53
+ }
54
+ } else {
55
+ resultList =
56
+ await MultiMediaPicker .pickImages (source: ImageSource .gallery);
49
57
}
50
58
}
51
59
@@ -67,12 +75,14 @@ class _CameraState extends State<Camera> {
67
75
@override
68
76
void initState () {
69
77
super .initState ();
70
- WidgetsBinding .instance.addPostFrameCallback ((_) {
71
- for (CameraDescription cameraDescription in cameras) {
72
- if (cameraDescription.lensDirection == CameraLensDirection .back)
73
- onNewCameraSelected (cameraDescription);
74
- }
75
- });
78
+ if (! widget.isUploading) {
79
+ WidgetsBinding .instance.addPostFrameCallback ((_) {
80
+ for (CameraDescription cameraDescription in cameras) {
81
+ if (cameraDescription.lensDirection == CameraLensDirection .back)
82
+ onNewCameraSelected (cameraDescription);
83
+ }
84
+ });
85
+ }
76
86
}
77
87
78
88
@override
@@ -83,54 +93,74 @@ class _CameraState extends State<Camera> {
83
93
84
94
@override
85
95
Widget build (BuildContext context) {
96
+ if (widget.isUploading && widget.resultList != null ) {
97
+ widget.resultList
98
+ .forEach ((eachImage) => {uploadImageToStorage (eachImage.path)});
99
+ }
86
100
return Scaffold (
87
101
key: _scaffoldKey,
88
102
appBar: AppBar (
89
103
backgroundColor: Theme .of (context).accentColor,
90
104
title: Text ('Capture sample for ${widget .label }' ),
91
105
),
92
- body: Container (
93
- decoration: new BoxDecoration (color: Colors .black),
94
- child: Column (
95
- children: < Widget > [
96
- Expanded (
97
- child: Container (
98
- child: Padding (
99
- padding: const EdgeInsets .all (1.0 ),
100
- child: Center (
101
- child: _cameraPreviewWidget (),
102
- ),
103
- ),
104
- decoration: BoxDecoration (
105
- color: Colors .black,
106
- border: Border .all (
107
- color:
108
- controller != null && controller.value.isRecordingVideo
109
- ? Colors .redAccent
110
- : Colors .black45,
111
- width: 2.0 ,
112
- ),
113
- ),
106
+ body: widget.isUploading
107
+ ? Center (
108
+ child: Column (
109
+ mainAxisAlignment: MainAxisAlignment .center,
110
+ crossAxisAlignment: CrossAxisAlignment .center,
111
+ children: < Widget > [
112
+ Text ('Uploading Images in the background' ),
113
+ MaterialButton (
114
+ onPressed: () {
115
+ Navigator .pop (context);
116
+ },
117
+ child: Text ('OK' ),
118
+ )
119
+ ],
114
120
),
115
- ),
116
- new CameraControlWidget (
117
- controller: controller,
118
- onRecordingStart: onVideoRecordButtonPressed,
119
- onRecordingStop: onStopButtonPressed,
120
- onPictureTaken: onTakePictureButtonPressed,
121
- ),
122
- Padding (
123
- padding: const EdgeInsets .all (5.0 ),
124
- child: Row (
125
- mainAxisAlignment: MainAxisAlignment .start,
121
+ )
122
+ : Container (
123
+ decoration: new BoxDecoration (color: Colors .black),
124
+ child: Column (
126
125
children: < Widget > [
127
- _thumbnailWidget (),
126
+ Expanded (
127
+ child: Container (
128
+ child: Padding (
129
+ padding: const EdgeInsets .all (1.0 ),
130
+ child: Center (
131
+ child: _cameraPreviewWidget (),
132
+ ),
133
+ ),
134
+ decoration: BoxDecoration (
135
+ color: Colors .black,
136
+ border: Border .all (
137
+ color: controller != null &&
138
+ controller.value.isRecordingVideo
139
+ ? Colors .redAccent
140
+ : Colors .black45,
141
+ width: 2.0 ,
142
+ ),
143
+ ),
144
+ ),
145
+ ),
146
+ new CameraControlWidget (
147
+ controller: controller,
148
+ onRecordingStart: onVideoRecordButtonPressed,
149
+ onRecordingStop: onStopButtonPressed,
150
+ onPictureTaken: onTakePictureButtonPressed,
151
+ ),
152
+ Padding (
153
+ padding: const EdgeInsets .all (5.0 ),
154
+ child: Row (
155
+ mainAxisAlignment: MainAxisAlignment .start,
156
+ children: < Widget > [
157
+ _thumbnailWidget (),
158
+ ],
159
+ ),
160
+ ),
128
161
],
129
162
),
130
163
),
131
- ],
132
- ),
133
- ),
134
164
);
135
165
}
136
166
@@ -200,60 +230,7 @@ class _CameraState extends State<Camera> {
200
230
201
231
void onTakePictureButtonPressed () async {
202
232
final filePath = await takePicture ();
203
- final automlStorage = InheritedStorage .of (context).autoMlStorage;
204
-
205
- if (mounted) {
206
- setState (() {
207
- imagePath = filePath;
208
- });
209
-
210
- final filename =
211
- new DateTime .now ().millisecondsSinceEpoch.toString () + '.jpg' ;
212
-
213
- // upload to storage and firestore
214
- final StorageReference ref = automlStorage
215
- .ref ()
216
- .child ('datasets' )
217
- .child (widget.dataset.name)
218
- .child (widget.label)
219
- .child (filename);
220
-
221
- final File file = File (filePath).absolute;
222
- // upload the file
223
- StorageUploadTask uploadTask = ref.putFile (
224
- file,
225
- StorageMetadata (
226
- contentType: 'image/jpeg' ,
227
- customMetadata: < String , String > {'activity' : 'imgUpload' },
228
- ),
229
- );
230
-
231
- final snapshot = await uploadTask.onComplete;
232
- final downloadUrl = await snapshot.ref.getDownloadURL ();
233
-
234
- Firestore .instance.collection ('images' ).add ({
235
- 'parent_key' : widget.labelKey,
236
- 'dataset_parent_key' : widget.dataset.id,
237
- 'type' : toString (SampleType
238
- .TRAIN ), // newly created images are categorized as training.
239
- 'filename' : filename,
240
- 'uploadPath' :
241
- 'datasets/${widget .dataset .name }/${widget .label }/$filename ' ,
242
- 'gcsURI' : downloadUrl,
243
- 'uploader' : widget.userModel.user.email,
244
- });
245
-
246
- final labelRef =
247
- Firestore .instance.collection ('labels' ).document (widget.labelKey);
248
-
249
- // increment count for the label
250
- await Firestore .instance.runTransaction ((Transaction tx) async {
251
- DocumentSnapshot snapshot = await tx.get (labelRef);
252
- await tx.update (labelRef, < String , dynamic > {
253
- 'total_images' : snapshot.data['total_images' ] + 1
254
- });
255
- });
256
- }
233
+ uploadImageToStorage (filePath);
257
234
}
258
235
259
236
void onVideoRecordButtonPressed () {
@@ -375,6 +352,63 @@ class _CameraState extends State<Camera> {
375
352
logError (e.code, e.description);
376
353
showInSnackBar ('Error: ${e .code }\n ${e .description }' );
377
354
}
355
+
356
+ void uploadImageToStorage (String filePath) async {
357
+ final automlStorage = InheritedStorage .of (context).autoMlStorage;
358
+
359
+ if (mounted) {
360
+ setState (() {
361
+ imagePath = filePath;
362
+ });
363
+
364
+ final filename =
365
+ new DateTime .now ().millisecondsSinceEpoch.toString () + '.jpg' ;
366
+
367
+ // upload to storage and firestore
368
+ final StorageReference ref = automlStorage
369
+ .ref ()
370
+ .child ('datasets' )
371
+ .child (widget.dataset.name)
372
+ .child (widget.label)
373
+ .child (filename);
374
+
375
+ final File file = File (filePath).absolute;
376
+ // upload the file
377
+ StorageUploadTask uploadTask = ref.putFile (
378
+ file,
379
+ StorageMetadata (
380
+ contentType: 'image/jpeg' ,
381
+ customMetadata: < String , String > {'activity' : 'imgUpload' },
382
+ ),
383
+ );
384
+
385
+ final snapshot = await uploadTask.onComplete;
386
+ final downloadUrl = await snapshot.ref.getDownloadURL ();
387
+
388
+ Firestore .instance.collection ('images' ).add ({
389
+ 'parent_key' : widget.labelKey,
390
+ 'dataset_parent_key' : widget.dataset.id,
391
+ 'type' : toString (SampleType
392
+ .TRAIN ), // newly created images are categorized as training.
393
+ 'filename' : filename,
394
+ 'uploadPath' :
395
+ 'datasets/${widget .dataset .name }/${widget .label }/$filename ' ,
396
+ 'gcsURI' : downloadUrl,
397
+ 'uploader' : widget.userModel.user.email,
398
+ });
399
+
400
+ final labelRef =
401
+ Firestore .instance.collection ('labels' ).document (widget.labelKey);
402
+
403
+ // increment count for the label
404
+ await Firestore .instance.runTransaction ((Transaction tx) async {
405
+ DocumentSnapshot snapshot = await tx.get (labelRef);
406
+ await tx.update (labelRef, < String , dynamic > {
407
+ 'total_images' : snapshot.data['total_images' ] + 1
408
+ });
409
+ });
410
+ }
411
+ }
378
412
}
379
413
380
414
/// Widget to control start / stop of camera
0 commit comments