image_ffi library

Native image decode, resize and encode for Dart, backed by Sean Barrett's stb single-file libraries over FFI.

The stb C sources are compiled from source by a Dart build hook, so there is no prebuilt binary to ship and no system library to install beyond a C toolchain. Decoding, resizing and encoding run in native code and copy the result into a Dart Uint8List, so callers never manage native memory.

import 'dart:io';
import 'package:image_ffi/image_ffi.dart';

void main() {
  final bytes = File('photo.jpg').readAsBytesSync();
  final thumb = thumbnailJpeg(bytes, maxDimension: 256);
  File('thumb.jpg').writeAsBytesSync(thumb);
}

See decodeImage, imageInfo, resizePixels, encodeJpeg, encodePng and thumbnailJpeg for the full API.

Classes

DecodedImage
A decoded image: raw 8-bit pixels plus their geometry.

Enums

ResizeColorSpace
The colour space a resize resamples in.

Functions

applyExifOrientation(DecodedImage image, int orientation) → DecodedImage
Applies orientation to image, returning the upright version.
decodeImage(Uint8List bytes, {int? forceChannels}) → DecodedImage
Decodes an encoded image into raw pixels.
encodeJpeg(Uint8List pixels, {required int width, required int height, int channels = 3, int quality = 90}) → Uint8List
Encodes raw pixels as a JPEG.
encodePng(Uint8List pixels, {required int width, required int height, int channels = 4}) → Uint8List
Encodes raw pixels as a PNG.
exifOrientation(Uint8List bytes) → int
Reads the EXIF orientation tag out of a JPEG.
imageInfo(Uint8List bytes) → ({int channels, int height, int width})
Reads an image's dimensions and channel count without decoding its pixels.
resizePixels(Uint8List pixels, {required int srcWidth, required int srcHeight, required int dstWidth, required int dstHeight, int channels = 4, ResizeColorSpace colorSpace = ResizeColorSpace.srgb}) → Uint8List
Resizes raw pixels to new dimensions with a high-quality filter.
thumbnailJpeg(Uint8List imageBytes, {int maxDimension = 256, int quality = 85, bool applyOrientation = true}) → Uint8List
Decodes an image, downscales it so its longer side is at most maxDimension, and JPEG-encodes the result, all in one call.
thumbnailJpegAsync(Uint8List imageBytes, {int maxDimension = 256, int quality = 85}) → Future<Uint8List>
The off-main-isolate version of thumbnailJpeg.
thumbnailJpegBatch(Iterable<Uint8List> images, {int maxDimension = 256, int quality = 85, int? concurrency}) → Stream<Uint8List>
Thumbnails a batch of images off the main isolate with a bounded number of isolates running at once.
thumbnailPng(Uint8List imageBytes, {int maxDimension = 256, bool applyOrientation = true}) → Uint8List
Decodes imageBytes, scales it so its longer side is at most maxDimension, and re-encodes it as PNG.
thumbnailPngAsync(Uint8List imageBytes, {int maxDimension = 256}) → Future<Uint8List>
The off-main-isolate version of thumbnailPng; see thumbnailJpegAsync for how the work is offloaded and thumbnailPng for the parameters. Use this when the source has transparency to preserve, since PNG keeps the alpha channel a JPEG thumbnail would drop.
thumbnailPngBatch(Iterable<Uint8List> images, {int maxDimension = 256, int? concurrency}) → Stream<Uint8List>
The PNG twin of thumbnailJpegBatch; see it for how concurrency is bounded and how results are ordered, and thumbnailPng for the parameters. Use this over a folder whose images have transparency to keep, since PNG keeps the alpha channel a JPEG thumbnail would drop.

Exceptions / Errors

ImageFfiException
Thrown when a native stb operation fails, for example when decodeImage is given bytes that are not a recognised image.