loadImage method

  1. @override
ImageStreamCompleter loadImage(
  1. ResizeImageKey key,
  2. ImageDecoderCallback decode
)
override

Converts a key into an ImageStreamCompleter, and begins fetching the image.

For backwards-compatibility the default implementation of this method returns an object that will cause resolveStreamForKey to consult loadBuffer. However, implementors of this interface should only override this method and not loadBuffer, which is deprecated.

The decode callback provides the logic to obtain the codec for the image.

See also:

  • ResizeImage, for modifying the key to account for cache dimensions.

Implementation

@override
ImageStreamCompleter loadImage(ResizeImageKey key, ImageDecoderCallback decode) {
  Future<ui.Codec> decodeResize(ui.ImmutableBuffer buffer, {ui.TargetImageSizeCallback? getTargetSize}) {
    assert(
      getTargetSize == null,
      'ResizeImage cannot be composed with another ImageProvider that applies '
      'getTargetSize.',
    );
    return decode(buffer, getTargetSize: (int intrinsicWidth, int intrinsicHeight) {
      switch (policy) {
        case ResizeImagePolicy.exact:
          int? targetWidth = width;
          int? targetHeight = height;

          if (!allowUpscaling) {
            if (targetWidth != null && targetWidth > intrinsicWidth) {
              targetWidth = intrinsicWidth;
            }
            if (targetHeight != null && targetHeight > intrinsicHeight) {
              targetHeight = intrinsicHeight;
            }
          }

          return ui.TargetImageSize(width: targetWidth, height: targetHeight);
        case ResizeImagePolicy.fit:
          final double aspectRatio = intrinsicWidth / intrinsicHeight;
          final int maxWidth = width ?? intrinsicWidth;
          final int maxHeight = height ?? intrinsicHeight;
          int targetWidth = intrinsicWidth;
          int targetHeight = intrinsicHeight;

          if (targetWidth > maxWidth) {
            targetWidth = maxWidth;
            targetHeight = targetWidth ~/ aspectRatio;
          }

          if (targetHeight > maxHeight) {
            targetHeight = maxHeight;
            targetWidth = (targetHeight * aspectRatio).floor();
          }

          if (allowUpscaling) {
            if (width == null) {
              assert(height != null);
              targetHeight = height!;
              targetWidth = (targetHeight * aspectRatio).floor();
            } else if (height == null) {
              targetWidth = width!;
              targetHeight = targetWidth ~/ aspectRatio;
            } else {
              final int derivedMaxWidth = (maxHeight * aspectRatio).floor();
              final int derivedMaxHeight = maxWidth ~/ aspectRatio;
              targetWidth = math.min(maxWidth, derivedMaxWidth);
              targetHeight = math.min(maxHeight, derivedMaxHeight);
            }
          }

          return ui.TargetImageSize(width: targetWidth, height: targetHeight);
      }
    });
  }

  final ImageStreamCompleter completer = imageProvider.loadImage(key._providerCacheKey, decodeResize);
  if (!kReleaseMode) {
    completer.debugLabel = '${completer.debugLabel} - Resized(${key._width}×${key._height})';
  }
  _configureErrorListener(completer, key);
  return completer;
}