From 7013aef2861b080710efb17bb4ed4ce019d92a8c Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Thu, 14 Apr 2022 10:37:56 +0200 Subject: [PATCH] feat: Faster image resizing --- lib/utils/client_manager.dart | 2 + lib/utils/custom_image_resizer.dart | 63 +++++++++++++++++++++++++++++ pubspec.lock | 9 +++++ pubspec.yaml | 2 + 4 files changed, 76 insertions(+) create mode 100644 lib/utils/custom_image_resizer.dart diff --git a/lib/utils/client_manager.dart b/lib/utils/client_manager.dart index 1e9e0cf9..5dc0c5ac 100644 --- a/lib/utils/client_manager.dart +++ b/lib/utils/client_manager.dart @@ -7,6 +7,7 @@ import 'package:matrix/encryption/utils/key_verification.dart'; import 'package:matrix/matrix.dart'; import 'package:path_provider/path_provider.dart'; +import 'package:fluffychat/utils/custom_image_resizer.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'famedlysdk_store.dart'; import 'matrix_sdk_extensions.dart/fluffybox_database.dart'; @@ -99,5 +100,6 @@ abstract class ClientManager { AuthenticationTypes.sso }, compute: compute, + customImageResizer: PlatformInfos.isMobile ? customImageResizer : null, ); } diff --git a/lib/utils/custom_image_resizer.dart b/lib/utils/custom_image_resizer.dart new file mode 100644 index 00000000..677d7e8e --- /dev/null +++ b/lib/utils/custom_image_resizer.dart @@ -0,0 +1,63 @@ +import 'dart:typed_data'; +import 'dart:ui'; + +import 'package:matrix/matrix.dart'; +import 'package:native_imaging/native_imaging.dart' as native; + +Future customImageResizer( + MatrixImageFileResizeArguments arguments) async { + await native.init(); + late native.Image nativeImg; + + try { + nativeImg = await native.Image.loadEncoded(arguments.bytes); // load on web + } on UnsupportedError { + try { + // for the other platforms + final dartCodec = await instantiateImageCodec(arguments.bytes); + final dartFrame = await dartCodec.getNextFrame(); + final rgbaData = await dartFrame.image.toByteData(); + if (rgbaData == null) { + return null; + } + final rgba = Uint8List.view( + rgbaData.buffer, rgbaData.offsetInBytes, rgbaData.lengthInBytes); + + final width = dartFrame.image.width; + final height = dartFrame.image.height; + + dartFrame.image.dispose(); + dartCodec.dispose(); + + nativeImg = native.Image.fromRGBA(width, height, rgba); + } catch (e, s) { + Logs().e("Could not generate preview", e, s); + rethrow; + } + } + + final width = nativeImg.width; + final height = nativeImg.height; + + final max = arguments.maxDimension; + if (width > max || height > max) { + var w = max, h = max; + if (width > height) { + h = max * height ~/ width; + } else { + w = max * width ~/ height; + } + + final scaledImg = nativeImg.resample(w, h, native.Transform.lanczos); + nativeImg.free(); + nativeImg = scaledImg; + } + final jpegBytes = await nativeImg.toJpeg(75); + + return MatrixImageFileResizedResponse( + bytes: jpegBytes, + width: nativeImg.width, + height: nativeImg.height, + blurhash: arguments.calcBlurhash ? nativeImg.toBlurhash(3, 3) : null, + ); +} diff --git a/pubspec.lock b/pubspec.lock index 37036074..cba62a45 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1047,6 +1047,15 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" + native_imaging: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: "8c6a5afe2c965b79b5959bb4b49c4aad020cb980" + url: "https://gitlab.com/famedly/company/frontend/libraries/native_imaging.git" + source: git + version: "0.1.0" nested: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 8e2e8750..f4a9a10b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -60,6 +60,8 @@ dependencies: lottie: ^1.2.2 matrix: ^0.8.18 matrix_link_text: ^1.0.2 + native_imaging: + git: https://gitlab.com/famedly/company/frontend/libraries/native_imaging.git open_noti_settings: ^0.4.0 package_info_plus: ^1.3.0 path_provider: ^2.0.9