Open sourceFlutter package
flutter_bicubic_resize
The fastest image resize, crop and compress for Flutter - pure native C, identical results on every platform.
- MIT
- Android · iOS · macOS
- 3-4x faster
DocsOverview
Why the whole image pipeline runs in native C, how fast it is, and how to get your first resize working.
On this page8 sections
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)
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).
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.
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.
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)
);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.
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.
Where next
Let's make something together.
No overengineering. No wasted time. Just straight-up execution.
Or book a call with Eryk (opens the booking calendar)[email protected]


