Flutter package
flutter_bicubic_resize
The fastest image resize, crop and compress for Flutter — pure native C, identical results on every platform.
API reference
Every method with parameters and defaults: resize, crop, compress, tensors and image info.
source: doc/api.mdAPI
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.
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,
})| Parameter | Type | Req. | Default | Description |
|---|---|---|---|---|
| jpegBytes | Uint8List | Yes | — | JPEG encoded image data |
| outputWidth | int | Yes | — | Desired output width in pixels |
| outputHeight | int | Yes | — | Desired output height in pixels |
| quality | int | No | 95 | JPEG output quality (1-100) |
| filter | BicubicFilter | No | catmullRom | Bicubic filter type |
| edgeMode | EdgeMode | No | clamp | How to handle pixels outside image bounds |
| crop | double | No | 1.0 | Crop factor (0.0-1.0). 1.0 = no crop |
| cropAnchor | CropAnchor | No | center | Position to anchor the crop |
| cropAspectRatio | CropAspectRatio | No | square | Aspect ratio mode for crop |
| aspectRatioWidth | double | No | 1.0 | Custom aspect ratio width (only with CropAspectRatio.custom) |
| aspectRatioHeight | double | No | 1.0 | Custom aspect ratio height (only with CropAspectRatio.custom) |
| applyExifOrientation | bool | No | true | Whether to apply EXIF orientation |
Returns: Uint8List — resized JPEG encoded data.
// 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.
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.
| Parameter | Type | Req. | Default | Description |
|---|---|---|---|---|
| pngBytes | Uint8List | Yes | — | PNG encoded image data |
| compressionLevel | int | No | 6 | PNG compression level (0-9, 0=none, 9=max) |
Returns: Uint8List — resized PNG encoded data.
// 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.
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.
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,
})| Parameter | Type | Req. | Default | Description |
|---|---|---|---|---|
| input | Uint8List | Yes | — | Raw RGB pixel data (3 bytes per pixel) |
| inputWidth | int | Yes | — | Width of input image in pixels |
| inputHeight | int | Yes | — | Height of input image in pixels |
| outputWidth | int | Yes | — | Desired output width |
| outputHeight | int | Yes | — | Desired 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.
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,
})| Parameter | Type | Req. | Default | Description |
|---|---|---|---|---|
| bytes | Uint8List | Yes | — | Image data (JPEG or PNG) |
| outputWidth | int | Yes | — | Desired output width (e.g. 224) |
| outputHeight | int | Yes | — | Desired output height (e.g. 224) |
| normalization | NormalizationType | No | none | Type of normalization to apply |
| channelOrder | ChannelOrder | No | rgb | RGB or BGR channel ordering |
| layout | TensorLayout | No | hwc | Tensor layout (HWC or CHW) |
| meanR / meanG / meanB | double | No | 0.0 | Custom mean values per channel (only with NormalizationType.custom) |
| stdR / stdG / stdB | double | No | 1.0 | Custom 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.
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.
static void resizeFileToFile({
required String inputPath,
required String outputPath,
required int outputWidth,
required int outputHeight,
// ... same options as resizeFile
})// 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.
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).
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).
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.
static Uint8List convertFormat({
required Uint8List bytes,
required ImageFormat targetFormat,
int quality = 95,
int compressionLevel = 6,
bool applyExifOrientation = true,
})| Parameter | Type | Req. | Default | Description |
|---|---|---|---|---|
| bytes | Uint8List | Yes | — | Image data (JPEG or PNG) |
| targetFormat | ImageFormat | Yes | — | Desired output format |
| quality | int | No | 95 | JPEG quality (used when target is JPEG) |
| compressionLevel | int | No | 6 | PNG compression (used when target is PNG) |
| applyExifOrientation | bool | No | true | EXIF orientation (JPEG input only) |
Returns: Uint8List — converted image data.
Throws: UnsupportedImageFormatException if the input format is not JPEG or PNG.
// 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.
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.
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.
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-8API
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 method | Async method | Return 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> |
// Non-blocking JPEG resize
final resized = await BicubicResizer.resizeJpegAsync(
jpegBytes: originalBytes,
outputWidth: 224,
outputHeight: 224,
);API
Enums
BicubicFilter
enum BicubicFilter {
catmullRom, // value: 0
cubicBSpline, // value: 1
mitchell, // value: 2
}| Filter | Description | Use case |
|---|---|---|
| catmullRom | Catmull-Rom spline. Same as OpenCV INTER_CUBIC and PIL BICUBIC. | Default. Best for ML preprocessing. Produces sharp results. |
| cubicBSpline | Cubic B-Spline interpolation. | Smoother, more blurry results. Good for artistic effects. |
| mitchell | Mitchell-Netravali filter. | Balanced between sharp and smooth. Good general-purpose filter. |
EdgeMode
enum EdgeMode {
clamp, // value: 0
wrap, // value: 1
reflect, // value: 2
zero, // value: 3
}| Mode | Description | Visual effect |
|---|---|---|
| clamp | Repeat edge pixels | [A B C D D D] — extends the last pixel |
| wrap | Wrap around (tile) | [A B C D A B] — image repeats |
| reflect | Mirror reflection | [A B C D C B] — mirror at the edge |
| zero | Black / transparent | [A B C D 0 0] — black pixels outside |
CropAnchor
Nine positions to anchor the crop region within the source image.
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
enum CropAspectRatio {
square, // value: 0
original, // value: 1
custom, // value: 2
}| Mode | Description |
|---|---|
| square | Default. Crops to the largest square that fits (1:1 ratio). |
| original | Keeps the original image aspect ratio. |
| custom | Uses aspectRatioWidth and aspectRatioHeight parameters. |
ImageFormat & ImageFormatX
The supported formats, plus the ImageFormatX extension (added in 1.5.4) exposing mimeType and fileExtension getters.
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.
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
enum ChannelOrder {
rgb, // Red, Green, Blue (default) - TensorFlow, most models
bgr, // Blue, Green, Red - OpenCV, some PyTorch models
}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.
