xclud / flutter_crop

Crop any widget/image in Android, iOS, Web and Desktop with fancy and customizable UI, in pure Dart code.
https://pub.dev/packages/crop
MIT License
256 stars 84 forks source link

Unsupported operation: LayerScene.toImage not implemented #43

Closed pulstar closed 3 years ago

pulstar commented 3 years ago

I implemented the crop widget to an existing application and now it is throwing an error below, at this line:

return rrb.toImage(pixelRatio: pixelRatio);

Maybe I am importing a wrong library somewhere. Do you have any idea? The error occurs when I click the crop button.

Uncaught (in promise) Error: Unsupported operation: LayerScene.toImage not implemented.
    at Object.throw_ [as throw] (errors.dart:216)
    at _engine.LayerScene.new.toImage (layer_scene_builder.dart:20)
    at layer$.OffsetLayer.new.toImage (layer.dart:1206)
    at toImage.next (<anonymous>)
    at runBody (async_patch.dart:84)
    at Object._async [as async] (async_patch.dart:123)
    at layer$.OffsetLayer.new.toImage (layer.dart:1190)
    at proxy_box.RenderRepaintBoundary.new.toImage (proxy_box.dart:2968)
    at ui$._CropState.new.[_crop] (ui.dart:80)
    at ui$.CropController.new.crop (ui.dart:409)
    at crop_widget._CropWidgetState.new.<anonymous> (crop_widget.dart:47)
    at Generator.next (<anonymous>)
    at runBody (async_patch.dart:84)
    at Object._async [as async] (async_patch.dart:123)
    at crop_widget.dart:44
    at ink_well._InkResponseState.new.[_handleTap] (ink_well.dart:985)
    at ink_well.dart:1101
    at tap.TapGestureRecognizer.new.invokeCallback (recognizer.dart:183)
    at tap.TapGestureRecognizer.new.handleTapUp (tap.dart:598)
    at tap.TapGestureRecognizer.new.[_checkUp] (tap.dart:287)
    at tap.TapGestureRecognizer.new.acceptGesture (tap.dart:259)
    at arena.GestureArenaManager.new.sweep (arena.dart:157)
    at binding$5.WidgetsFlutterBinding.new.handleEvent (binding.dart:372)
    at binding$5.WidgetsFlutterBinding.new.dispatchEvent (binding.dart:348)
    at binding$5.WidgetsFlutterBinding.new.dispatchEvent (binding.dart:268)
    at binding$5.WidgetsFlutterBinding.new.[_handlePointerEventImmediately] (binding.dart:303)
    at binding$5.WidgetsFlutterBinding.new.handlePointerEvent (binding.dart:267)
    at binding$5.WidgetsFlutterBinding.new.[_flushPointerEventQueue] (binding.dart:225)
    at binding$5.WidgetsFlutterBinding.new.[_handlePointerDataPacket] (binding.dart:208)
    at Object._invoke1 (window.dart:853)
    at _engine.EngineWindow.new.invokeOnPointerDataPacket (window.dart:389)
    at _engine.PointerBinding.__.[_onPointerData] (pointer_binding.dart:129)
    at pointer_binding.dart:479
    at pointer_binding.dart:440
    at pointer_binding.dart:210
bartonhammond commented 3 years ago

Firstly - thanks for making this package!

I believe I have the same error though the stacktrace is different though it also occurs here:

    final pixelRatio = MediaQuery.of(context).devicePixelRatio;
    final cropped = await controller.crop(pixelRatio: pixelRatio);

flutter doctor

[✓] Flutter (Channel master, 1.24.0-8.0.pre.374, on macOS 11.0.1 20B29 darwin-x64, locale en-US)
    • Flutter version 1.24.0-8.0.pre.374 at /Users/bartonhammond/tools/flutter
    • Framework revision 183f0e797a (30 hours ago), 2020-11-26 19:12:28 +0100
    • Engine revision 20caf54969
    • Dart version 2.12.0 (build 2.12.0-76.0.dev)

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at /Users/bartonhammond/Library/Android/sdk
    • Platform android-29, build-tools 29.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1248-b01)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 12.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.1, Build version 12A7403
    • CocoaPods version 1.9.3

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

[✓] Android Studio (version 3.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 33.3.1
    • Dart plugin version 182.5215
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1248-b01)

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

[✓] Connected device (2 available)
    • Web Server (web) • web-server • web-javascript • Flutter Tools
    • Chrome (web)     • chrome     • web-javascript • Google Chrome 87.0.4280.67

• No issues found!

I am running with this launch.json

{
      "name": "Chrome SKIA",
      "request": "launch",
      "type": "dart",
      "args": [
        "-d",
        "chrome",
        "--dart-define",
        "FLUTTER_WEB_USE_SKIA=true"
      ]
    },

stack:

