From 7bbbeceab5fa5920ba6b6b8dd7219201a0d26eb4 Mon Sep 17 00:00:00 2001 From: laurenspriem Date: Tue, 24 Jun 2025 14:05:06 +0530 Subject: [PATCH] Compress face thumbnail in regular isolate --- .../face_thumbnail_generator.dart | 18 +++++++++++++++++- mobile/lib/utils/image_ml_util.dart | 16 ++++++---------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/mobile/lib/services/machine_learning/face_thumbnail_generator.dart b/mobile/lib/services/machine_learning/face_thumbnail_generator.dart index d98fe63793..6b2599bbf1 100644 --- a/mobile/lib/services/machine_learning/face_thumbnail_generator.dart +++ b/mobile/lib/services/machine_learning/face_thumbnail_generator.dart @@ -1,12 +1,15 @@ import 'dart:async'; import 'dart:typed_data' show Uint8List; +import "package:computer/computer.dart"; import "package:logging/logging.dart"; import "package:photos/models/ml/face/box.dart"; import "package:photos/services/isolate_functions.dart"; import "package:photos/services/isolate_service.dart"; import "package:photos/utils/image_ml_util.dart"; +final Computer _computer = Computer.shared(); + class FaceThumbnailGenerator extends SuperIsolate { @override Logger get logger => _logger; @@ -36,12 +39,25 @@ class FaceThumbnailGenerator extends SuperIsolate { ) async { final List> faceBoxesJson = faceBoxes.map((box) => box.toJson()).toList(); - return await runInIsolate( + final List faces = await runInIsolate( IsolateOperation.generateFaceThumbnails, { 'imagePath': imagePath, 'faceBoxesList': faceBoxesJson, }, ).then((value) => value.cast()); + final compressedFaces = >[]; + for (final face in faces) { + if (!shouldCompressFaceThumbnail(face)) { + compressedFaces.add(Future.value(face)); + } else { + final compressedFace = _computer.compute( + compressFaceThumbnail, + param: {'pngBytes': face}, + ); + compressedFaces.add(compressedFace); + } + } + return await Future.wait(compressedFaces); } } diff --git a/mobile/lib/utils/image_ml_util.dart b/mobile/lib/utils/image_ml_util.dart index 7f2f493058..c4101859c4 100644 --- a/mobile/lib/utils/image_ml_util.dart +++ b/mobile/lib/utils/image_ml_util.dart @@ -541,19 +541,15 @@ Future _cropAndEncodeCanvas( width: width, height: height, ); - final pngBytes = await _encodeImageToPng(croppedImage); - return await _compressFaceThumbnailIfNeeded(pngBytes); + return await _encodeImageToPng(croppedImage); } -/// Compresses the face thumbnail if it's too large in size. -/// -/// Returns compressed bytes if the original size exceeds [_maxFaceThumbnailSizeBytes], -/// otherwise returns the original bytes. -Future _compressFaceThumbnailIfNeeded(Uint8List pngBytes) async { - if (pngBytes.length <= _maxFaceThumbnailSizeBytes) { - return pngBytes; - } +bool shouldCompressFaceThumbnail(Uint8List pngBytes) { + return pngBytes.length > _maxFaceThumbnailSizeBytes; +} +Future compressFaceThumbnail(Map args) async { + final pngBytes = args['pngBytes'] as Uint8List; try { final compressedBytes = await FlutterImageCompress.compressWithList( pngBytes,