Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getCropRect() returns Rect with negative values #580

Open
mitrakov opened this issue May 17, 2023 · 4 comments
Open

getCropRect() returns Rect with negative values #580

mitrakov opened this issue May 17, 2023 · 4 comments

Comments

@mitrakov
Copy link

Version

7.0.2

Platforms

macOS

Device Model

MacOS 13.3.1

flutter info

<details>
  <summary>flutter doctor -v</summary>


flutter doctor -v
[✓] Flutter (Channel stable, 3.7.12, on macOS 13.3.1 22E261 darwin-x64, locale en-GB)
    • Flutter version 3.7.12 on channel stable at /Users/macbook1/soft/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 4d9e56e694 (4 weeks ago), 2023-04-17 21:47:46 -0400
    • Engine revision 1a65d409c7
    • Dart version 2.19.6
    • DevTools version 2.20.1

[!] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    • Android SDK at /Users/macbook1/Library/Android/sdk
    ✗ 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 14.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14E222b
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[✓] IntelliJ IDEA Community Edition (version 2022.3.1)
    • IntelliJ at /Applications/IntelliJ IDEA CE.app
    • Flutter plugin version 72.1.4
    • Dart plugin version 223.8214.16

[✓] VS Code (version 1.74.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.21.0

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-x64     • macOS 13.3.1 22E261 darwin-x64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 113.0.5672.126

[✓] HTTP Host Availability
    • All required HTTP hosts are available

! Doctor found issues in 1 category.
  
</details>

How to reproduce?

case ExtendedImageMode.editor:
    final state = editorKey.currentState!;
    final cropRect = state.getCropRect()!;
    print(cropRect);

Logs

After several attempts of cropping, it may return "-0.0", which causes issues in other libraries:

flutter: Rect.fromLTRB(0.0, 51.6, 1080.0, 1545.0)
flutter: Rect.fromLTRB(0.0, 23.1, 1080.0, 1493.0)
flutter: Rect.fromLTRB(0.0, 28.8, 1080.0, 1470.0)
flutter: Rect.fromLTRB(0.0, 31.5, 1080.0, 1441.0)
flutter: Rect.fromLTRB(0.0, 45.3, 1080.0, 1802.0)
flutter: Rect.fromLTRB(0.0, 157.0, 1080.0, 1757.0)
flutter: Rect.fromLTRB(-0.0, 70.6, 1080.0, 1600.0)
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: 'package:image_editor_platform_interface/src/option/clip.dart': Failed assertion: line 17 pos 16: 'x >= 0': true
#0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:51:61)
#1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:40:5)
#2      new ClipOption (package:image_editor_platform_interface/src/option/clip.dart:17:16)
#3      _MyAppState._saveFile.converterMacOs (package:tommyview/main.dart:283:46)
#4      _MyAppState._saveFileInternal (package:tommyview/main.dart:318:47)
#5      _MyAppState._saveFile (package:tommyview/main.dart:289:10)
#6      _MyAppState.build.<anonymous closure> (package:tommyview/main.dart:132:75)
#7      CallbackAction.invoke (package:flutter/src/widgets/actions.dart:541:39)

Example code (optional)

No response

Contact

mitrakov-artem@yandex.ru

@zmtzawqlp
Copy link
Member

is there any cases or demo to reproduce it?

@mitrakov
Copy link
Author

Source code
import "dart:io";
import "package:flutter/material.dart";
import "package:flutter/services.dart";
import "package:image_editor/image_editor.dart";
import "package:extended_image/extended_image.dart";

// dependencies:
//   extended_image: 7.0.2
//   image_editor: 1.3.0
// 1. Make sure to remove "com.apple.security.app-sandbox" from entitlements
// 2. Prepare "1.png" file
// 3. Click F3 to crop image, and ENTER to save the file
// 4. Try several times!
void main(List<String> args) async {
  runApp(MaterialApp(home: Scaffold(body: MyApp(File("/Users/tommy/1.png")))));
}

class MyApp extends StatefulWidget {
  final File startPath;
  const MyApp(this.startPath);
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final editorKey = GlobalKey<ExtendedImageEditorState>();
  final extImgKey = GlobalKey();
  ExtendedImageMode _mode = ExtendedImageMode.gesture;

  @override
  Widget build(BuildContext context) {
    return Shortcuts(
      shortcuts: {
        const SingleActivator(LogicalKeyboardKey.enter): SaveFileIntent(),
        const SingleActivator(LogicalKeyboardKey.f3):    SwitchModeIntent(),
      },
      child: Actions(
        actions: {
          SaveFileIntent:   CallbackAction(onInvoke: (_) => _saveFile()),
          SwitchModeIntent: CallbackAction(onInvoke: (_) => _switchMode()),
        },
        child: Focus(
          autofocus: true,
          child: ExtendedImage.file (key: extImgKey, widget.startPath, mode: _mode, fit: _mode == ExtendedImageMode.editor ? BoxFit.contain : null, width: double.infinity, height: double.infinity, extendedImageEditorKey: editorKey, cacheRawData: true)
        )
      )
    );
  }

  void _switchMode() {
    setState(() {
      _mode = _mode == ExtendedImageMode.editor ? ExtendedImageMode.gesture : ExtendedImageMode.editor;
    });
  }

  void _saveFile() {
    converterMacOs(Uint8List image, Rect? cropRect) async {
      final option = ImageEditorOption();
      if (cropRect != null) option.addOption(ClipOption(x: cropRect.left, y: cropRect.top, width: cropRect.width, height: cropRect.height));
      final result = await ImageEditor.editImage(image: image, imageEditorOption: option);
      return result!;
    }

    _saveFileInternal(converterMacOs);
  }

  void _saveFileInternal(ImageConverter converter) async {
    Rect? cropOption;

    switch (_mode) {
      case ExtendedImageMode.editor:
        final state = editorKey.currentState!;
        final action = state.editAction!;
        final cropRect = state.getCropRect()!;
        print("Rect is $cropRect");
        if (action.needCrop) {
          cropOption = cropRect;
        }
        break;
      default:
    }

    if (cropOption != null) {
      final exImage = extImgKey.currentWidget as ExtendedImage;
      final imageProvider = exImage.image as ExtendedFileImageProvider;
      final Uint8List image = imageProvider.rawImageData;
      final Uint8List bytes = await converter.call(image, cropOption);
      widget.startPath.writeAsBytesSync(bytes, flush: true);
      clearMemoryImageCache();
      _switchMode();
    }
  }
}

typedef ImageConverter = Future<Uint8List> Function(Uint8List curImage, Rect? cropRect);

class SaveFileIntent extends Intent {}
class SwitchModeIntent extends Intent {}

How to reproduce (press F3 and ENTER):

tommyview

@zmtzawqlp
Copy link
Member

i can't reprduce it at my side, can you try it on latest version of extended_image?

@mitrakov
Copy link
Author

@zmtzawqlp, I ended up with this dirty-hack method:

Rect _fixRect(Rect rect) {
  // extended_image: 7.0.2 has a bug when sometimes it provides "-0.0" values in Rect
  if (rect.left.isNegative || rect.right.isNegative || rect.top.isNegative || rect.bottom.isNegative) {
    final left   = rect.left.isNegative   ? 0.0 : rect.left;
    final right  = rect.right.isNegative  ? 0.0 : rect.right;
    final top    = rect.top.isNegative    ? 0.0 : rect.top;
    final bottom = rect.bottom.isNegative ? 0.0 : rect.bottom;
    return Rect.fromLTRB(left, top, right, bottom);
  }
  return rect;
}

which works for me.

Will try to check 8.2.0 at my spare time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants