imageProviderToScaledRgba function

Future<ByteData> imageProviderToScaledRgba(
  1. ImageProvider<Object> imageProvider,
  2. double maxDimension
)

Implementation

Future<ByteData> imageProviderToScaledRgba(
  ImageProvider imageProvider,
  double maxDimension,
) {
  final stream = imageProvider.resolve(
    ImageConfiguration(size: Size(maxDimension, maxDimension)),
  );
  ImageStreamListener? listener;
  final completer = Completer<ByteData>();
  listener = ImageStreamListener((frame, sync) async {
    try {
      if (listener != null) {
        stream.removeListener(listener);
      }
      final image = frame.image;
      final width = image.width;
      final height = image.height;
      var paintWidth = width.toDouble();
      var paintHeight = height.toDouble();
      final rescale = width > maxDimension || height > maxDimension;
      if (rescale) {
        paintWidth = (width > height)
            ? maxDimension
            : (maxDimension / height) * width;
        paintHeight = (height > width)
            ? maxDimension
            : (maxDimension / width) * height;
      }
      final byteData = await image.toByteData(
        format: ui.ImageByteFormat.rawStraightRgba,
      );
      if (byteData == null) {
        completer.complete(ByteData(0));
        return;
      }
      final scaledByteData = _scaleRgbaNearest(
        byteData,
        sourceWidth: width,
        sourceHeight: height,
        targetWidth: paintWidth.toInt().clamp(1, width),
        targetHeight: paintHeight.toInt().clamp(1, height),
      );
      completer.complete(scaledByteData);
    } catch (e, stack) {
      debugPrint('error scaling image: $e, $stack');
      completer.completeError('Failed to scale image. Error receieved: $e');
    }
  });
  stream.addListener(listener);
  return completer.future;
}