@@ -25,6 +25,7 @@ class ExtendedResizeImage extends ImageProvider<_SizeAwareCacheKey>
2525 this .allowUpscaling = false ,
2626 this .cacheRawData = false ,
2727 this .imageCacheName,
28+ this .policy = ResizeImagePolicy .exact,
2829 }) : assert ((compressionRatio != null &&
2930 compressionRatio > 0 &&
3031 compressionRatio < 1 ) ||
@@ -52,6 +53,11 @@ class ExtendedResizeImage extends ImageProvider<_SizeAwareCacheKey>
5253 /// The height the image should decode to and cache.
5354 final int ? height;
5455
56+ /// The policy that determines how [width] and [height] are interpreted.
57+ ///
58+ /// Defaults to [ResizeImagePolicy.exact] .
59+ final ResizeImagePolicy policy;
60+
5561 /// Whether the [width] and [height] parameters should be clamped to the
5662 /// intrinsic width and height of the image.
5763 ///
@@ -108,17 +114,21 @@ class ExtendedResizeImage extends ImageProvider<_SizeAwareCacheKey>
108114 }
109115
110116 @override
111- ImageStreamCompleter loadBuffer (
112- _SizeAwareCacheKey key, DecoderBufferCallback decode) {
113- Future <Codec > decodeResize (ImmutableBuffer buffer,
114- {int ? cacheWidth, int ? cacheHeight, bool ? allowUpscaling}) {
117+ ImageStreamCompleter loadImage (
118+ _SizeAwareCacheKey key, ImageDecoderCallback decode) {
119+ Future <Codec > decodeResize (
120+ ImmutableBuffer buffer, {
121+ TargetImageSizeCallback ? getTargetSize,
122+ }) {
115123 assert (
116- cacheWidth == null && cacheHeight == null && allowUpscaling == null ,
124+ getTargetSize == null ,
117125 'ResizeImage cannot be composed with another ImageProvider that applies '
118126 'cacheWidth, cacheHeight, or allowUpscaling.' ,
119127 );
128+
120129 return _instantiateImageCodec (
121130 buffer,
131+ decode,
122132 compressionRatio: compressionRatio,
123133 maxBytes: maxBytes,
124134 targetWidth: width,
@@ -127,7 +137,7 @@ class ExtendedResizeImage extends ImageProvider<_SizeAwareCacheKey>
127137 }
128138
129139 final ImageStreamCompleter completer =
130- imageProvider.loadBuffer (key._providerCacheKey, decodeResize);
140+ imageProvider.loadImage (key._providerCacheKey, decodeResize);
131141 if (! kReleaseMode) {
132142 completer.debugLabel =
133143 '${completer .debugLabel } - Resized(${key ._width }×${key ._height })' ;
@@ -178,7 +188,8 @@ class ExtendedResizeImage extends ImageProvider<_SizeAwareCacheKey>
178188 }
179189
180190 Future <Codec > _instantiateImageCodec (
181- ImmutableBuffer buffer, {
191+ ImmutableBuffer buffer,
192+ ImageDecoderCallback decode, {
182193 double ? compressionRatio,
183194 int ? maxBytes,
184195 int ? targetWidth,
@@ -205,14 +216,71 @@ class ExtendedResizeImage extends ImageProvider<_SizeAwareCacheKey>
205216 );
206217 targetWidth = size.width;
207218 targetHeight = size.height;
208- } else if (! allowUpscaling) {
209- if (targetWidth != null && targetWidth > descriptor.width) {
210- targetWidth = descriptor.width;
211- }
212- if (targetHeight != null && targetHeight > descriptor.height) {
213- targetHeight = descriptor.height;
214- }
215219 }
220+ // else if (!allowUpscaling) {
221+ // if (targetWidth != null && targetWidth > descriptor.width) {
222+ // targetWidth = descriptor.width;
223+ // }
224+ // if (targetHeight != null && targetHeight > descriptor.height) {
225+ // targetHeight = descriptor.height;
226+ // }
227+ // }
228+ else {
229+ return decode (buffer,
230+ getTargetSize: (int intrinsicWidth, int intrinsicHeight) {
231+ switch (policy) {
232+ case ResizeImagePolicy .exact:
233+ int ? targetWidth = width;
234+ int ? targetHeight = height;
235+
236+ if (! allowUpscaling) {
237+ if (targetWidth != null && targetWidth > intrinsicWidth) {
238+ targetWidth = intrinsicWidth;
239+ }
240+ if (targetHeight != null && targetHeight > intrinsicHeight) {
241+ targetHeight = intrinsicHeight;
242+ }
243+ }
244+
245+ return TargetImageSize (width: targetWidth, height: targetHeight);
246+ case ResizeImagePolicy .fit:
247+ final double aspectRatio = intrinsicWidth / intrinsicHeight;
248+ final int maxWidth = width ?? intrinsicWidth;
249+ final int maxHeight = height ?? intrinsicHeight;
250+ int targetWidth = intrinsicWidth;
251+ int targetHeight = intrinsicHeight;
252+
253+ if (targetWidth > maxWidth) {
254+ targetWidth = maxWidth;
255+ targetHeight = targetWidth ~ / aspectRatio;
256+ }
257+
258+ if (targetHeight > maxHeight) {
259+ targetHeight = maxHeight;
260+ targetWidth = (targetHeight * aspectRatio).floor ();
261+ }
262+
263+ if (allowUpscaling) {
264+ if (width == null ) {
265+ assert (height != null );
266+ targetHeight = height! ;
267+ targetWidth = (targetHeight * aspectRatio).floor ();
268+ } else if (height == null ) {
269+ targetWidth = width! ;
270+ targetHeight = targetWidth ~ / aspectRatio;
271+ } else {
272+ final int derivedMaxWidth = (maxHeight * aspectRatio).floor ();
273+ final int derivedMaxHeight = maxWidth ~ / aspectRatio;
274+ targetWidth = min (maxWidth, derivedMaxWidth);
275+ targetHeight = min (maxHeight, derivedMaxHeight);
276+ }
277+ }
278+
279+ return TargetImageSize (width: targetWidth, height: targetHeight);
280+ }
281+ });
282+ }
283+
216284 return descriptor.instantiateCodec (
217285 targetWidth: targetWidth,
218286 targetHeight: targetHeight,
0 commit comments