feat: Reenable native imaging for all platforms

This commit is contained in:
Christian Kußowski 2026-02-20 17:28:19 +01:00
parent a9a8b39465
commit 162a594d80
No known key found for this signature in database
GPG key ID: E067ECD60F1A0652
5 changed files with 125 additions and 4 deletions

View file

@ -1,5 +1,6 @@
import 'dart:io';
import 'package:fluffychat/utils/custom_image_resizer.dart';
import 'package:flutter/foundation.dart';
import 'package:collection/collection.dart';
@ -122,6 +123,7 @@ abstract class ClientManager {
// To make room emotes work
'im.ponies.room_emotes',
},
customImageResizer: customImageResizer,
logLevel: kReleaseMode ? Level.warning : Level.verbose,
database: await flutterMatrixSdkDatabaseBuilder(clientName),
supportedLoginTypes: {

View file

@ -0,0 +1,101 @@
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
import 'package:matrix/matrix.dart';
import 'package:native_imaging/native_imaging.dart' as native;
(int, int) _scaleToBox(int width, int height, {required int boxSize}) {
final fit = applyBoxFit(
BoxFit.scaleDown,
Size(width.toDouble(), height.toDouble()),
Size(boxSize.toDouble(), boxSize.toDouble()),
).destination;
return (fit.width.round(), fit.height.round());
}
Future<MatrixImageFileResizedResponse?> customImageResizer(
MatrixImageFileResizeArguments arguments,
) async {
await native.init();
var imageBytes = arguments.bytes;
String? blurhash;
var originalWidth = 0;
var originalHeight = 0;
var width = 0;
var height = 0;
try {
// for the other platforms
final dartCodec = await instantiateImageCodec(arguments.bytes);
final frameCount = dartCodec.frameCount;
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,
);
width = originalWidth = dartFrame.image.width;
height = originalHeight = dartFrame.image.height;
var nativeImg = native.Image.fromRGBA(width, height, rgba);
dartFrame.image.dispose();
dartCodec.dispose();
if (arguments.calcBlurhash) {
// scale down image for blurhashing to speed it up
final (blurW, blurH) = _scaleToBox(width, height, boxSize: 100);
final blurhashImg = nativeImg.resample(
blurW,
blurH,
// nearest is unsupported...
native.Transform.bilinear,
);
blurhash = blurhashImg.toBlurhash(3, 3);
blurhashImg.free();
}
if (frameCount > 1) {
// Don't scale down animated images, since those would lose frames.
nativeImg.free();
} else {
final max = arguments.maxDimension;
if (width > max || height > max) {
(width, height) = _scaleToBox(width, height, boxSize: max);
final scaledImg = nativeImg.resample(
width,
height,
native.Transform.lanczos,
);
nativeImg.free();
nativeImg = scaledImg;
}
imageBytes = await nativeImg.toJpeg(75);
nativeImg.free();
}
} catch (e, s) {
Logs().e('Could not generate preview', e, s);
}
return MatrixImageFileResizedResponse(
bytes: imageBytes,
width: width,
height: height,
originalWidth: originalWidth,
originalHeight: originalHeight,
blurhash: blurhash,
);
}

View file

@ -984,10 +984,10 @@ packages:
dependency: transitive
description:
name: js
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted
version: "0.7.2"
version: "0.6.7"
json_annotation:
dependency: transitive
description:
@ -1156,6 +1156,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.0"
native_imaging:
dependency: "direct main"
description:
name: native_imaging
sha256: b910bd7c4fae77d9f91fb59840995e4fb91505b20a46ee1be88db3e4c4e219c4
url: "https://pub.dev"
source: hosted
version: "0.3.0"
native_toolchain_c:
dependency: transitive
description:

View file

@ -55,6 +55,7 @@ dependencies:
linkify: ^5.0.0
matrix: ^6.1.1
mime: ^2.0.0
native_imaging: ^0.3.0
opus_caf_converter_dart: ^1.0.1
package_info_plus: ^9.0.0
particles_network: ^1.9.3

View file

@ -1,5 +1,6 @@
#!/bin/sh -ve
# Compile Vodozemac for web
version=$(yq ".dependencies.flutter_vodozemac" < pubspec.yaml)
version=$(expr "$version" : '\^*\(.*\)')
git clone https://github.com/famedly/dart-vodozemac.git -b ${version} .vodozemac
@ -10,6 +11,14 @@ cd ..
rm -f ./assets/vodozemac/vodozemac_bindings_dart*
mv .vodozemac/dart/web/pkg/vodozemac_bindings_dart* ./assets/vodozemac/
rm -rf .vodozemac
flutter pub get
dart compile js ./web/native_executor.dart -o ./web/native_executor.js -m
# Download native_imaging for web:
version=$(yq ".dependencies.native_imaging" < pubspec.yaml)
version=$(expr "$version" : '\^*\(.*\)')
curl -L "https://github.com/famedly/dart_native_imaging/releases/download/v${version}/native_imaging.zip" > native_imaging.zip
unzip native_imaging.zip
mv js/* web/
rmdir js
rm native_imaging.zip