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

API reference

Every method with parameters and defaults: resize, crop, compress, tensors and image info.

source: doc/api.md

API

Image resizing

Every operation is a static method on BicubicResizer. The encoded-bytes methods (resizeJpeg, resizePng) decode, transform and re-encode in one native call; the raw-pixel methods work directly on interleaved byte buffers.

resizeJpeg

Resize JPEG image bytes using bicubic interpolation.

dart
static Uint8List resizeJpeg({
  required Uint8List jpegBytes,
  required int outputWidth,
  required int outputHeight,
  int quality = 95,
  BicubicFilter filter = BicubicFilter.catmullRom,
  EdgeMode edgeMode = EdgeMode.clamp,
  double crop = 1.0,
  CropAnchor cropAnchor = CropAnchor.center,
  CropAspectRatio cropAspectRatio = CropAspectRatio.square,
  double aspectRatioWidth = 1.0,
  double aspectRatioHeight = 1.0,
  bool applyExifOrientation = true,
})
ParameterTypeReq.DefaultDescription
jpegBytesUint8ListYesJPEG encoded image data
outputWidthintYesDesired output width in pixels
outputHeightintYesDesired output height in pixels
qualityintNo95JPEG output quality (1-100)
filterBicubicFilterNocatmullRomBicubic filter type
edgeModeEdgeModeNoclampHow to handle pixels outside image bounds
cropdoubleNo1.0Crop factor (0.0-1.0). 1.0 = no crop
cropAnchorCropAnchorNocenterPosition to anchor the crop
cropAspectRatioCropAspectRatioNosquareAspect ratio mode for crop
aspectRatioWidthdoubleNo1.0Custom aspect ratio width (only with CropAspectRatio.custom)
aspectRatioHeightdoubleNo1.0Custom aspect ratio height (only with CropAspectRatio.custom)
applyExifOrientationboolNotrueWhether to apply EXIF orientation

Returns: Uint8List — resized JPEG encoded data.

dart
// Crop from the top-left corner, keeping original aspect ratio
final cropped = BicubicResizer.resizeJpeg(
  jpegBytes: originalBytes,
  outputWidth: 800,
  outputHeight: 600,
  crop: 0.8,
  cropAnchor: CropAnchor.topLeft,
  cropAspectRatio: CropAspectRatio.original,
);

resizePng

Resize PNG image bytes using bicubic interpolation. Preserves the alpha channel if present.

dart
static Uint8List resizePng({
  required Uint8List pngBytes,
  required int outputWidth,
  required int outputHeight,
  BicubicFilter filter = BicubicFilter.catmullRom,
  EdgeMode edgeMode = EdgeMode.clamp,
  double crop = 1.0,
  CropAnchor cropAnchor = CropAnchor.center,
  CropAspectRatio cropAspectRatio = CropAspectRatio.square,
  double aspectRatioWidth = 1.0,
  double aspectRatioHeight = 1.0,
  int compressionLevel = 6,
})

The filter, edgeMode, crop, cropAnchor, cropAspectRatio, aspectRatioWidth and aspectRatioHeight parameters behave exactly as in resizeJpeg. PNG adds compressionLevel and has no quality or applyExifOrientation.

ParameterTypeReq.DefaultDescription
pngBytesUint8ListYesPNG encoded image data
compressionLevelintNo6PNG compression level (0-9, 0=none, 9=max)

Returns: Uint8List — resized PNG encoded data.

dart
// Simple resize with maximum compression
final resized = BicubicResizer.resizePng(
  pngBytes: originalBytes,
  outputWidth: 512,
  outputHeight: 512,
  compressionLevel: 9,
);

resize

Generic resize with automatic format detection — returns the resized image in the same format as the input.

dart
static Uint8List resize({
  required Uint8List bytes,
  required int outputWidth,
  required int outputHeight,
  int quality = 95,
  int compressionLevel = 6,
  BicubicFilter filter = BicubicFilter.catmullRom,
  EdgeMode edgeMode = EdgeMode.clamp,
  double crop = 1.0,
  CropAnchor cropAnchor = CropAnchor.center,
  CropAspectRatio cropAspectRatio = CropAspectRatio.square,
  double aspectRatioWidth = 1.0,
  double aspectRatioHeight = 1.0,
  bool applyExifOrientation = true,
})

