2

I am trying to take a screenshot of a widget and save it as a png.

Its working fine for macos and ios but not for desktop(chrome).

The file downloaded from browser seems to be not encoded correct, I have tried a lot of different encodings but cant get it working.

Would be nice if someone knows how to encode the image so its downloaded correct in web too.

    final boundary = _boundaryKey.currentContext.findRenderObject() as RenderRepaintBoundary;
    final image = await boundary.toImage(pixelRatio: 2);
    final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    final pngBytes = byteData.buffer.asUint8List();

    if (kIsWeb) {
        final blob = html.Blob(<dynamic>[base64Encode(pngBytes)], 'image/png');
        final anchorElement = html.AnchorElement(
          href: html.Url.createObjectUrlFromBlob(blob),
        )
          ..setAttribute('download', 'details.png')
          ..click();
    } else {
        await File('details_${widget.order.id}'.trim().replaceAll(' ', '_')).writeAsBytes(pngBytes);
    }
passsy
  • 5,162
  • 4
  • 39
  • 65
Steven Dz
  • 89
  • 5

1 Answers1

4

The trick is to set 'application/octet-stream' when creating the Blob

final fileName = 'details_${widget.order.id.trim().replaceAll(' ', '_')}';
final boundary = _boundaryKey.currentContext.findRenderObject() as RenderRepaintBoundary;
final image = await boundary.toImage(pixelRatio: 2);
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
final pngBytes = byteData.buffer.asUint8List();
final blob = html.Blob(<dynamic>[pngBytes], 'application/octet-stream');
html.AnchorElement(href: html.Url.createObjectUrlFromBlob(blob))
    ..setAttribute('download', fileName)
    ..click();
passsy
  • 5,162
  • 4
  • 39
  • 65