[mob][photos] Use thumbnails for generating face crop in suggestions
This commit is contained in:
parent
a80c9dd589
commit
29b9bee1be
3 changed files with 32 additions and 14 deletions
|
@ -261,21 +261,21 @@ class _PersonClustersState extends State<PersonReviewClusterSuggestion> {
|
|||
],
|
||||
);
|
||||
// Precompute face thumbnails for next suggestions, in case there are
|
||||
const precompute = 6;
|
||||
const maxComputations = 10;
|
||||
const precomputeSuggestions = 6;
|
||||
const maxPrecomputations = 10;
|
||||
int compCount = 0;
|
||||
|
||||
if (allSuggestions.length > currentSuggestionIndex + 1) {
|
||||
for (final suggestion in allSuggestions.sublist(
|
||||
currentSuggestionIndex + 1,
|
||||
min(allSuggestions.length, currentSuggestionIndex + precompute),
|
||||
min(allSuggestions.length, currentSuggestionIndex + precomputeSuggestions),
|
||||
)) {
|
||||
final files = suggestion.filesInCluster;
|
||||
final clusterID = suggestion.clusterIDToMerge;
|
||||
for (final file in files.sublist(0, min(files.length, 8))) {
|
||||
unawaited(PersonFaceWidget.precomputeNextFaceCrops(file, clusterID));
|
||||
compCount++;
|
||||
if (compCount >= maxComputations) {
|
||||
if (compCount >= maxPrecomputations) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -300,6 +300,7 @@ class _PersonClustersState extends State<PersonReviewClusterSuggestion> {
|
|||
child: PersonFaceWidget(
|
||||
files[start + index],
|
||||
clusterID: cluserId,
|
||||
useFullFile: false,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -19,6 +19,7 @@ class PersonFaceWidget extends StatelessWidget {
|
|||
final EnteFile file;
|
||||
final String? personId;
|
||||
final int? clusterID;
|
||||
final bool useFullFile;
|
||||
|
||||
// PersonFaceWidget constructor checks that both personId and clusterID are not null
|
||||
// and that the file is not null
|
||||
|
@ -26,6 +27,7 @@ class PersonFaceWidget extends StatelessWidget {
|
|||
this.file, {
|
||||
this.personId,
|
||||
this.clusterID,
|
||||
this.useFullFile = true,
|
||||
Key? key,
|
||||
}) : assert(
|
||||
personId != null || clusterID != null,
|
||||
|
@ -176,6 +178,13 @@ class PersonFaceWidget extends StatelessWidget {
|
|||
faceCropCache.put(face.faceID, data);
|
||||
return data;
|
||||
}
|
||||
if (!useFullFile) {
|
||||
final Uint8List? cachedFaceThumbnail =
|
||||
faceCropThumbnailCache.get(face.faceID);
|
||||
if (cachedFaceThumbnail != null) {
|
||||
return cachedFaceThumbnail;
|
||||
}
|
||||
}
|
||||
EnteFile? fileForFaceCrop = file;
|
||||
if (face.fileID != file.uploadedFileID!) {
|
||||
fileForFaceCrop =
|
||||
|
@ -191,12 +200,17 @@ class PersonFaceWidget extends StatelessWidget {
|
|||
{
|
||||
face.faceID: face.detection.box,
|
||||
},
|
||||
useFullFile: useFullFile,
|
||||
),
|
||||
);
|
||||
final Uint8List? computedCrop = result?[face.faceID];
|
||||
if (computedCrop != null) {
|
||||
faceCropCache.put(face.faceID, computedCrop);
|
||||
faceCropCacheFile.writeAsBytes(computedCrop).ignore();
|
||||
if (useFullFile) {
|
||||
faceCropCache.put(face.faceID, computedCrop);
|
||||
faceCropCacheFile.writeAsBytes(computedCrop).ignore();
|
||||
} else {
|
||||
faceCropThumbnailCache.put(face.faceID, computedCrop);
|
||||
}
|
||||
}
|
||||
return computedCrop;
|
||||
} catch (e, s) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import "dart:io";
|
||||
import "dart:io" show File;
|
||||
|
||||
import "package:flutter/foundation.dart";
|
||||
import "package:photos/core/cache/lru_map.dart";
|
||||
|
@ -12,24 +12,27 @@ import "package:photos/utils/thumbnail_util.dart";
|
|||
import "package:pool/pool.dart";
|
||||
|
||||
final LRUMap<String, Uint8List?> faceCropCache = LRUMap(1000);
|
||||
final LRUMap<String, Uint8List?> faceCropThumbnailCache = LRUMap(1000);
|
||||
final pool = Pool(10, timeout: const Duration(seconds: 15));
|
||||
Future<Map<String, Uint8List>?> getFaceCrops(
|
||||
EnteFile file,
|
||||
Map<String, FaceBox> faceBoxeMap,
|
||||
Map<String, FaceBox> faceBoxeMap, {
|
||||
bool useFullFile = true,
|
||||
}
|
||||
) async {
|
||||
late String? imagePath;
|
||||
if (file.fileType != FileType.video) {
|
||||
if (useFullFile && file.fileType != FileType.video) {
|
||||
final File? ioFile = await getFile(file);
|
||||
if (ioFile == null) {
|
||||
return null;
|
||||
}
|
||||
imagePath = ioFile.path;
|
||||
} else {
|
||||
final thumbnail = await getThumbnailForUploadedFile(file);
|
||||
if (thumbnail == null) {
|
||||
return null;
|
||||
}
|
||||
imagePath = thumbnail.path;
|
||||
final thumbnail = await getThumbnailForUploadedFile(file);
|
||||
if (thumbnail == null) {
|
||||
return null;
|
||||
}
|
||||
imagePath = thumbnail.path;
|
||||
}
|
||||
final List<String> faceIds = [];
|
||||
final List<FaceBox> faceBoxes = [];
|
||||
|
|
Loading…
Add table
Reference in a new issue