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

Image.toByteData and Picture.toImage implementations (#3) #20750

Merged
merged 87 commits into from
Sep 2, 2020
Merged

Image.toByteData and Picture.toImage implementations (#3) #20750

merged 87 commits into from
Sep 2, 2020

Conversation

deakjahn
Copy link
Contributor

@deakjahn deakjahn commented Aug 25, 2020

Description

  • Image.toByteData() was not implemented in either DomCanvas or CanvasKit. This PR covers both.
  • Picture.toImage() was not implemented in either DomCanvas or CanvasKit. This PR covers CanvasKit (I also have a solution for DomCanvas but that would need some discussion, it might clash with functionality somewhere else; details in a comment below).

Related Issues

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the contributor guide and followed the process outlined there for submitting PRs.
  • I signed the CLA.
  • I read and followed the C++, Objective-C, Java style guides for the engine.
  • I read the tree hygiene wiki page, which explains my responsibilities.
  • I updated/added relevant documentation.
  • All existing and new tests are passing.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Did any tests fail when you ran them? Please read handling breaking changes.

  • No, no existing tests failed, so this is not a breaking change.
  • Yes, this is a breaking change. If not, delete the remainder of this section.

engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Sep 3, 2020
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Sep 3, 2020
zanderso pushed a commit to flutter/flutter that referenced this pull request Sep 3, 2020
* 5e54c70 Reland: Enable hybrid composition by default on Android (#20722) (flutter/engine#20864)

* 9398717 Roll Skia from db5582b71116 to 44e96bee4b6a (4 revisions) (flutter/engine#20908)

* 5f49a95 Add auto plugin registration to FlutterFragmentActivity as well (flutter/engine#20865)

* c4c4f34 Wait for first frame before checking layer tree (flutter/engine#20910)

* 0773bf0 Roll Skia from 44e96bee4b6a to 3913d3e137ed (2 revisions) (flutter/engine#20909)

* 8ec8af7 [windows] Add horizontal scroll support (flutter/engine#20668)

* 1bd9b8e Reset Shell::weak_factory_gpu_ on the raster thread (flutter/engine#20869)

* d67923f Pass text input key events to the EventResponder if they do not yield characters (flutter/engine#20912)

* abe10d1 Roll Dart SDK from 84c3eacc7ba0 to 6eab35f49cbb (2 revisions) (flutter/engine#20913)

* 101316b [web] migrate from e2e to integration_test (flutter/engine#20914)

* 1f52ec3 Roll Dart SDK from 6eab35f49cbb to 2a5f37d25453 (1 revision) (flutter/engine#20917)

* 8019058 Default C++ wrapper templates to EncodableValue (flutter/engine#20760)

* 5f3ec38 Roll Fuchsia Mac SDK from sI2DAAmSI... to waj2pOhDh... (flutter/engine#20919)

* a651020 Roll Fuchsia Linux SDK from _SVZn8uN2... to 9tLNFbjA1... (flutter/engine#20920)

* 696c2aa Roll Skia from 3913d3e137ed to 7b46300fe4ff (4 revisions) (flutter/engine#20924)

* 95f2b72 Create root isolate asynchronously (flutter/engine#20142)

* 58a6207 Adds fuchsia node roles to accessibility bridge updates. (flutter/engine#20385)

* a762143 Roll Dart SDK from 2a5f37d25453 to e8e0d5a539fb (3 revisions) (flutter/engine#20928)

* 49d6805 Ensure all images are closed in FlutterImageView (flutter/engine#20842)

* d67bda7 Image.toByteData and Picture.toImage implementations (#3) (flutter/engine#20750)

* 96efe39 Revert "Adds fuchsia node roles to accessibility bridge updates. (#20385)" (flutter/engine#20936)

* 5585ed9 Revert "Create root isolate asynchronously (#20142)" (flutter/engine#20937)

* f6270c0 Roll Dart SDK from e8e0d5a539fb to b29f228f62e2 (3 revisions) (flutter/engine#20939)

* 15bf1bb [Android R] Integrate DisplayCutouts into viewportMetrics (flutter/engine#20921)

* 615e668 Clear the GL context only after submitting the frame (flutter/engine#20931)

* ca989b8 Roll Skia from 7b46300fe4ff to 1338a37a1add (16 revisions) (flutter/engine#20943)

* 8f3f711 Roll Fuchsia Linux SDK from 9tLNFbjA1... to knpSoAoZq... (flutter/engine#20944)

* 873c007 Log exception in addition to the stack trace for unhandled exceptions. (flutter/engine#20935)

* d761629 Roll Skia from 1338a37a1add to 8fa3b4e8cde5 (6 revisions) (flutter/engine#20949)

* f6920da Roll Skia from 8fa3b4e8cde5 to e9a9ad908226 (5 revisions) (flutter/engine#20952)

* 634e499 Use hint freed specifically for image disposal (flutter/engine#20754)

* c700479 Revert external size changes to Picture (flutter/engine#20950)

* 4353797 Roll Skia from e9a9ad908226 to 3d1d636cd839 (6 revisions) (flutter/engine#20955)

* 80f4481 renaming e2e tests to integration (flutter/engine#20954)

* 61e057a Clear GL context before Gr context (flutter/engine#20957)

* f43c3d7 Roll Fuchsia Mac SDK from waj2pOhDh... to 0r88gDzUP... (flutter/engine#20958)

* 5a2db33 Roll Skia from 3d1d636cd839 to 683beccf6776 (13 revisions) (flutter/engine#20961)

* efb339f Only clear GL context after changing the thread configuration (flutter/engine#20965)

* 58d5132 Roll Fuchsia Linux SDK from knpSoAoZq... to odFvFQV9Z... (flutter/engine#20968)

* 3729fdb Roll Skia from 683beccf6776 to a66a9c31a318 (4 revisions) (flutter/engine#20969)

* 40fe7f3 Roll Fuchsia Mac SDK from 0r88gDzUP... to gOI3W1UNU... (flutter/engine#20970)

* e979c29 Roll Skia from a66a9c31a318 to be72801f29f9 (1 revision) (flutter/engine#20971)
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Sep 3, 2020
flar pushed a commit to flutter/flutter that referenced this pull request Sep 3, 2020
* 5e54c70 Reland: Enable hybrid composition by default on Android (#20722) (flutter/engine#20864)

* 9398717 Roll Skia from db5582b71116 to 44e96bee4b6a (4 revisions) (flutter/engine#20908)

* 5f49a95 Add auto plugin registration to FlutterFragmentActivity as well (flutter/engine#20865)

* c4c4f34 Wait for first frame before checking layer tree (flutter/engine#20910)

* 0773bf0 Roll Skia from 44e96bee4b6a to 3913d3e137ed (2 revisions) (flutter/engine#20909)

* 8ec8af7 [windows] Add horizontal scroll support (flutter/engine#20668)

* 1bd9b8e Reset Shell::weak_factory_gpu_ on the raster thread (flutter/engine#20869)

* d67923f Pass text input key events to the EventResponder if they do not yield characters (flutter/engine#20912)

* abe10d1 Roll Dart SDK from 84c3eacc7ba0 to 6eab35f49cbb (2 revisions) (flutter/engine#20913)

* 101316b [web] migrate from e2e to integration_test (flutter/engine#20914)

* 1f52ec3 Roll Dart SDK from 6eab35f49cbb to 2a5f37d25453 (1 revision) (flutter/engine#20917)

* 8019058 Default C++ wrapper templates to EncodableValue (flutter/engine#20760)

* 5f3ec38 Roll Fuchsia Mac SDK from sI2DAAmSI... to waj2pOhDh... (flutter/engine#20919)

* a651020 Roll Fuchsia Linux SDK from _SVZn8uN2... to 9tLNFbjA1... (flutter/engine#20920)

* 696c2aa Roll Skia from 3913d3e137ed to 7b46300fe4ff (4 revisions) (flutter/engine#20924)

* 95f2b72 Create root isolate asynchronously (flutter/engine#20142)

* 58a6207 Adds fuchsia node roles to accessibility bridge updates. (flutter/engine#20385)

* a762143 Roll Dart SDK from 2a5f37d25453 to e8e0d5a539fb (3 revisions) (flutter/engine#20928)

* 49d6805 Ensure all images are closed in FlutterImageView (flutter/engine#20842)

* d67bda7 Image.toByteData and Picture.toImage implementations (#3) (flutter/engine#20750)

* 96efe39 Revert "Adds fuchsia node roles to accessibility bridge updates. (#20385)" (flutter/engine#20936)

* 5585ed9 Revert "Create root isolate asynchronously (#20142)" (flutter/engine#20937)

* f6270c0 Roll Dart SDK from e8e0d5a539fb to b29f228f62e2 (3 revisions) (flutter/engine#20939)

* 15bf1bb [Android R] Integrate DisplayCutouts into viewportMetrics (flutter/engine#20921)

* 615e668 Clear the GL context only after submitting the frame (flutter/engine#20931)

* ca989b8 Roll Skia from 7b46300fe4ff to 1338a37a1add (16 revisions) (flutter/engine#20943)

* 8f3f711 Roll Fuchsia Linux SDK from 9tLNFbjA1... to knpSoAoZq... (flutter/engine#20944)

* 873c007 Log exception in addition to the stack trace for unhandled exceptions. (flutter/engine#20935)

* d761629 Roll Skia from 1338a37a1add to 8fa3b4e8cde5 (6 revisions) (flutter/engine#20949)

* f6920da Roll Skia from 8fa3b4e8cde5 to e9a9ad908226 (5 revisions) (flutter/engine#20952)

* 634e499 Use hint freed specifically for image disposal (flutter/engine#20754)

* c700479 Revert external size changes to Picture (flutter/engine#20950)

* 4353797 Roll Skia from e9a9ad908226 to 3d1d636cd839 (6 revisions) (flutter/engine#20955)

* 80f4481 renaming e2e tests to integration (flutter/engine#20954)

* 61e057a Clear GL context before Gr context (flutter/engine#20957)

* f43c3d7 Roll Fuchsia Mac SDK from waj2pOhDh... to 0r88gDzUP... (flutter/engine#20958)

* 5a2db33 Roll Skia from 3d1d636cd839 to 683beccf6776 (13 revisions) (flutter/engine#20961)

* efb339f Only clear GL context after changing the thread configuration (flutter/engine#20965)

* 58d5132 Roll Fuchsia Linux SDK from knpSoAoZq... to odFvFQV9Z... (flutter/engine#20968)

* 3729fdb Roll Skia from 683beccf6776 to a66a9c31a318 (4 revisions) (flutter/engine#20969)

* 40fe7f3 Roll Fuchsia Mac SDK from 0r88gDzUP... to gOI3W1UNU... (flutter/engine#20970)

* e979c29 Roll Skia from a66a9c31a318 to be72801f29f9 (1 revision) (flutter/engine#20971)

* 6e8930b Roll Skia from be72801f29f9 to f8823b572600 (1 revision) (flutter/engine#20973)

* 68b7b84 [fuchsia] Send trace events to system tracing on all configurations (flutter/engine#20974)

* 3f05b52 Always set the callback during Rasterizer setup (flutter/engine#20976)
mingwandroid pushed a commit to mingwandroid/flutter that referenced this pull request Sep 6, 2020
* 5e54c70 Reland: Enable hybrid composition by default on Android (flutter#20722) (flutter/engine#20864)

* 9398717 Roll Skia from db5582b71116 to 44e96bee4b6a (4 revisions) (flutter/engine#20908)

* 5f49a95 Add auto plugin registration to FlutterFragmentActivity as well (flutter/engine#20865)

* c4c4f34 Wait for first frame before checking layer tree (flutter/engine#20910)

* 0773bf0 Roll Skia from 44e96bee4b6a to 3913d3e137ed (2 revisions) (flutter/engine#20909)

* 8ec8af7 [windows] Add horizontal scroll support (flutter/engine#20668)

* 1bd9b8e Reset Shell::weak_factory_gpu_ on the raster thread (flutter/engine#20869)

* d67923f Pass text input key events to the EventResponder if they do not yield characters (flutter/engine#20912)

* abe10d1 Roll Dart SDK from 84c3eacc7ba0 to 6eab35f49cbb (2 revisions) (flutter/engine#20913)

* 101316b [web] migrate from e2e to integration_test (flutter/engine#20914)

* 1f52ec3 Roll Dart SDK from 6eab35f49cbb to 2a5f37d25453 (1 revision) (flutter/engine#20917)

* 8019058 Default C++ wrapper templates to EncodableValue (flutter/engine#20760)

* 5f3ec38 Roll Fuchsia Mac SDK from sI2DAAmSI... to waj2pOhDh... (flutter/engine#20919)

* a651020 Roll Fuchsia Linux SDK from _SVZn8uN2... to 9tLNFbjA1... (flutter/engine#20920)

* 696c2aa Roll Skia from 3913d3e137ed to 7b46300fe4ff (4 revisions) (flutter/engine#20924)

* 95f2b72 Create root isolate asynchronously (flutter/engine#20142)

* 58a6207 Adds fuchsia node roles to accessibility bridge updates. (flutter/engine#20385)

* a762143 Roll Dart SDK from 2a5f37d25453 to e8e0d5a539fb (3 revisions) (flutter/engine#20928)

* 49d6805 Ensure all images are closed in FlutterImageView (flutter/engine#20842)

* d67bda7 Image.toByteData and Picture.toImage implementations (flutter#3) (flutter/engine#20750)

* 96efe39 Revert "Adds fuchsia node roles to accessibility bridge updates. (flutter#20385)" (flutter/engine#20936)

* 5585ed9 Revert "Create root isolate asynchronously (flutter#20142)" (flutter/engine#20937)

* f6270c0 Roll Dart SDK from e8e0d5a539fb to b29f228f62e2 (3 revisions) (flutter/engine#20939)

* 15bf1bb [Android R] Integrate DisplayCutouts into viewportMetrics (flutter/engine#20921)

* 615e668 Clear the GL context only after submitting the frame (flutter/engine#20931)

* ca989b8 Roll Skia from 7b46300fe4ff to 1338a37a1add (16 revisions) (flutter/engine#20943)

* 8f3f711 Roll Fuchsia Linux SDK from 9tLNFbjA1... to knpSoAoZq... (flutter/engine#20944)

* 873c007 Log exception in addition to the stack trace for unhandled exceptions. (flutter/engine#20935)

* d761629 Roll Skia from 1338a37a1add to 8fa3b4e8cde5 (6 revisions) (flutter/engine#20949)

* f6920da Roll Skia from 8fa3b4e8cde5 to e9a9ad908226 (5 revisions) (flutter/engine#20952)

* 634e499 Use hint freed specifically for image disposal (flutter/engine#20754)

* c700479 Revert external size changes to Picture (flutter/engine#20950)

* 4353797 Roll Skia from e9a9ad908226 to 3d1d636cd839 (6 revisions) (flutter/engine#20955)

* 80f4481 renaming e2e tests to integration (flutter/engine#20954)

* 61e057a Clear GL context before Gr context (flutter/engine#20957)

* f43c3d7 Roll Fuchsia Mac SDK from waj2pOhDh... to 0r88gDzUP... (flutter/engine#20958)

* 5a2db33 Roll Skia from 3d1d636cd839 to 683beccf6776 (13 revisions) (flutter/engine#20961)

* efb339f Only clear GL context after changing the thread configuration (flutter/engine#20965)

* 58d5132 Roll Fuchsia Linux SDK from knpSoAoZq... to odFvFQV9Z... (flutter/engine#20968)

* 3729fdb Roll Skia from 683beccf6776 to a66a9c31a318 (4 revisions) (flutter/engine#20969)

* 40fe7f3 Roll Fuchsia Mac SDK from 0r88gDzUP... to gOI3W1UNU... (flutter/engine#20970)

* e979c29 Roll Skia from a66a9c31a318 to be72801f29f9 (1 revision) (flutter/engine#20971)
mingwandroid pushed a commit to mingwandroid/flutter that referenced this pull request Sep 6, 2020
* 5e54c70 Reland: Enable hybrid composition by default on Android (flutter#20722) (flutter/engine#20864)

* 9398717 Roll Skia from db5582b71116 to 44e96bee4b6a (4 revisions) (flutter/engine#20908)

* 5f49a95 Add auto plugin registration to FlutterFragmentActivity as well (flutter/engine#20865)

* c4c4f34 Wait for first frame before checking layer tree (flutter/engine#20910)

* 0773bf0 Roll Skia from 44e96bee4b6a to 3913d3e137ed (2 revisions) (flutter/engine#20909)

* 8ec8af7 [windows] Add horizontal scroll support (flutter/engine#20668)

* 1bd9b8e Reset Shell::weak_factory_gpu_ on the raster thread (flutter/engine#20869)

* d67923f Pass text input key events to the EventResponder if they do not yield characters (flutter/engine#20912)

* abe10d1 Roll Dart SDK from 84c3eacc7ba0 to 6eab35f49cbb (2 revisions) (flutter/engine#20913)

* 101316b [web] migrate from e2e to integration_test (flutter/engine#20914)

* 1f52ec3 Roll Dart SDK from 6eab35f49cbb to 2a5f37d25453 (1 revision) (flutter/engine#20917)

* 8019058 Default C++ wrapper templates to EncodableValue (flutter/engine#20760)

* 5f3ec38 Roll Fuchsia Mac SDK from sI2DAAmSI... to waj2pOhDh... (flutter/engine#20919)

* a651020 Roll Fuchsia Linux SDK from _SVZn8uN2... to 9tLNFbjA1... (flutter/engine#20920)

* 696c2aa Roll Skia from 3913d3e137ed to 7b46300fe4ff (4 revisions) (flutter/engine#20924)

* 95f2b72 Create root isolate asynchronously (flutter/engine#20142)

* 58a6207 Adds fuchsia node roles to accessibility bridge updates. (flutter/engine#20385)

* a762143 Roll Dart SDK from 2a5f37d25453 to e8e0d5a539fb (3 revisions) (flutter/engine#20928)

* 49d6805 Ensure all images are closed in FlutterImageView (flutter/engine#20842)

* d67bda7 Image.toByteData and Picture.toImage implementations (flutter#3) (flutter/engine#20750)

* 96efe39 Revert "Adds fuchsia node roles to accessibility bridge updates. (flutter#20385)" (flutter/engine#20936)

* 5585ed9 Revert "Create root isolate asynchronously (flutter#20142)" (flutter/engine#20937)

* f6270c0 Roll Dart SDK from e8e0d5a539fb to b29f228f62e2 (3 revisions) (flutter/engine#20939)

* 15bf1bb [Android R] Integrate DisplayCutouts into viewportMetrics (flutter/engine#20921)

* 615e668 Clear the GL context only after submitting the frame (flutter/engine#20931)

* ca989b8 Roll Skia from 7b46300fe4ff to 1338a37a1add (16 revisions) (flutter/engine#20943)

* 8f3f711 Roll Fuchsia Linux SDK from 9tLNFbjA1... to knpSoAoZq... (flutter/engine#20944)

* 873c007 Log exception in addition to the stack trace for unhandled exceptions. (flutter/engine#20935)

* d761629 Roll Skia from 1338a37a1add to 8fa3b4e8cde5 (6 revisions) (flutter/engine#20949)

* f6920da Roll Skia from 8fa3b4e8cde5 to e9a9ad908226 (5 revisions) (flutter/engine#20952)

* 634e499 Use hint freed specifically for image disposal (flutter/engine#20754)

* c700479 Revert external size changes to Picture (flutter/engine#20950)

* 4353797 Roll Skia from e9a9ad908226 to 3d1d636cd839 (6 revisions) (flutter/engine#20955)

* 80f4481 renaming e2e tests to integration (flutter/engine#20954)

* 61e057a Clear GL context before Gr context (flutter/engine#20957)

* f43c3d7 Roll Fuchsia Mac SDK from waj2pOhDh... to 0r88gDzUP... (flutter/engine#20958)

* 5a2db33 Roll Skia from 3d1d636cd839 to 683beccf6776 (13 revisions) (flutter/engine#20961)

* efb339f Only clear GL context after changing the thread configuration (flutter/engine#20965)

* 58d5132 Roll Fuchsia Linux SDK from knpSoAoZq... to odFvFQV9Z... (flutter/engine#20968)

* 3729fdb Roll Skia from 683beccf6776 to a66a9c31a318 (4 revisions) (flutter/engine#20969)

* 40fe7f3 Roll Fuchsia Mac SDK from 0r88gDzUP... to gOI3W1UNU... (flutter/engine#20970)

* e979c29 Roll Skia from a66a9c31a318 to be72801f29f9 (1 revision) (flutter/engine#20971)

* 6e8930b Roll Skia from be72801f29f9 to f8823b572600 (1 revision) (flutter/engine#20973)

* 68b7b84 [fuchsia] Send trace events to system tracing on all configurations (flutter/engine#20974)

* 3f05b52 Always set the callback during Rasterizer setup (flutter/engine#20976)
final data = UriData.fromUri(Uri.parse(imgElement.src!));
return Future.value(data.contentAsBytes().buffer.asByteData());
} else {
return Future.value(null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should probably throw instead of returning null. This indicates we don't support the format. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't know what you normally do in a situation like that. If throw, than throw it is.

Future<ByteData?> toByteData({ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba}) {
if (imgElement.src?.startsWith('data:') == true) {
final data = UriData.fromUri(Uri.parse(imgElement.src!));
return Future.value(data.contentAsBytes().buffer.asByteData());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ignores the format parameter. It's not entirely clear to me what format the data: URI is in, I'm trying to test this and I'm only seeing regular URIs or blob URIs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, this was some time ago already, we spent some with finalizing the PR, so the code itself is even older. Let me think. I seem to remember PNG was the only format available in the data URL, so it simply couldn't support anything else. The possibilities are:

  • Only serve PNG, throw for the others,
  • Always serve PNG, no matter what is asked for (current),
  • Convert if something else than PNG is asked for (unlikely, I guess).

@monsieurtanuki
Copy link

For what it's worth, I've just run a simple Picture.toImage test on both iOS and web, and it crashed on web with an Unexpected null value. (in that case the Picture being instantiated as an EnginePicture)
I don't know what is supposed to be currently merged on what flutter channel; sorry if I've tested much too early.
I hope this will be fixed soon: thanks in advance :)

flutter doctor
[✓] Flutter (Channel beta, 1.23.0-18.1.pre, on Mac OS X 10.15.5 19F101 x86_64,
    locale fr-FR)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 12.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.1)
 
[✓] Connected device (3 available)            

• No issues found!
simple Picture.toImage test
ui.PictureRecorder recorder = new ui.PictureRecorder();
new Canvas(recorder, Rect.fromLTRB(0, 0, 100, 200));
ui.Picture picture = recorder.endRecording();
try {
  var img = await picture.toImage(100, 200);
} catch (e) {
  print(e);
}

@deakjahn
Copy link
Contributor Author

The very first question is whether CanvasKit or DomCanvas. As you can read in the OP, the Picture variant was only done for the first (I described in one of the related issues what could be the solution to the DomCanvas case but that was beyond the scope of a relatively simple PR).

@monsieurtanuki
Copy link

@deakjahn Köszönöm! I've just run my test on debug with CanvasKit on my Mac (flutter run -d chrome --dart-define=FLUTTER_WEB_USE_SKIA=true) and it was successful. I mean, the Picture.toImage part was successful. The rest of the interface was a bit bumpy, though.
I'm still curious to see how this will work on release mode, and on a mobile.

Regarding DomCanvas, you say that this PR fixes Image.toByteData(), but not Picture.toImage().
And in a comment you say

If at least one of the two worked (Picture.toImage() or Image.toByteData()), the first could provide a workaround for the second. Not pretty but a workaround, nonetheless.

I cannot picture (ahah) how I could rely only on Image.toByteData() and not on Picture.toImage(). In my case I create a ui.PictureRecorder to paint on it, and then get a Picture with recorder.endRecording().

Questions:

  1. what was your idea on a workaround to emulate Picture.toImage() from Image.toByteData(), even in an ugly way?
  2. do you know if there is a pending issue or PR about Picture.toImage() on DomCanvas?

@deakjahn
Copy link
Contributor Author

That comment was written before I started to work on the PR. I've been complaining about the lack of support for some time then, finally, I started to see how I could fix it myself instead of waiting for the Flutter team to do it. :-))

Basically, I wasn't particulary interested in DomCanvas because, for my work, I switched to CanvasKit completely (both for performance and because I needed many features that were only available in the new engine, anyway). But when I set out to create the PR, I was obviously trying to cover both engines, if possible.

Now, I don't think there is a PR, or even any work done on that case for that matter. There is a post "DomCanvas case" early in this thread, check that out. The change would be straightforward but while it would fix this case, it would also probably break some others. To avoid the regression, some refactoring would be needed.

@deakjahn
Copy link
Contributor Author

Wait a minute, Picture null and turning the canvas into an image, that's it, right? Then I must have thought of this, I also answered about this on SO and was at same point, while still in DomCanvas, using this solution: https://stackoverflow.com/questions/56052004/capturing-a-canvas-as-an-image-in-flutter-web/61960761#61960761

@monsieurtanuki
Copy link

@deakjahn Thank you for your help and all your remarks.

Regarding HTML5's canvas.context2D it's not that simple: I have tons of drawing operations. And I would need to maintain both canvas and context2D - or rather create some kind of meta canvas - hoping that all the drawing methods I need are available in both, and that the resulting picture looks more or less the same. Looks like an interesting new pub lib to develop ;)

@deakjahn
Copy link
Contributor Author

And are you sure you wouldn't be better off using CanvasKit?

@monsieurtanuki
Copy link

@deakjahn I'm not sure of anything; I just want to know all the possibilities.

Using CanvasKit is a possibility, but it is branded as "highly experimental" and I've already experienced glitches in the UI.
I don't feel like devoting time into fixing CanvasKit. After all the good job you did on DomCanvas, your involvement and your understanding of the case, I guess it's not that straightforward to fix it for CanvasKit too (with the refactoring you suggested).

I know it will take me about a day to run my tests about my "meta canvas" solution, and that's a visibility I'm ok with.

@deakjahn
Copy link
Contributor Author

That's the other way around. I primarily did it for CanvasKit, not DomCanvas. I wouldn't call it experimental any more (yes, Google has to be careful in the documentation) but more like work in progress. In my actual work where I needed to have the same Skia-based graphics support that I already use on Android and iOS, it was indispensable for me, that's why I moved to CanvasKit definitely. I don't find any serious issues with CanvasKit nowadays, so, even if it's not yet officially done, I'm quite comfortable with using it.

@monsieurtanuki
Copy link

@deakjahn Correct: my problem is with DomCanvas.
I mean, "was with DomCanvas", as I managed to code an elegant meta layer for the canvas and the SVG path operations, that now work on both the standard flutter Canvas and html.CanvasRenderingContext2D.
As you provided some javascript code in order to download an html canvas into a picture file, I'm finished! Thanks again.

@lukemadera
Copy link

@deakjahn Thanks for all your work on this! Is there a fix for picture.toImage for DomCanvas or is it still broken? I'm having this issue when I use the html renderer (which we use for deploys) but not when I use the canvaskit renderer (local development).

@deakjahn
Copy link
Contributor Author

deakjahn commented May 28, 2021

I really don't know, I left DomCanvas quite some time ago and never looked back. The last time I checked the problem was as described in #20750 (comment).

Come to think of it, this is the same problem I mentioned as a "Known problem" with my https://github.com/deakjahn/crop_image package... I'll link to this issue then.

@lukemadera
Copy link

Ok, thanks for the prompt reply; seems it still doesn't work then :(

@tolotrasamuel
Copy link

Steps to reproduce:

  1. On Flutter Web, Wrap Flutter Google Maps in a RepaintBoundary

Like so:

  @override
  Widget build(BuildContext context) {
    return RepaintBoundary(
      key: ScreenShotable.previewContainer,
      child: widget.child,
    );
  }

Usage:

final img = await screenshotController.captureAsUiImage(
        Container(
          height: 100,
          width: 100,
          color: Colors.brown,
          child: GoogleMap(
            initialCameraPosition: CameraPosition(
              target: FlitLatLng(-20.1020344, 57.5621812999999).toLatLng(),
              zoom: 13.0,
            ),
            rotateGesturesEnabled: false,
            tiltGesturesEnabled: false,
            // markers: Set<Marker>.of(controller.markers.values),
          ),
        ),
        delay: Duration(seconds: 6));

ScreenshotControllers.captureAsUiImage

RenderRepaintBoundary boundary =
    this.view!.context.findRenderObject() as RenderRepaintBoundary;
ui.Image image = await boundary.toImage(pixelRatio: pxRatio); // crash here

Actual:

Error: Unexpected null value.
    at Object.throw_ [as throw] (http://localhost:49196/dart_sdk.js:5037:11)
    at Object.nullCheck (http://localhost:49196/dart_sdk.js:5362:30)
    at _engine.PlatformViewLayer.new.preroll (http://localhost:49196/dart_sdk.js:135222:12)
    at _engine.OffsetEngineLayer.new.prerollChildren (http://localhost:49196/dart_sdk.js:134614:15)
    at _engine.OffsetEngineLayer.new.preroll (http://localhost:49196/dart_sdk.js:134881:35)
    at _engine.OffsetEngineLayer.new.prerollChildren (http://localhost:49196/dart_sdk.js:134614:15)
    at _engine.OffsetEngineLayer.new.preroll (http://localhost:49196/dart_sdk.js:134881:35)
    at _engine.TransformEngineLayer.new.prerollChildren (http://localhost:49196/dart_sdk.js:134614:15)
    at _engine.TransformEngineLayer.new.preroll (http://localhost:49196/dart_sdk.js:134881:35)
    at _engine.RootLayer.new.prerollChildren (http://localhost:49196/dart_sdk.js:134614:15)
    at _engine.RootLayer.new.preroll (http://localhost:49196/dart_sdk.js:134609:31)
    at _engine.LayerTree.new.flatten (http://localhost:49196/dart_sdk.js:135508:22)
    at _engine.LayerScene.new.toImage (http://localhost:49196/dart_sdk.js:135263:36)
    at layer$.OffsetLayer.new.toImage (http://localhost:49196/packages/flutter/src/rendering/layer.dart.js:1327:30)
    at toImage.next (<anonymous>)
    at runBody (http://localhost:49196/dart_sdk.js:37393:34)
    at Object._async [as async] (http://localhost:49196/dart_sdk.js:37424:7)
    at layer$.OffsetLayer.new.toImage (http://localhost:49196/packages/flutter/src/rendering/layer.dart.js:1318:20)
    at proxy_box.RenderRepaintBoundary.new.toImage (http://localhost:49196/packages/flutter/src/rendering/proxy_box.dart.js:3096:26)
    at captureFromWidget (http://localhost:49196/packages/screenshot/screenshot.dart.js:242:44)
    at captureFromWidget.next (<anonymous>)
    at http://localhost:49196/dart_sdk.js:37374:33
    at _RootZone.runUnary (http://localhost:49196/dart_sdk.js:37245:59)
    at _FutureListener.thenAwait.handleValue (http://localhost:49196/dart_sdk.js:32501:29)
    at handleValueCallback (http://localhost:49196/dart_sdk.js:33028:49)
    at Function._propagateToListeners (http://localhost:49196/dart_sdk.js:33066:17)
    at _Future.new.[_complete] (http://localhost:49196/dart_sdk.js:32906:25)
    at http://localhost:49196/dart_sdk.js:32085:30
    at internalCallback (http://localhost:49196/dart_sdk.js:24224:11)

Expected:

No crash. Even better if we get the screenshot of the map.
On Mobile, we get blank screen.

Further debugging:

I tried with my own code above and even with the https://pub.dev/packages/screenshot package. Same result

If you have any clue on what the error above means, I would appreciate, even a small comment. It will help me find a workaround

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