Skip to content

[Feature request] Add an opt-in fit/downscale-only thumbnail policy #1441

Description

@neeraj-pilot

Platforms

  • Dart
  • Android
  • iOS
  • macOS

Description

ThumbnailOption currently lets callers specify a target size, format, and quality, but it does not provide a cross-platform way to request all of the following:

  • Preserve the source aspect ratio.
  • Fit within the requested width and height.
  • Never enlarge media that is already smaller than the requested size.
  • Avoid cropping.

On Android, thumbnail generation currently calls Glide with .submit(width, height) without an explicit resize policy:

https://github.com/fluttercandies/flutter_photo_manager/blob/v3.12.0/android/src/main/kotlin/com/fluttercandies/photo_manager/thumb/ThumbnailUtil.kt#L27-L35

Glide's default downsampling strategy is currently CENTER_OUTSIDE, so smaller sources can be enlarged and non-square output can exceed one requested dimension.

Could PhotoManager expose an opt-in policy through ThumbnailOption, for example:

enum ThumbnailResizePolicy {
  platformDefault,
  fitDownscaleOnly,
}

const ThumbnailOption(
  size: ThumbnailSize.square(512),
  resizePolicy: ThumbnailResizePolicy.fitDownscaleOnly,
);

platformDefault should remain the default so existing applications retain their current behavior.

The proposed fitDownscaleOnly contract would be:

scale = min(
  1,
  requestedWidth / sourceWidth,
  requestedHeight / sourceHeight,
)

Expected results for a 512x512 request:

Source Result
64x64 64x64
320x240 320x240
4000x3000 512x384
3000x4000 384x512

This request is specifically about the bytes returned by thumbnailDataWithOption and thumbnailDataWithSize. It does not depend on requestCacheAssets.

Possible native mappings:

  • Android: Glide's centerInside() behavior, which retains the original bitmap when it is smaller and fits larger media within the requested bounds.
  • iOS/macOS: PhotoKit aspect-fit generation with the scale capped at 1, using the freshly fetched native PHAsset.

The exact native implementation is up to the maintainers; the important part is the public output contract.

Why

Upscaling a thumbnail before encoding it does not add image detail, but it can increase:

  • Bitmap allocation and memory pressure.
  • Decode, resize, and compression work.
  • Method-channel response size.
  • Encoded thumbnail size.
  • Storage and network usage for applications that upload generated thumbnails.

Applications cannot safely work around this by clamping the request using AssetEntity.width and AssetEntity.height:

  • PhotoManager documents that these values can be zero.
  • Android values originate from indexed MediaStore metadata.
  • Orientation is represented separately.
  • AssetEntity is an immutable snapshot and can become stale after an edit.

PhotoManager's native implementation is the correct owner because Glide and PhotoKit have access to the current source dimensions while decoding.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions