Flutter package
flutter_bicubic_resize
The fastest image resize, crop and compress for Flutter — pure native C, identical results on every platform.
flutter_bicubic_resize
Why the whole image pipeline runs in native C, how fast it is, and how to get your first resize working.
source: README.mdOverview
What it is
flutter_bicubic_resize runs the entire image pipeline — decode, crop, resize and encode — in native C, so a 4K photo becomes a 224×224 tensor in roughly 15–30 ms and the output is byte-identical on Android, iOS and macOS. It uses stb_image_resize2 with the Catmull-Rom spline, the same interpolation as OpenCV cv2.INTER_CUBIC and PIL Image.BICUBIC, which is why it is a good fit for ML preprocessing that must match a Python training pipeline.
Why identical output matters
Default platform APIs use different algorithms — Android is typically bilinear, iOS depends on context (Lanczos, bilinear, and others). This package runs the same C code on every platform, so the same input always produces the same pixels.
- 3-4x faster than other Flutter image libraries (pure native C pipeline)
- 100% native C performance (stb_image + stb_image_resize + stb_image_write)
- Identical results on iOS, Android and macOS
- Bicubic interpolation (Catmull-Rom, same as OpenCV INTER_CUBIC and PIL BICUBIC)
- RGB and RGBA support, JPEG and PNG with alpha preservation
- EXIF orientation support — rotates JPEG photos correctly
- Flexible crop system — anchor position, aspect ratio modes, custom ratios
- Edge handling modes — clamp, wrap, reflect, zero
- ML preprocessing — tensor normalization, HWC/CHW layouts, RGB/BGR ordering
- Async wrappers — every method has an *Async() variant using Isolate.run()
- File I/O and JPEG↔PNG format conversion without resizing
- Zero external Dart dependencies (only ffi)
Speed
Performance
The whole pipeline runs in native C — there is no Dart image-processing overhead. Operations are synchronous but extremely fast, and there is no memory copying between Dart and native code thanks to direct FFI.
- Resize a 4K JPEG to 224×224 in about 15–30 ms.
- Crop, resize and compress in a single pass.
- No memory copying between Dart and native (direct FFI).
How it works
Architecture
A single call walks the image through five native stages. No Dart image libraries are involved at any point.
- 1
Decode
stb_image decodes JPEG/PNG to raw pixels.
- 2
EXIF orientation
For JPEG: parses EXIF metadata and applies the correct rotation/flip (optional).
- 3
Crop
Extracts a region based on anchor position and aspect ratio mode.
- 4
Resize
stb_image_resize2 applies bicubic interpolation with the selected edge mode.
- 5
Encode
stb_image_write encodes back to JPEG/PNG.
Setup
Installation
Add the dependency to your pubspec.yaml:
dependencies:
flutter_bicubic_resize: ^1.7.0Or add it from the command line:
flutter pub add flutter_bicubic_resizeVersion
The current published version is 1.7.0. Older README snippets may still reference ^1.5.3 — use ^1.7.0 to get macOS support and the Swift Package Manager fixes.
First resize
Quickstart
Every operation is a static method on BicubicResizer. Pass the encoded bytes and the target size — the return value is the resized, re-encoded bytes.
import 'package:flutter_bicubic_resize/flutter_bicubic_resize.dart';
final resized = BicubicResizer.resizeJpeg(
jpegBytes: originalBytes,
outputWidth: 224,
outputHeight: 224,
quality: 95, // optional, default 95
);final resized = BicubicResizer.resizePng(
pngBytes: originalBytes,
outputWidth: 224,
outputHeight: 224,
compressionLevel: 6, // optional, 0-9 (default: 6)
);Support
Requirements & platforms
These constraints come from pubspec.yaml at v1.7.0 and are authoritative — the README lists an older, looser baseline.
- Dart SDK
>=3.5.0 <4.0.0, Flutter>=3.24.0. - Android SDK 21+, iOS 13.0+, macOS 10.15+.
- FFI plugin platforms: Android, iOS and macOS (macOS added in 1.7.0).
- Only one external dependency:
ffi: ^2.1.0.
Changelog
Recent highlights
1.7.0macOS support — fixes the missing bicubic_resize_rgb symbol lookup; Package.swift declares .macOS(10.15).
1.6.0Swift Package Manager support for iOS; Android compileSdk raised to 36; min Dart >=3.5.0, Flutter >=3.24.0.
1.5.4ImageFormatX extension — mimeType and fileExtension getters on ImageFormat.
1.5.0getImageInfo() + BicubicImageInfo, resizeFile()/resizeFileToFile(), JPEG↔PNG conversion, formatUnknown (-6) error code.
1.4.0Async wrappers via Isolate.run(), BicubicNativeError enum + BicubicResizeException, zero-std ArgumentError validation.
1.3.0resizeForModel() ML preprocessing (NormalizationType, ChannelOrder, TensorLayout) with pre-computed scale/offset.
Keep going
Where next
Let's make something together.
If you have any questions about a new project or other inquiries, feel free to contact us. We will get back to you as soon as possible.
