Take a screenshot of all content (including off-screen) in Flutter

41 Views Asked by At

I'm making software for Windows using Flutter. I've already done everything, I'm in the final step where I need to take a screenshot of the content of a SizedBox of size 5000x5000 and transform it into PNG. The problem is that the screenshot is always the size of the software window, even registering the overflow at the edges of the window. I need to record a screenshot of the content that is outside the window too (obviously without the overflow indicator). And I'm not using Listview, these are specific fixed widgets with data received from a local database.

My first attempt was using the screenshot package, but I had this problem with the window limits. I tried capturing the page itself, through the controller; and also "captureFromWidget", being called on the previous page and considering the entire page as a widget within "captureFromWidget". I thought of the solution of resizing the window to 5000x5000, taking a screenshot of the content and reducing the window to normal size back.

To resize I used the "desktop_window" package, and unfortunately it only resizes the window to the maximum size of my monitor. Because of this I tried a different package, "bitsdojo_window", and again the same problem, the maximum it resizes is to the size of my monitor, not reaching the 5000x5000 that I need.

I also tried wrapping 5000x5000 content with two SingleChildScrollview (one horizontal and one vertical) wrapped by two Scrollbar. It resolves to browsing the content, but not to taking the screenshot, being limited to the size of the window.

-

So I tried Flutter's own RenderRepaintBoundary, which is basically how the "screenshot" package works, but unfortunately, the same problem, limited by window size.

In the end, all my attempts resulted in a screenshot limited to the window. Is there any way to take a screenshot beyond the window limits? Is there a widget that renders and considers 5000x5000 to be registered within the "screenshot" or "RenderRepaintBoundary"? I tried OverflowBox and it didn't work either.

-

I need this software to work at least on a 1366x768 computer, so I can't have the screenshot limit within the window, as I need to capture 5000x5000, not just 1366x768.

1

There are 1 best solutions below

0
Matheus290 On

I can't believe it, after days of suffocating over the problem, I discovered the solution, and it's very simple. I did some Widget order tests and discovered that the RenderRepaintBoundary or Screenshot need to be INSIDE the SingleChildScrollView, and not before, as I was doing. Just that. The code looked like this:

return Scaffold(
    body: Scrollbar(
      controller: vertical,
      thumbVisibility: true,
      trackVisibility: true,
      child: Scrollbar(
          controller: horizontal,
          thumbVisibility: true,
          trackVisibility: true,
          notificationPredicate: (notif) => notif.depth == 1,
          child: SingleChildScrollView(
              controller: vertical,
              scrollDirection: Axis.vertical,
              child: SingleChildScrollView(
                  scrollDirection: Axis.horizontal,
                  controller: horizontal,
                  child: Screenshot(
                    controller: screenshotController,
                    child: SizedBox(...

I want to thank pskink too, although unfortunately I didn't see his answer before, the solution can also be found there!