Returns: Uint8List — resized image in the same format as input.

Throws: UnsupportedImageFormatException if the format is not JPEG or PNG.

resizeRgb / resizeRgba

Resize raw RGB (3 bytes per pixel) or RGBA (4 bytes per pixel) buffers using bicubic interpolation. resizeRgba has an identical signature operating on 4-byte RGBA pixel data.

dart
static Uint8List resizeRgb({
  required Uint8List input,
  required int inputWidth,
  required int inputHeight,
  required int outputWidth,
  required int outputHeight,
  BicubicFilter filter = BicubicFilter.catmullRom,
  EdgeMode edgeMode = EdgeMode.clamp,
  double crop = 1.0,
  CropAnchor cropAnchor = CropAnchor.center,
  CropAspectRatio cropAspectRatio = CropAspectRatio.square,
  double aspectRatioWidth = 1.0,
  double aspectRatioHeight = 1.0,
})
ParameterTypeReq.DefaultDescription
inputUint8ListYesRaw RGB pixel data (3 bytes per pixel)
inputWidthintYesWidth of input image in pixels
inputHeightintYesHeight of input image in pixels
outputWidthintYesDesired output width
outputHeightintYesDesired output height

The crop, filter and edge parameters match resizeJpeg.

Returns: Uint8List — resized raw pixel data.

Throws: ArgumentError if the input size does not match inputWidth * inputHeight * 3 (or * 4 for RGBA).

API

ML tensor output

resizeForModel

Resize and normalize an image for ML model inference. Returns a Float32List ready for TensorFlow Lite, PyTorch or other ML frameworks.

dart
static Float32List resizeForModel({
  required Uint8List bytes,
  required int outputWidth,
  required int outputHeight,
  NormalizationType normalization = NormalizationType.none,
  ChannelOrder channelOrder = ChannelOrder.rgb,
  TensorLayout layout = TensorLayout.hwc,
  BicubicFilter filter = BicubicFilter.catmullRom,
  EdgeMode edgeMode = EdgeMode.clamp,
  double crop = 1.0,
  CropAnchor cropAnchor = CropAnchor.center,
  CropAspectRatio cropAspectRatio = CropAspectRatio.square,
  double aspectRatioWidth = 1.0,
  double aspectRatioHeight = 1.0,
  bool applyExifOrientation = true,
  // Custom normalization parameters (only with NormalizationType.custom)
  double meanR = 0.0,
  double meanG = 0.0,
  double meanB = 0.0,
  double stdR = 1.0,
  double stdG = 1.0,
  double stdB = 1.0,
})
ParameterTypeReq.DefaultDescription
bytesUint8ListYesImage data (JPEG or PNG)
outputWidthintYesDesired output width (e.g. 224)
outputHeightintYesDesired output height (e.g. 224)
normalizationNormalizationTypeNononeType of normalization to apply
channelOrderChannelOrderNorgbRGB or BGR channel ordering
layoutTensorLayoutNohwcTensor layout (HWC or CHW)
meanR / meanG / meanBdoubleNo0.0Custom mean values per channel (only with NormalizationType.custom)
stdR / stdG / stdBdoubleNo1.0Custom std values per channel (only with NormalizationType.custom)

The crop, filter, edge and applyExifOrientation parameters match resize. See the Advanced page for normalization presets and layout details.

Returns: Float32List — tensor data ready for ML model input.

API

File I/O

resizeFile

Read the file at inputPath, auto-detect its format, resize, and return the bytes. Takes the same options as resize plus a required inputPath string.

dart
static Uint8List resizeFile({
  required String inputPath,
  required int outputWidth,
  required int outputHeight,
  int quality = 95,
  int compressionLevel = 6,
  BicubicFilter filter = BicubicFilter.catmullRom,
  EdgeMode edgeMode = EdgeMode.clamp,
  double crop = 1.0,
  CropAnchor cropAnchor = CropAnchor.center,
  CropAspectRatio cropAspectRatio = CropAspectRatio.square,
  double aspectRatioWidth = 1.0,
  double aspectRatioHeight = 1.0,
  bool applyExifOrientation = true,
})

