fluttercandies / flutter_photo_manager

A Flutter plugin that provides images, videos, and audio abstraction management APIs without interface integration, available on Android, iOS, macOS and OpenHarmony.
https://pub.dev/packages/photo_manager
Apache License 2.0
667 stars 301 forks source link

[Bug report] Thumbnail size might respect the given value regardless of the aspect ratio #1135

Open iosephmagno opened 3 months ago

iosephmagno commented 3 months ago

Version

3.1.1

Platforms

Android, iOS

Device Model

Xiaomi mi lite 5g and iphone 13 pro

flutter info

[✓] Flutter (Channel master, 3.22.0-42.0.pre.6, on macOS 14.2.1 23C71 darwin-arm64, locale en-IT)
[!] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS (Xcode 15.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2023.1)

How to reproduce?

Pick an horizontal image and get the entity thumbnail as square. The result image is not squared. Note: in a previous version of the plugin, result image was squared but a black are was filled in. I guess there is an issue with the crop.

entity!.thumbnailDataWithOption(
          ThumbnailOption(
            size: const ThumbnailSize.square(350),
            quality: 65,
            //deliveryMode: DeliveryMode.opportunistic,
            // resizeMode: ResizeMode.fast,
            format: ThumbnailFormat.jpeg,
           // resizeContentMode: ResizeContentMode.fill
          ),
        )
        .then((result) async {
          img.Image? image = img.decodeImage(result);
          debugPrint("DEBUG result width ${image!.width}");
          debugPrint("DEBUG result height ${image!.height}");
          ...

Logs

No response

Example code (optional)

No response

Contact

No response

AlexV525 commented 3 months ago

Could you make a bisect to determine what is the last commit that works for you?

delfme commented 3 months ago

Hello Alex, I eventually noticed that thumbs are never squared whatever is the original file. Can you test it by removing any fit in the widget used to display the thumb images inside the grid? Coz they look squared only because of the fit effect.

AlexV525 commented 3 months ago

Which grid? The plugin did not provide any grid AFAIK

delfme commented 3 months ago

My bad, but it is not required. You can just print width and height of the returned thumbnail, it is not a squared image, whatever the original pic.

iosephmagno commented 1 month ago

Hello @AlexV525 @CaiJingLong Here is what we are doing to create a squared thumbnail

import 'package:image/image.dart' as img;
    ....

    // Get a big res thumb with width: 1400px and height: auto
    final croppedWidth = entity.width >= 1400 ? 1400 : entity.width;
    await entity.thumbnailDataWithOption(
      ThumbnailOption(
          size: ThumbnailSize(croppedWidth, (croppedWidth * entity.height/entity.width).toInt()),
          quality: 80,
          format: ThumbnailFormat.jpeg
      ),
    ).then((result) async {
      if (result != null) {
        // Create a 350px square thumbnail
        img.Image? image = img.decodeJpg(result!);
        if (image != null) {
          img.Image resizedImage = img.copyResizeCropSquare(
            image,
            size: 350,
          );
      ....

Above code returns a resizedImage which is a 350x350px thumbnail.

On the contrary, the official way to get it, doesnt. More precisely, the returned image size is 350x350px but there is a black inner area inside the image and the real image content is not really squared.

  entity!.thumbnailDataWithOption(
          ThumbnailOption(
            size: const ThumbnailSize.square(350),
            quality: 80,
            format: ThumbnailFormat.jpeg,
          ),
        )

Hope this helps.

iosephmagno commented 1 month ago

Here is an example of black inner area (on the left size of the squared rect), see first two thumbnails in the grid 1721403695956

Here is an example of correct squared pics obtained through the code mentioned above

1721403695959

AlexV525 commented 1 month ago

Is that critical? IMO using BoxFit.cover should regardless of the image size.

delfme commented 1 month ago

Yes. The black area inside the image is "part of the image itself", hence BoxFit.cover cannot do the job (the "cover" fit property is already applied when black area is shown). The BoxFit trick would work if ThumbnailSize.square were not used at all. In that case photo_manager would return the thumb imagine with original aspect ratio and that image can be fitted in a square rect via BoxFit.cover. But that is not the way to go if these thumbnails are meant to be squared and uploaded to a backend (ie. instagram-like app).

If photo_manager is square-cropping thumbs on dart side, you could try to integrate our code, or if the crop occurs on native side you could try to see what's wrong with that part.

AlexV525 commented 1 month ago

So it only takes place on certain assets rather than all of them right? From your screenshot all other images are displayed well.

iosephmagno commented 1 month ago

Version

3.1.1

Platforms

Android, iOS

Device Model

Xiaomi mi lite 5g and iphone 13 pro

flutter info

[✓] Flutter (Channel master, 3.22.0-42.0.pre.6, on macOS 14.2.1 23C71 darwin-arm64, locale en-IT)
[!] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS (Xcode 15.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2023.1)

How to reproduce?

Pick an horizontal image and get the entity thumbnail as square. The result image is not squared. Note: in a previous version of the plugin, result image was squared but a black are was filled in. I guess there is an issue with the crop.

entity!.thumbnailDataWithOption(
          ThumbnailOption(
            size: const ThumbnailSize.square(350),
            quality: 65,
            //deliveryMode: DeliveryMode.opportunistic,
            // resizeMode: ResizeMode.fast,
            format: ThumbnailFormat.jpeg,
           // resizeContentMode: ResizeContentMode.fill
          ),
        )
        .then((result) async {
          img.Image? image = img.decodeImage(result);
          debugPrint("DEBUG result width ${image!.width}");
          debugPrint("DEBUG result height ${image!.height}");
          ...

Logs

No response

Example code (optional)

No response

Contact

No response

No that was done on purpose. You can try this sample code. Time passed by and I dont remember well, but with one version the thumb was not squared at all, and with another version the thumb was squared wrongly (with the black inner area).