simple_native_image_compress
A simple native image compression library for Flutter written in rust using flutter_rust_bridge, image, cargokit, kamadak-exif and anyhow
Why?
- For some reason, image compression in Dart is slow. Even with isolate.
- There is no native libraries that supports WINDOWS & LINUX when it comes to image compression.
What does it do?
- If path for an image file is given, it will resize and return Jpeg/WebP image as Uint8List.
What it does not do
- Web Support with WASM. Since I use
Angular
for Web notFlutter
Prerequisite
- Rust
- Android NDK for Android
Setup
- Follow the instructions here and install
Rust
- If installed already
rustup update
Android
- Install rust tools for Android
cargo install cargo-ndk
rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android i686-linux-android
- Since
simple_native_image_compress
requires Android NDK, installAndroid NDK
viaAndroid Studio
and add ndkVersion inandroid/app/build.gradle
.
android {
// by default the project uses NDK version from flutter plugin.
ndkVersion flutter.ndkVersion
Apple
- Install rust tools for Apple
cargo install cargo-xcode
cargo install cargo-lipo
- If you are targeting iOS
rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
Supported Output Formats
- Jpeg
- WebP
- lossless only
- AVIF
- lossy only
speed
parameter can be given in the range 1-10, where 1 is the slowest and 10 is the fastest. Default is 10.
Sampling Filter Types
- 5 types of sampling filters are available and can be selected
- Nearest, // Nearest Neighbor
- Triangle, // Linear Filter (DEFAULT)
- CatmullRom, // Cubic Filter
- Gaussian, // Gaussian Filter
- Lanczos3, // Lanczos with window 3
- you can read more about sampling filters here image crate doc
Example
- Initialize Simple Native Image Compress in main function
Future<void> main() async {
await NativeImageCompress.init();
runApp(const MaterialApp(home: MyApp()));
}
- After initialization call static methods from ImageCompress class
"contain" will make the image fit into the given max width/height.
try{
final bytes = await ImageCompress.contain(
filePath: yourFilePath,
compressFormat: CompressFormat.avif,
speed: 3, // only for AVIF
quality: 90,
maxWidth: 512,
maxHeight: 512,
samplingFilter: FilterType.Lanczos3
);
} catch (e) {
print(e);
}
"fitWidth" will make the image fit into the given max width.
try{
final bytes = await ImageCompress.fitWidth(
filePath: yourFilePath,
compressFormat: CompressFormat.webP,
maxWidth: 512,
samplingFilter: FilterType.Lanczos3
);
} catch (e) {
print(e);
}
"fitHeight" will make the image fit into the given max height.
try{
final bytes = await ImageCompress.fitHeight(
filePath: yourFilePath,
compressFormat: CompressFormat.jpeg,
maxHeight: 512,
samplingFilter: FilterType.Lanczos3
);
} catch (e) {
print(e);
}
Default values
- Default value for width and/or height is
1024 px
- Default value for Jpeg/AVIF quality is
80
(For webP Quality does nothing) - Default value for samplingFilter is
FilterType.Triangle
- Default value for AVIF speed is
10