cream_of_the_crop 0.92.1 copy "cream_of_the_crop: ^0.92.1" to clipboard
cream_of_the_crop: ^0.92.1 copied to clipboard

Platformweb

Blazingly fast image transformations for Flutter Web.

Cream Of The Crop #

Blazingly fast image crop and resize processing for Flutter Web.

Features:

  • Crop
  • Resize
  • Get Image Dimensions

Why? #

This package exists to offer a high performance option for image resize and crop transformations on web. Due to the nature of dart, an image transformer writen in pure dart is slow on web. See the performance warning on that package for details.

Dart Image vs Cream Of The Crop Benchmark. 1.591 vs 38.634

How? #

In almost all modern web browsers, cream_of_the_crop can leverage the GPU Accelerated HTML <canvas> element to perform resize and crop operations.

Demo #

Launch the app in the example folder to see the performance difference between canvas and pure dart.

No User Interface #

This package has no user interface. It is designed to be used with crop_image or any other cropping library that doesn't handle its own image transformation. crop_image provides a user interface for cropping the image, and generates crop values that this package can consume to transform the image data.

iOS / Android? #

This package is for web only. Make use of the kIsWeb conditional to ensure you are only calling its functions on web. Other platforms will throw an unimplemented error.

The image package is more performant on iOS and Android devices, and can provide a good user experience for those platforms. There is potential to add native Swift and Kotlin code to handle these tasks even faster. Consider checking out flutter_native_image.

Crop Instructions: #

The crop command takes several variables. Please reference the mozilla developer docs for a description of that they mean.

Dart Image vs Cream Of The Crop Benchmark. 1.591 vs 38.634

Image source: Mozilla mdn docs

import 'package:cream_of_the_crop/cream_of_the_crop.dart';

final _creamOfTheCropPlugin = CreamOfTheCrop();

Uint8List? crop() async {
  return await _creamOfTheCropPlugin.cropImage(
    imageBytes,
    sx, sy,  // Crop position relative to the top left of the original image
    sw, sh,  // Width and height of the area to remain
    dx, dy,  // Relative position on the destination canvas (almost always 0,0 since creating a canvas larger than the desired image is not supported right now)
    dw, dh,  // Final width and height of the finished image
    quality, 
    imageExportType,
  );
}

To calculate these values, it may be useful to use the dart:ui package's Image() object to obtain the original image's width and height. Example shown with an imagePicker.

import 'package:image_picker/image_picker.dart';
import 'dart:ui' as ui;

final ImagePicker imagePicker = ImagePicker();

void getImage() async {
  // Image Picker
  final XFile? image = await imagePicker.pickImage(source: ImageSource.gallery);

  if (image != null) {
    // Read as bytes
    Uint8List bytes = await image.readAsBytes();

    // Decode as image
    ui.Image decoded = await decodeImageFromList(bytes);
    
    print("Image Width: ${decoded.width}, Height: ${decoded.height}");
  }
}

crop_image example #

See the flutter project in the example folder for an implementation of a cropping overlay dialog returning crop values to be used by cream_of_the_crop.

Given an original image of X x Y dimensions, cropping to a 500 x 500 square.

// dart:ui decoded original image dimensions
int decodedWidth = decoded.width; // X
int decodedHeight = decoded.height; // Y

// Desired final pixel size of the image
int exportWidth = 500;
int exportHeight = 500;

// Values provided by crop_image package cropping UI
double cropTop = finalCropPixels.top;
double cropRight = finalCropPixels.right;
double cropBottom = finalCropPixels.bottom;
double cropLeft = finalCropPixels.left;

// Distances From Edges
int distTop = cropTop.toInt();
int distRight = (decodedWidth - cropRight).toInt();
int distLeft = cropLeft.toInt();
int distBottom = (decodedHeight - cropBottom).toInt();

// Calculated crop values needed to create the cropped image data
int sx = distLeft;
int sy = distTop;
int sw = decodedWidth - distLeft - distRight;
int sh = decodedHeight - distTop - distBottom;
int dx = 0;
int dy = 0;
int dw = exportWidth;
int dh = exportHeight;

Room for Improvement #

Very large images (over 15MB) can still take 2-3 seconds to process. The image processing blocks the main UI thread so a progress indicator won't animate. This could potentially be fixed by moving the processing code over to external javascript and setting up a web worker, however, the installation process would be more complex for the package user.

A typical 10MP smart phone photo of ~5MB can be processed in under 1 second on an average computer, so in most cases the experience should be good enough as is.

5
likes
110
pub points
66%
popularity

Publisher

verified publisherrideout.studio

Blazingly fast image transformations for Flutter Web.

Homepage

Documentation

API reference

License

BSD-3-Clause (LICENSE)

Dependencies

flutter, flutter_web_plugins, plugin_platform_interface

More

Packages that depend on cream_of_the_crop