Error: Unsupported operation: toImage is not supported on the Web
    at Object.throw_ [as throw] (http://localhost:64152/dart_sdk.js:4351:11)
    at _engine.SurfaceScene.new.toImage (http://localhost:64152/dart_sdk.js:158747:17)
    at layer$.OffsetLayer.new.toImage (http://localhost:64152/packages/flutter/src/rendering/layer.dart.lib.js:1636:30)
    at toImage.next (<anonymous>)
    at runBody (http://localhost:64152/dart_sdk.js:37988:34)
    at Object._async [as async] (http://localhost:64152/dart_sdk.js:38019:7)
    at layer$.OffsetLayer.new.toImage (http://localhost:64152/packages/flutter/src/rendering/layer.dart.lib.js:1627:20)
    at proxy_box.RenderRepaintBoundary.new.toImage (http://localhost:64152/packages/flutter/src/rendering/proxy_box.dart.lib.js:3355:26)
    at ui$._CropState.new.[_crop] (http://localhost:64152/packages/crop/src/ui.dart.lib.js:715:18)
    at ui$.CropController.new.crop (http://localhost:64152/packages/crop/src/ui.dart.lib.js:977:33)
    at crop_widget._CropWidgetPageState.new._cropImage (http://localhost:64152/packages/MyFamilyVoice/web/crop_widget.dart.lib.js:1712:46)
    at _cropImage.next (<anonymous>)
    at runBody (http://localhost:64152/dart_sdk.js:37988:34)
    at Object._async [as async] (http://localhost:64152/dart_sdk.js:38019:7)
    at crop_widget._CropWidgetPageState.new.[_cropImage] (http://localhost:64152/packages/MyFamilyVoice/web/crop_widget.dart.lib.js:1709:20)
    at ink_well._InkResponseState.new.[_handleTap] (http://localhost:64152/packages/flutter/src/material/icon_button.dart.lib.js:51084:42)
    at tap.TapGestureRecognizer.new.invokeCallback (http://localhost:64152/packages/flutter/src/gestures/recognizer.dart.lib.js:189:18)
    at tap.TapGestureRecognizer.new.handleTapUp (http://localhost:64152/packages/flutter/src/gestures/tap.dart.lib.js:395:40)
    at tap.TapGestureRecognizer.new.[_checkUp] (http://localhost:64152/packages/flutter/src/gestures/tap.dart.lib.js:201:12)
    at tap.TapGestureRecognizer.new.acceptGesture (http://localhost:64152/packages/flutter/src/gestures/tap.dart.lib.js:178:23)
    at arena.GestureArenaManager.new.sweep (http://localhost:64152/packages/flutter/src/gestures/arena.dart.lib.js:208:31)
    at binding$5.WidgetsFlutterBinding.new.handleEvent (http://localhost:64152/packages/flutter/src/gestures/binding.dart.lib.js:318:27)
    at binding$5.WidgetsFlutterBinding.new.dispatchEvent (http://localhost:64152/packages/flutter/src/gestures/binding.dart.lib.js:297:24)
    at binding$5.WidgetsFlutterBinding.new.dispatchEvent (http://localhost:64152/packages/flutter/src/rendering/layer.dart.lib.js:6093:13)
    at binding$5.WidgetsFlutterBinding.new.[_handlePointerEventImmediately] (http://localhost:64152/packages/flutter/src/gestures/binding.dart.lib.js:268:14)
    at binding$5.WidgetsFlutterBinding.new.handlePointerEvent (http://localhost:64152/packages/flutter/src/gestures/binding.dart.lib.js:241:43)
    at binding$5.WidgetsFlutterBinding.new.[_flushPointerEventQueue] (http://localhost:64152/packages/flutter/src/gestures/binding.dart.lib.js:230:14)
    at binding$5.WidgetsFlutterBinding.new.[_handlePointerDataPacket] (http://localhost:64152/packages/flutter/src/gestures/binding.dart.lib.js:220:65)
    at Object.invoke1 (http://localhost:64152/dart_sdk.js:178716:7)
    at _engine.EnginePlatformDispatcher.__.invokeOnPointerDataPacket (http://localhost:64152/dart_sdk.js:161367:15)
    at _engine.PointerBinding.__.[_onPointerData] (http://localhost:64152/dart_sdk.js:162002:49)
bartonhammond commented 3 years ago

Update.

When I build with flutter build web --dart-define=FLUTTER_WEB_USE_SKIA=true and run in the production env, the cropping works fine.

I just tested running the flutter_code/example and that works just fine. My error is happening w/in my project.

Then I ran flutter run -d chrome --dart-define=FLUTTER_WEB_USE_SKIA=true and that works w/ my app.

So maybe, for me, it's something w/ the launch.json?

bartonhammond commented 3 years ago

Boy do I feel stupid.

I changed the vsCode launch.json configuration and it works fine now. I hope I didn't confuse this issue

{
      "name": "Chrome SKIA",
      "request": "launch",
      "type": "dart",
      "args": [
        "-d",
        "chrome",
        "--release",
        "--dart-define=FLUTTER_WEB_USE_SKIA=true"
      ]
    },
pulstar commented 3 years ago

I check the demo app now and the same error is occurring... Here are more log messages:

════════ Exception caught by foundation library ════════════════════════════════════════════════════
The following assertion was thrown while dispatching notifications for CropController:
Cannot get size during build.

The size of this render object has not yet been determined because the framework is still in the process of building 
widgets, which means the render tree for this frame has not yet been determined. The size getter should only be 
called from paint callbacks or interaction event handlers (e.g. gesture callbacks).

If you need some sizing information during build to decide which widgets to build, consider using a LayoutBuilder 
widget, which can tell you the layout constraints at a given location in the tree. See 
<https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html> for more details.

The size getter was called for the following element: IgnorePointer-[GlobalKey#fb5a9]
  ignoring: true
  renderObject: RenderIgnorePointer#6a147
When the exception was thrown, this was the stack: 
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 216:49
throw_
packages/flutter/src/widgets/framework.dart 3825:9                   <fn>
packages/flutter/src/widgets/framework.dart 3846:7                   get size
packages/crop/src/ui.dart 107:36                                     [_reCenterImage]
packages/flutter/src/foundation/change_notifier.dart 243:16          notifyListeners
...
The CropController sending notification was: Instance of 'CropController'
xclud commented 3 years ago

@pulstar It's very important to set FLUTTER_WEB_USE_SKIA to true. Basically there are two engines in flutter for web: DOM and SKIA.

DOM is the current version, deprecated and [possibly] no longer receiving updates from flutter team. SKIA is the next generation and the future of flutter, still beta and actively worked on.

For a production build run:

flutter build web --dart-define=FLUTTER_WEB_USE_SKIA=true

And for debugging in vs code create a file named /.vscode/launch.json in your project folder and paste the following in it:

{
      "name": "Chrome SKIA",
      "request": "launch",
      "type": "dart",
      "args": [
        "-d",
        "chrome",
        "--dart-define=FLUTTER_WEB_USE_SKIA=true"
      ]
}

Please let me know if this works for you.

pulstar commented 3 years ago

I am already using the FLUTTER_WEB_USE_SKIA parameter in my settings. It solved many problems, but not this one. Only your online demo is working fine.

xclud commented 3 years ago

Then i guess it's a problem with your flutter version. It must be version 1.24.0-8.0.pre.359 or newer.

You can get this version by switching to master channel and upgrading. in your terminal run:

flutter channel master
flutter upgrade
pulstar commented 3 years ago

Hmmm... I will try the upgrade!

Flutter 1.24.0-3.0.pre • channel dev • https://github.com/flutter/flutter.git
Framework • revision 2783f8e2e1 (5 weeks ago) • 2020-10-22 09:36:06 -0700
Engine • revision defa8be2b1
Tools • Dart 2.11.0 (build 2.11.0-242.0.dev)
xclud commented 3 years ago

Yes you are on dev channel. That's why. Scene.toImage is implemented last week in SKIA engine. It's quite new and you have to upgrade to get it.

xclud commented 3 years ago

I assume your problem is solved now. I close this issue. Please feel free to open a new issue.

pulstar commented 3 years ago

Is that feature so brand new?

I changed to the master channel and your demo app is working fine. By the way, it now allow me to pan a little bit.

But my existing application doesn't work in the master channel... I will need to migrate a lot of things... :-(

xclud commented 3 years ago

Exactly, it's quite new.

As far as I know there is no breaking change in master channel. In your pubspec.yaml file make sure you are not on null-safety version.

environment:
  sdk: ">=2.7.0 <3.0.0"

If you have SDK version 2.12 you will get a whole lot of null-safety errors. Use SDK 2.11 or lower to stay on the safe side. SDK 2.7.0 I recommend as in above code.

Please let me know if this helps you.

pulstar commented 3 years ago

The environment line above is already configured in my pubspec.yaml How can I downgrade the SDK to 2.11?

xclud commented 3 years ago

Can you paste you pubspec file here?

xclud commented 3 years ago

Also a screenshot from the errors would help a lot.

pulstar commented 3 years ago

I downgrade with the command flutter downgrade, but it downgraded to SDK 2.10 in the master channel. This version doesn't have ScaffoldMessenger, the only thing I found different in this version.

With Dark 2.12 all errors are related to Null Safety. I will need to refactor a lot of things to make it work.

xclud commented 3 years ago

You need to upgrade flutter from master channel, indeed the newer the better. You can specify the dart-sdk version in pubspec and you are good to go.

pulstar commented 3 years ago

Will this work?

environment:
  sdk: ">=2.7.0 <2.12.0"
xclud commented 3 years ago

I guess so. Run flutter pub upgrade and you should be able to run your project.

pulstar commented 3 years ago

No luck changing that parameter... A lot of errors still remain. This existing application is huge, so I need time to migrate it.

xclud commented 3 years ago

I wish you a good luck migrating. I would help if you got questions.

pulstar commented 3 years ago

I will close this issue now, when I have news I come back here.