Returns: Uint8List — resized image in the same format as input.

resizeFileToFile

Resize an image file and write it straight to outputPath. Returns void.

dart
static void resizeFileToFile({
  required String inputPath,
  required String outputPath,
  required int outputWidth,
  required int outputHeight,
  // ... same options as resizeFile
})
dart
// Read file, resize, get bytes
final resized = BicubicResizer.resizeFile(
  inputPath: '/path/to/photo.jpg',
  outputWidth: 800,
  outputHeight: 600,
);

// Read file, resize, save to output file
BicubicResizer.resizeFileToFile(
  inputPath: '/path/to/photo.jpg',
  outputPath: '/path/to/thumbnail.jpg',
  outputWidth: 200,
  outputHeight: 200,
);

API

Format utilities

detectFormat

Detect the image format from raw bytes.

dart
static ImageFormat? detectFormat(Uint8List bytes)

Returns: ImageFormat.jpeg, ImageFormat.png, or null if unsupported.

jpegToPng

Convert JPEG to PNG without resizing. Decodes the JPEG, optionally applies EXIF orientation, and encodes as PNG (compressionLevel default 6, applyExifOrientation default true).

dart
static Uint8List jpegToPng({
  required Uint8List jpegBytes,
  int compressionLevel = 6,
  bool applyExifOrientation = true,
})

Returns: Uint8List — PNG encoded data.

pngToJpeg

Convert PNG to JPEG without resizing. Decodes the PNG, drops the alpha channel, and encodes as JPEG (quality default 95).

dart
static Uint8List pngToJpeg({
  required Uint8List pngBytes,
  int quality = 95,
})

Returns: Uint8List — JPEG encoded data. The alpha channel is discarded during conversion.

convertFormat

Convert between JPEG and PNG with auto-detection. If the input already matches the target format, the original bytes are returned unchanged.

dart
static Uint8List convertFormat({
  required Uint8List bytes,
  required ImageFormat targetFormat,
  int quality = 95,
  int compressionLevel = 6,
  bool applyExifOrientation = true,
})
ParameterTypeReq.DefaultDescription
bytesUint8ListYesImage data (JPEG or PNG)
targetFormatImageFormatYesDesired output format
qualityintNo95JPEG quality (used when target is JPEG)
compressionLevelintNo6PNG compression (used when target is PNG)
applyExifOrientationboolNotrueEXIF orientation (JPEG input only)

Returns: Uint8List — converted image data.

Throws: UnsupportedImageFormatException if the input format is not JPEG or PNG.

dart
// Auto-detect and convert to PNG
final pngBytes = BicubicResizer.convertFormat(
  bytes: imageBytes,
  targetFormat: ImageFormat.png,
);

API

Image info

getImageInfo

Read dimensions, format, channels and EXIF orientation without decoding pixel data. Uses stbi_info_from_memory() internally, so it is very fast and lightweight.

dart
static BicubicImageInfo getImageInfo(Uint8List bytes)

Returns: BicubicImageInfo with width, height, channels, format and EXIF orientation.

Throws: UnsupportedImageFormatException if the format is not JPEG or PNG.

BicubicImageInfodart
class BicubicImageInfo {
  final int width;            // Image width (before EXIF)
  final int height;           // Image height (before EXIF)
  final int channels;         // Color channels (1=gray, 3=RGB, 4=RGBA)
  final ImageFormat format;   // Detected format (jpeg or png)
  final int exifOrientation;  // EXIF orientation (1-8, JPEG only)

  int get orientedWidth;      // Width after EXIF rotation
  int get orientedHeight;     // Height after EXIF rotation
}

For EXIF orientations 1-4, orientedWidth == width and orientedHeight == height. For orientations 5-8 (90°/270° rotations), width and height are swapped.

dart
final info = BicubicResizer.getImageInfo(imageBytes);
print('${info.width}x${info.height}');               // Raw dimensions
print('${info.orientedWidth}x${info.orientedHeight}'); // After EXIF rotation
print('Format: ${info.format}');                       // ImageFormat.jpeg or .png
print('Channels: ${info.channels}');                   // 1, 3, or 4
print('EXIF: ${info.exifOrientation}');                // 1-8

API

Async methods

