fluttercandies / extended_image

A powerful official extension library of image, which support placeholder(loading)/ failed state, cache network, zoom pan image, photo view, slide out page, editor(crop,rotate,flip), paint custom etc.
https://fluttercandies.github.io/extended_image/
MIT License
1.94k stars 505 forks source link

[Discussions] How to retrieve the original Crop Rect from the new cropping process? #715

Open maRci002 opened 3 days ago

maRci002 commented 3 days ago

Content

The old cropping process was as follows:
Crop -> Flip -> Rotate

The new cropping process is:
Rotate -> Flip -> Crop

This means the current Crop Rect obtained via getCropRect is transformed by the flip and rotate operations. How can I retrieve the Crop Rect before any transformations are applied?

I tried the old method, but it didn't give back the proper result:

  // https://github.com/fluttercandies/extended_image/blob/03bd2ad621583f2f716da1915506f8df34ec8f52/lib/src/editor/editor.dart#L291C9-L291C20
  Rect? _getCropRect(ExtendedImageState extendedImageState, EditActionDetails? editActionDetails) {
    if (extendedImageState.extendedImageInfo?.image == null || editActionDetails == null) {
      return null;
    }

    var cropScreen = editActionDetails.screenCropRect;
    var imageScreenRect = editActionDetails.screenDestinationRect;

    if (cropScreen == null || imageScreenRect == null) {
      return null;
    }

    imageScreenRect = _paintRect(imageScreenRect, editActionDetails);
    cropScreen = _paintRect(cropScreen, editActionDetails);

    //move to zero
    cropScreen = cropScreen.shift(-imageScreenRect.topLeft);

    imageScreenRect = imageScreenRect.shift(-imageScreenRect.topLeft);

    final image = extendedImageState.extendedImageInfo!.image;
    // var size = _editActionDetails.isHalfPi
    //     ? Size(image.height.toDouble(), image.width.toDouble())
    //     : Size(image.width.toDouble(), image.height.toDouble());
    final imageRect = Offset.zero & Size(image.width.toDouble(), image.height.toDouble());

    final ratioX = imageRect.width / imageScreenRect.width;
    final ratioY = imageRect.height / imageScreenRect.height;

    final cropImageRect = Rect.fromLTWH(cropScreen.left * ratioX, cropScreen.top * ratioY, cropScreen.width * ratioX, cropScreen.height * ratioY);
    return cropImageRect;
  }

  // https://github.com/fluttercandies/extended_image/blob/03bd2ad621583f2f716da1915506f8df34ec8f52/lib/src/editor/editor_utils.dart#L154
  Rect _paintRect(Rect rect, EditActionDetails editActionDetails) {
    var resultRect = rect;

    if (!editActionDetails.hasEditAction || editActionDetails.screenCropRect == null) {
      return resultRect;
    }

    final flipOrigin = editActionDetails.screenCropRect!.center;
    if (editActionDetails.hasRotateDegrees) {
      resultRect = editActionDetails.rotateRect(resultRect, flipOrigin, -editActionDetails.rotateRadians);
    }

    if (editActionDetails.flipY) {
      resultRect = Rect.fromLTRB(
        2 * flipOrigin.dx - resultRect.right,
        resultRect.top,
        2 * flipOrigin.dx - resultRect.left,
        resultRect.bottom,
      );
    }

    return resultRect;
  }
zmtzawqlp commented 1 day ago

what do you want to do?

maRci002 commented 1 day ago

My server-side service applies filters to the image in the following order: Crop -> Flip -> Rotate.

My goal is to retrieve the crop area as if the image hadn’t been rotated or flipped.

For example, when I rotate the image to the left and want to crop the largest 16:9 ( when rotated it is actually 9/16 ) area, I currently get the following result:
{top: 0, left: 0, bottom: 414, right: 232.875}

The old method gave the same result, regardless of whether I rotated the image: {top: 0, left: 0, bottom: 232.875, right: 414}

+-----------------------------+
|                             |
|                             |
|                             |
|                             |
|                             |
+-----------------------------+
|                             |
|                             |
|                             |
|                             |
|                             |
|                             |
|                             |
|                             |
|                             |
|                             |
|                             |
|                             |
+-----------------------------+
+-----------------+---------------------------------+
|                 |                                 |
|                 |                                 |
|                 |                                 |
|                 |                                 |
|                 |                                 |
|                 |                                 |
|                 |                                 |
|                 |                                 |
|                 |                                 |
|                 |                                 |
|                 |                                 |
+-----------------+---------------------------------+
zmtzawqlp commented 56 minutes ago

What is your actual intention? The previous algorithm and the current one differ in that the current version supports arbitrary angles, which has resulted in a change in the order. If the current version does not meet your needs, you may consider using an older version.