Open Source

Flutter package

flutter_bicubic_resize

The fastest image resize, crop and compress for Flutter — pure native C, identical results on every platform.

v1.8.223.5k / month45 likesMITAndroid · iOS · macOS3-4x faster

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.md

Overview

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. 1

    Decode

    stb_image decodes JPEG/PNG to raw pixels.

  2. 2

    EXIF orientation

    For JPEG: parses EXIF metadata and applies the correct rotation/flip (optional).

  3. 3

    Crop

    Extracts a region based on anchor position and aspect ratio mode.

  4. 4

    Resize

    stb_image_resize2 applies bicubic interpolation with the selected edge mode.

  5. 5

    Encode

    stb_image_write encodes back to JPEG/PNG.

Setup

Installation

Add the dependency to your pubspec.yaml:

pubspec.yamlyaml
dependencies:
  flutter_bicubic_resize: ^1.7.0

Or add it from the command line:

bash
flutter pub add flutter_bicubic_resize

Version

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.

Resize a JPEGdart
import 'package:flutter_bicubic_resize/flutter_bicubic_resize.dart';

final resized = BicubicResizer.resizeJpeg(
  jpegBytes: originalBytes,
  outputWidth: 224,
  outputHeight: 224,
  quality: 95, // optional, default 95
);
Resize a PNGdart
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.0

macOS support — fixes the missing bicubic_resize_rgb symbol lookup; Package.swift declares .macOS(10.15).

1.6.0

Swift Package Manager support for iOS; Android compileSdk raised to 36; min Dart >=3.5.0, Flutter >=3.24.0.

1.5.4

ImageFormatX extension — mimeType and fileExtension getters on ImageFormat.

1.5.0

getImageInfo() + BicubicImageInfo, resizeFile()/resizeFileToFile(), JPEG↔PNG conversion, formatUnknown (-6) error code.

1.4.0

Async wrappers via Isolate.run(), BicubicNativeError enum + BicubicResizeException, zero-std ArgumentError validation.

1.3.0

resizeForModel() 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.

Codigee
We are using cookies. Learn more