Every public resize method has an *Async() counterpart that runs in a separate isolate via Isolate.run(), keeping the UI thread free. Each async method accepts the same parameters as its sync version.

Sync methodAsync methodReturn type
resizeJpeg()resizeJpegAsync()Future<Uint8List>
resizePng()resizePngAsync()Future<Uint8List>
resizeRgb()resizeRgbAsync()Future<Uint8List>
resizeRgba()resizeRgbaAsync()Future<Uint8List>
resize()resizeAsync()Future<Uint8List>
resizeForModel()resizeForModelAsync()Future<Float32List>
getImageInfo()getImageInfoAsync()Future<BicubicImageInfo>
resizeFile()resizeFileAsync()Future<Uint8List>
resizeFileToFile()resizeFileToFileAsync()Future<void>
jpegToPng()jpegToPngAsync()Future<Uint8List>
pngToJpeg()pngToJpegAsync()Future<Uint8List>
convertFormat()convertFormatAsync()Future<Uint8List>
dart
// Non-blocking JPEG resize
final resized = await BicubicResizer.resizeJpegAsync(
  jpegBytes: originalBytes,
  outputWidth: 224,
  outputHeight: 224,
);

API

Enums

BicubicFilter

dart
enum BicubicFilter {
  catmullRom,   // value: 0
  cubicBSpline, // value: 1
  mitchell,     // value: 2
}
FilterDescriptionUse case
catmullRomCatmull-Rom spline. Same as OpenCV INTER_CUBIC and PIL BICUBIC.Default. Best for ML preprocessing. Produces sharp results.
cubicBSplineCubic B-Spline interpolation.Smoother, more blurry results. Good for artistic effects.
mitchellMitchell-Netravali filter.Balanced between sharp and smooth. Good general-purpose filter.

EdgeMode

dart
enum EdgeMode {
  clamp,   // value: 0
  wrap,    // value: 1
  reflect, // value: 2
  zero,    // value: 3
}
ModeDescriptionVisual effect
clampRepeat edge pixels[A B C D D D] — extends the last pixel
wrapWrap around (tile)[A B C D A B] — image repeats
reflectMirror reflection[A B C D C B] — mirror at the edge
zeroBlack / transparent[A B C D 0 0] — black pixels outside

CropAnchor

Nine positions to anchor the crop region within the source image.

dart
enum CropAnchor {
  center,       // value: 0
  topLeft,      // value: 1
  topCenter,    // value: 2
  topRight,     // value: 3
  centerLeft,   // value: 4
  centerRight,  // value: 5
  bottomLeft,   // value: 6
  bottomCenter, // value: 7
  bottomRight,  // value: 8
}

CropAspectRatio

dart
enum CropAspectRatio {
  square,   // value: 0
  original, // value: 1
  custom,   // value: 2
}
ModeDescription
squareDefault. Crops to the largest square that fits (1:1 ratio).
originalKeeps the original image aspect ratio.
customUses aspectRatioWidth and aspectRatioHeight parameters.

ImageFormat & ImageFormatX

The supported formats, plus the ImageFormatX extension (added in 1.5.4) exposing mimeType and fileExtension getters.

dart
enum ImageFormat {
  jpeg,
  png,
}

// Since 1.5.4
extension ImageFormatX on ImageFormat {
  String get mimeType;      // MIME type for the format
  String get fileExtension; // file extension for the format
}

NormalizationType

Tensor normalization for resizeForModel. Formulas and presets are covered on the Advanced page.

dart
enum NormalizationType {
  none,      // No normalization (default) - raw pixel values 0-255 as float
  simple,    // pixel / 255.0 -> [0, 1]
  centered,  // (pixel / 127.5) - 1.0 -> [-1, 1]
  imageNet,  // ImageNet mean/std normalization
  custom,    // User-defined mean/std values
}

ChannelOrder & TensorLayout

dart
enum ChannelOrder {
  rgb,  // Red, Green, Blue (default) - TensorFlow, most models
  bgr,  // Blue, Green, Red - OpenCV, some PyTorch models
}
dart
enum TensorLayout {
  hwc,  // Height, Width, Channels (default) - TensorFlow/TFLite
  chw,  // Channels, Height, Width - PyTorch
}

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