flutter icon indicating copy to clipboard operation
flutter copied to clipboard

RenderRepaintBoundary screenshot sometimes fails to render images

Open BaroneX opened this issue 4 years ago • 21 comments

Steps to Reproduce

1.Use RepaintBoundary widget, with an Image as a child. 2.Use RenderRepaintBoundary to generate screenshots 3.Sometimes the image component is not rendered in the screenshot

Future<ByteData> _capturePngToByteData() async {
    try {
      RenderRepaintBoundary boundary =
          repaintWidgetKey.currentContext.findRenderObject();
      boundary =
          repaintWidgetKey.currentContext.findRenderObject();
      double dpr = ui.window.devicePixelRatio;
      ui.Image image = await boundary.toImage(pixelRatio: dpr);
      ByteData _byteData =
          await image.toByteData(format: ui.ImageByteFormat.png);
      return _byteData;
    } catch (e) {
      print(e);
    }
    return null;
  }

Expected results: the image component is rendered in the screenshot

Actual results: Sometimes the image component is not rendered in the screenshot The user avatar and background image are not rendered in the screenshot

Devices iPhone 12(14.3)

Logs
⚡ flutter analyze
Analyzing iOS...                                                        
No issues found! (ran in 0.8s)
⚡ flutter doctor -v
[✓] Flutter (Channel unknown, 1.22.5, on Mac OS X 10.15.5 19F101 darwin-x64, locale zh-Hans-CN)
    • Flutter version 1.22.5 at /Users/blake/flutter/flutter
    • Framework revision 7891006299 (8 周前), 2020-12-10 11:54:40 -0800
    • Engine revision ae90085a84
    • Dart version 2.10.4
    • Pub download mirror https://pub.flutter-io.cn
    • Flutter download mirror https://storage.flutter-io.cn

 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at /Users/blake/Library/Android/sdk
    • Platform android-29, build-tools 29.0.2
    • ANDROID_HOME = /Users/blake/Library/Android/sdk
    • 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-1343-b01)
    • All Android licenses accepted.

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

[✓] Android Studio (version 3.4)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 39.0.1
    • Dart plugin version 183.6270
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)

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

BaroneX avatar Feb 03 '21 09:02 BaroneX

Hi @BaroneX Here I created a complete runnable code sample based on your snippet, output looks fine physical or emulator/simulator

Ouput

iOS Android
exported_image exported_image

Try the code sample below

code sample
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:path_provider/path_provider.dart';

void main() => runApp(MyApp());

class UiImagePainter extends CustomPainter {
  final ui.Image image;

  UiImagePainter(this.image);

  @override
  void paint(ui.Canvas canvas, ui.Size size) {
    // simple aspect fit for the image
    var hr = size.height / image.height;
    var wr = size.width / image.width;

    double ratio;
    double translateX;
    double translateY;
    if (hr < wr) {
      ratio = hr;
      translateX = (size.width - (ratio * image.width)) / 2;
      translateY = 0.0;
    } else {
      ratio = wr;
      translateX = 0.0;
      translateY = (size.height - (ratio * image.height)) / 2;
    }

    canvas.translate(translateX, translateY);
    canvas.scale(ratio, ratio);
    canvas.drawImage(image, new Offset(0.0, 0.0), new Paint());
  }

  @override
  bool shouldRepaint(UiImagePainter other) {
    return other.image != image;
  }
}

class UiImageDrawer extends StatelessWidget {
  final ui.Image image;

  const UiImageDrawer({Key key, this.image}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      size: Size.infinite,
      painter: UiImagePainter(image),
    );
  }
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  GlobalKey<OverRepaintBoundaryState> globalKey = GlobalKey();

  ui.Image image;

  Future<void> writeToFile(ByteData data, String path) {
    final buffer = data.buffer;
    return new File(path).writeAsBytes(
        buffer.asUint8List(data.offsetInBytes, data.lengthInBytes));
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: image == null
            ? Capturer(
                overRepaintKey: globalKey,
              )
            : UiImageDrawer(image: image),
        floatingActionButton: image == null
            ? FloatingActionButton(
                child: Icon(Icons.camera),
                onPressed: () async {
                  var renderObject =
                      globalKey.currentContext.findRenderObject();

                  RenderRepaintBoundary boundary = renderObject;

                  ui.Image captureImage = await boundary.toImage();
                  String dir = (await getApplicationDocumentsDirectory()).path;

                  print(dir);

                  ByteData _byteData = await captureImage.toByteData(
                      format: ui.ImageByteFormat.png);
                  writeToFile(_byteData, "$dir/exported_image.png");
                  setState(() => image = captureImage);
                },
              )
            : FloatingActionButton(
                onPressed: () => setState(() => image = null),
                child: Icon(Icons.remove),
              ),
      ),
    );
  }
}

class Capturer extends StatelessWidget {
  static final Random random = Random();

  final GlobalKey<OverRepaintBoundaryState> overRepaintKey;

  const Capturer({Key key, this.overRepaintKey}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: OverRepaintBoundary(
        key: overRepaintKey,
        child: RepaintBoundary(
          child: Card(
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(25),
            ),
            child: Container(
              margin: const EdgeInsets.all(20),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(
                    "This is a RenderRepaintBoundary test",
                    style: Theme.of(context)
                        .textTheme
                        .headline6
                        .copyWith(color: Colors.blue),
                  ),
                  ClipRRect(
                    borderRadius: BorderRadius.circular(25),
                    child: Container(
                      color: Colors.grey[100],
                      child: FlutterLogo(
                        size: 300,
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class OverRepaintBoundary extends StatefulWidget {
  final Widget child;

  const OverRepaintBoundary({Key key, this.child}) : super(key: key);

  @override
  OverRepaintBoundaryState createState() => OverRepaintBoundaryState();
}

class OverRepaintBoundaryState extends State<OverRepaintBoundary> {
  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}

flutter doctor -v
[✓] Flutter (Channel stable, 1.22.6, on macOS 11.1 20C69 darwin-x64, locale en-GB)
    • Flutter version 1.22.6 at /Users/tahatesser/Code/flutter_stable
    • Framework revision 9b2d32b605 (12 days ago), 2021-01-22 14:36:39 -0800
    • Engine revision 2f0af37152
    • Dart version 2.10.5

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    • Android SDK at /Volumes/Extreme/SDK
    • Platform android-30, build-tools 30.0.3
    • ANDROID_HOME = /Volumes/Extreme/SDK
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 12.4)
    • Xcode at /Volumes/Extreme/Xcode.app/Contents/Developer
    • Xcode 12.4, Build version 12D4e
    • CocoaPods version 1.10.1

[!] Android Studio (version 4.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)

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

[!] Connected device
    ! No devices available

! Doctor found issues in 2 categories.
[✓] Flutter (Channel master, 1.26.0-18.0.pre.156, on macOS 11.1 20C69 darwin-x64, locale en-GB)
    • Flutter version 1.26.0-18.0.pre.156 at /Users/tahatesser/Code/flutter_master
    • Framework revision 45508985b1 (8 hours ago), 2021-02-02 22:46:04 -0500
    • Engine revision 2c144c3eeb
    • Dart version 2.12.0 (build 2.12.0-282.0.dev)

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    • Android SDK at /Volumes/Extreme/SDK
    • Platform android-30, build-tools 30.0.3
    • ANDROID_HOME = /Volumes/Extreme/SDK
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Volumes/Extreme/Xcode.app/Contents/Developer
    • Xcode 12.4, Build version 12D4e
    • CocoaPods version 1.10.1

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

[✓] Android Studio (version 4.1)
    • 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 1.8.0_242-release-1644-b3-6915495)

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

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-x64     • macOS 11.1 20C69 darwin-x64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 88.0.4324.96

• No issues found!

Can you please provide more details and a minimal complete reproducible code sample? Thank you

TahaTesser avatar Feb 03 '21 15:02 TahaTesser

@TahaTesser Thank you for your attention to this issue

code sample
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'package:yeelight_iot_library_log/toast_util.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: QrCodeWidget(),
      ),
    );
  }
}

class QrCodeWidget extends StatefulWidget {
  QrCodeWidget({Key key}) : super(key: key);

  @override
  _QrCodeWidgetState createState() => _QrCodeWidgetState();
}

class _QrCodeWidgetState extends State<QrCodeWidget> {
  final ScrollController controller =
      ScrollController(initialScrollOffset: -1, keepScrollOffset: true);
  ui.Image image;
  GlobalKey repaintWidgetKey = GlobalKey(); // 绘图key值
  String _barCodeString = "123456";

  _saveImage() async {
    ByteData sourceByteData = await _capturePngToByteData();
    final result = await ImageGallerySaver.saveImage(
        sourceByteData.buffer.asUint8List(),
        quality: 60,
        name: "hello");
    if (result["isSuccess"]) {
      ToastUtil.showToast(msg: "success");
    } else {
      ToastUtil.showToast(msg: "fail");
    }
  }

  Future<ByteData> _capturePngToByteData() async {
    try {
      RenderRepaintBoundary boundary =
          repaintWidgetKey.currentContext.findRenderObject();
      double dpr = ui.window.devicePixelRatio;
      ui.Image image = await boundary.toImage(pixelRatio: dpr);
      ByteData _byteData =
          await image.toByteData(format: ui.ImageByteFormat.png);
      return _byteData;
    } catch (e) {
      print(e);
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: Stack(
        children: <Widget>[
          Container(
            child: CustomScrollView(
              slivers: <Widget>[
                SliverToBoxAdapter(
                  child: Container(
                    child: GestureDetector(
                      child: Container(
                        width: 110,
                        alignment: Alignment.center,
                        margin: EdgeInsets.only(
                            top: 20),
                        height: 35,
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.all(Radius.circular(
                                19)),
                            color: Colors.transparent,
                            border:
                                Border.all(color: Colors.white, width: 0.5)),
                        child: Text(
                          "save",
                          style: TextStyle(color: Colors.white, fontSize: 14),
                        ),
                      ),
                      onTap: () {
                        _saveImage();
                      },
                    ),
                  ),
                ),
              ],
              controller: controller,
            ),
          ),
          _renderQrCaptureView(),
        ],
      ),
    );
  }

  _renderQrCaptureView() {
    double topImageWidth = 75.0;
    double qrCodeImageWitdh = 135;
    return Positioned(
      top: MediaQuery.of(context).size.height,
      child: RepaintBoundary(
        key: repaintWidgetKey,
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: 667,
          decoration: BoxDecoration(
            color: Colors.black,
            image: DecorationImage(
                image: AssetImage("res/images/img_share_image_bg.png"),
                fit: BoxFit.fill),
          ),
          child: Stack(
            alignment: Alignment.topCenter,
            children: [
              Positioned(
                top: 164,
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(10),
                  child: Container(
                    color: Colors.white,
                    width: 335,
                    height: 365,
                    child: Column(
                      children: [
                        Expanded(
                            flex: 135,
                            child: Container(
                              constraints: BoxConstraints.expand(),
                              color: Colors.grey,
                              child: Column(
                                children: [
                                  Container(
                                      margin: EdgeInsets.only(
                                          top:
                                              50),
                                      child: Text(
                                        "Name",
                                        style: TextStyle(color: Colors.black,fontWeight: FontWeight.w400,),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                  Container(
                                      margin: EdgeInsets.only(
                                          top: 20, left: 5, right: 5),
                                      child: Text(
                                        "desc",
                                        style: TextStyle(color: Colors.black,fontWeight: FontWeight.w400,fontSize: 20),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                ],
                              ),
                            )),
                        Expanded(
                            flex: 231,
                            child: Container(
                              color: Colors.white,
                              child: Column(
                                children: [
                                  Container(
                                    margin: EdgeInsets.only(
                                        top: 18),
                                    child: QrImage(
                                      data: _barCodeString,
                                      version: QrVersions.auto,
                                      padding: EdgeInsets.all(5),
                                      size: qrCodeImageWitdh,
                                      backgroundColor: Colors.white,
                                      errorCorrectionLevel:
                                          QrErrorCorrectLevel.H,
                                      embeddedImage: AssetImage(
                                          'res/images/icon_default_portrait.png'),
                                      embeddedImageStyle: QrEmbeddedImageStyle(
                                        size: Size(qrCodeImageWitdh / 5.0,
                                            qrCodeImageWitdh / 5.0),
                                      ),
                                    ),
                                  ),
                                  Container(
                                    margin: EdgeInsets.only(
                                        top: 15),
                                    child: Text(
                                      "time",
                                        style: TextStyle(color: Colors.black,fontWeight: FontWeight.w400,fontSize: 14),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                  Container(
                                    margin: EdgeInsets.only(top: 5),
                                    child: Text(
                                      "text",
                                    style: TextStyle(color: Colors.black,fontWeight: FontWeight.w400,fontSize: 13),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                ],
                              ),
                            )),
                      ],
                    ),
                  ),
                ),
              ),
              Positioned(
                top: 127,
                child: Container(
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(
                        Radius.circular((topImageWidth + 4) / 2.0)),
                    border: Border.all(color: Colors.white, width: 2),
                  ),
                  child: Container(
                    height: topImageWidth,
                    width: topImageWidth,
                    child: CircleAvatar(
                        radius: topImageWidth / 2.0,
                        child: Image.asset(
                          "res/images/icon_default_portrait.png",
                        )),
                  ),
                ),
              ),
              Positioned(
                bottom: 31,
                child: Image.asset(
                  "res/images/icon_default_portrait.png",
                  height: 21,
                  fit: BoxFit.contain,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

BaroneX avatar Feb 04 '21 02:02 BaroneX

Hi @BaroneX

code sample
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:qr_flutter/qr_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: QrCodeWidget(),
      ),
    );
  }
}

class QrCodeWidget extends StatefulWidget {
  QrCodeWidget({Key key}) : super(key: key);

  @override
  _QrCodeWidgetState createState() => _QrCodeWidgetState();
}

class _QrCodeWidgetState extends State<QrCodeWidget> {
  final ScrollController controller =
      ScrollController(initialScrollOffset: -1, keepScrollOffset: true);
  ui.Image image;
  GlobalKey repaintWidgetKey = GlobalKey(); // 绘图key值
  String _barCodeString = "123456";

  _saveImage() async {
    ByteData sourceByteData = await _capturePngToByteData();
    final result = await ImageGallerySaver.saveImage(
        sourceByteData.buffer.asUint8List(),
        quality: 60,
        name: "hello");
    if (result["isSuccess"]) {
      print("success");
    } else {
      print("fail");
    }
  }

  Future<ByteData> _capturePngToByteData() async {
    try {
      RenderRepaintBoundary boundary =
          repaintWidgetKey.currentContext.findRenderObject();
      double dpr = ui.window.devicePixelRatio;
      ui.Image image = await boundary.toImage(pixelRatio: dpr);
      ByteData _byteData =
          await image.toByteData(format: ui.ImageByteFormat.png);
      return _byteData;
    } catch (e) {
      print(e);
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: Stack(
        children: <Widget>[
          Container(
            child: CustomScrollView(
              slivers: <Widget>[
                SliverToBoxAdapter(
                  child: Container(
                    child: GestureDetector(
                      child: Container(
                        width: 110,
                        alignment: Alignment.center,
                        margin: EdgeInsets.only(top: 20),
                        height: 35,
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.all(Radius.circular(19)),
                            color: Colors.transparent,
                            border:
                                Border.all(color: Colors.white, width: 0.5)),
                        child: Text(
                          "save",
                          style: TextStyle(color: Colors.white, fontSize: 14),
                        ),
                      ),
                      onTap: () {
                        _saveImage();
                      },
                    ),
                  ),
                ),
              ],
              controller: controller,
            ),
          ),
          _renderQrCaptureView(),
        ],
      ),
    );
  }

  _renderQrCaptureView() {
    double topImageWidth = 75.0;
    double qrCodeImageWitdh = 135;
    return Positioned(
      top: MediaQuery.of(context).size.height,
      child: RepaintBoundary(
        key: repaintWidgetKey,
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: 667,
          decoration: BoxDecoration(
            color: Colors.black,
            image: DecorationImage(
                image: AssetImage("res/images/img_share_image_bg.png"),
                fit: BoxFit.fill),
          ),
          child: Stack(
            alignment: Alignment.topCenter,
            children: [
              Positioned(
                top: 164,
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(10),
                  child: Container(
                    color: Colors.white,
                    width: 335,
                    height: 365,
                    child: Column(
                      children: [
                        Expanded(
                            flex: 135,
                            child: Container(
                              constraints: BoxConstraints.expand(),
                              color: Colors.grey,
                              child: Column(
                                children: [
                                  Container(
                                      margin: EdgeInsets.only(top: 50),
                                      child: Text(
                                        "Name",
                                        style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                        ),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                  Container(
                                      margin: EdgeInsets.only(
                                          top: 20, left: 5, right: 5),
                                      child: Text(
                                        "desc",
                                        style: TextStyle(
                                            color: Colors.black,
                                            fontWeight: FontWeight.w400,
                                            fontSize: 20),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                ],
                              ),
                            )),
                        Expanded(
                            flex: 231,
                            child: Container(
                              color: Colors.white,
                              child: Column(
                                children: [
                                  Container(
                                    margin: EdgeInsets.only(top: 18),
                                    child: QrImage(
                                      data: _barCodeString,
                                      version: QrVersions.auto,
                                      padding: EdgeInsets.all(5),
                                      size: qrCodeImageWitdh,
                                      backgroundColor: Colors.white,
                                      errorCorrectionLevel:
                                          QrErrorCorrectLevel.H,
                                      embeddedImage: AssetImage(
                                          'res/images/icon_default_portrait.png'),
                                      embeddedImageStyle: QrEmbeddedImageStyle(
                                        size: Size(qrCodeImageWitdh / 5.0,
                                            qrCodeImageWitdh / 5.0),
                                      ),
                                    ),
                                  ),
                                  Container(
                                    margin: EdgeInsets.only(top: 15),
                                    child: Text(
                                      "time",
                                      style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                          fontSize: 14),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                  Container(
                                    margin: EdgeInsets.only(top: 5),
                                    child: Text(
                                      "text",
                                      style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                          fontSize: 13),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                ],
                              ),
                            )),
                      ],
                    ),
                  ),
                ),
              ),
              Positioned(
                top: 127,
                child: Container(
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(
                        Radius.circular((topImageWidth + 4) / 2.0)),
                    border: Border.all(color: Colors.white, width: 2),
                  ),
                  child: Container(
                    height: topImageWidth,
                    width: topImageWidth,
                    child: CircleAvatar(
                        radius: topImageWidth / 2.0,
                        child: Image.asset(
                          "res/images/icon_default_portrait.png",
                        )),
                  ),
                ),
              ),
              Positioned(
                bottom: 31,
                child: Image.asset(
                  "res/images/icon_default_portrait.png",
                  height: 21,
                  fit: BoxFit.contain,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

flutter doctor -v
[✓] Flutter (Channel stable, 1.22.6, on macOS 11.1 20C69 darwin-x64, locale en-GB)
    • Flutter version 1.22.6 at /Users/tahatesser/Code/flutter_stable
    • Framework revision 9b2d32b605 (12 days ago), 2021-01-22 14:36:39 -0800
    • Engine revision 2f0af37152
    • Dart version 2.10.5

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    • Android SDK at /Volumes/Extreme/SDK
    • Platform android-30, build-tools 30.0.3
    • ANDROID_HOME = /Volumes/Extreme/SDK
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 12.4)
    • Xcode at /Volumes/Extreme/Xcode.app/Contents/Developer
    • Xcode 12.4, Build version 12D4e
    • CocoaPods version 1.10.1

[!] Android Studio (version 4.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)

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

[✓] Connected device (1 available)
    • Taha’s iPhone (mobile) • 00008020-001059882212002E • ios • iOS 14.4

! Doctor found issues in 1 category.
[✓] Flutter (Channel master, 1.26.0-18.0.pre.186, on macOS 11.1 20C69 darwin-x64, locale en-GB)
    • Flutter version 1.26.0-18.0.pre.186 at /Users/tahatesser/Code/flutter_master
    • Framework revision 39114251af (2 hours ago), 2021-02-04 01:16:04 -0500
    • Engine revision 1c2c78398c
    • Dart version 2.12.0 (build 2.12.0-284.0.dev)

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    • Android SDK at /Volumes/Extreme/SDK
    • Platform android-30, build-tools 30.0.3
    • ANDROID_HOME = /Volumes/Extreme/SDK
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Volumes/Extreme/Xcode.app/Contents/Developer
    • Xcode 12.4, Build version 12D4e
    • CocoaPods version 1.10.1

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

[✓] Android Studio (version 4.1)
    • 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 1.8.0_242-release-1644-b3-6915495)

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

[✓] Connected device (3 available)
    • Taha’s iPhone (mobile) • 00008020-001059882212002E • ios            • iOS 14.4
    • macOS (desktop)        • macos                     • darwin-x64     • macOS 11.1 20C69 darwin-x64
    • Chrome (web)           • chrome                    • web-javascript • Google Chrome 88.0.4324.96

• No issues found!

Thank you

TahaTesser avatar Feb 04 '21 08:02 TahaTesser

@TahaTesser I found that the possibility of this problem is very high when the authorization pops up for the first time.

normal error
IMG_3027 IMG_3030
code sample
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:qr_flutter/qr_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: QrCodeWidget(),
      ),
    );
  }
}

class QrCodeWidget extends StatefulWidget {
  QrCodeWidget({Key key}) : super(key: key);

  @override
  _QrCodeWidgetState createState() => _QrCodeWidgetState();
}

class _QrCodeWidgetState extends State<QrCodeWidget> {
  final ScrollController controller =
      ScrollController(initialScrollOffset: -1, keepScrollOffset: true);
  ui.Image image;
  GlobalKey repaintWidgetKey = GlobalKey(); 
  String _barCodeString = "123456";


  _saveImage() async {
    PermissionStatus permission = await Permission.photos.request();
    bool isPhotoGranted = (permission.isUndetermined ||
          permission.isRestricted ||
          permission.isGranted);
    if (!isPhotoGranted) {
      return;
    }

    ByteData sourceByteData = await _capturePngToByteData();
    final result = await ImageGallerySaver.saveImage(
        sourceByteData.buffer.asUint8List(),
        quality: 60,
        name: "hello");
    if (result["isSuccess"]) {
      print("success");
    } else {
      print("fail");
    }
  }

  Future<ByteData> _capturePngToByteData() async {
    try {
      RenderRepaintBoundary boundary =
          repaintWidgetKey.currentContext.findRenderObject();
      double dpr = ui.window.devicePixelRatio;
      ui.Image image = await boundary.toImage(pixelRatio: dpr);
      ByteData _byteData =
          await image.toByteData(format: ui.ImageByteFormat.png);
      return _byteData;
    } catch (e) {
      print(e);
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.green,
      body: Stack(
        children: <Widget>[
          Container(
            child: CustomScrollView(
              slivers: <Widget>[
                SliverToBoxAdapter(
                  child: Container(
                    child: GestureDetector(
                      child: Container(
                        width: 110,
                        alignment: Alignment.center,
                        margin: EdgeInsets.only(top: 20),
                        height: 35,
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.all(Radius.circular(19)),
                            color: Colors.transparent,
                            border:
                                Border.all(color: Colors.white, width: 0.5)),
                        child: Text(
                          "save",
                          style: TextStyle(color: Colors.white, fontSize: 14),
                        ),
                      ),
                      onTap: () {
                        _saveImage();
                      },
                    ),
                  ),
                ),
              ],
              controller: controller,
            ),
          ),
          _renderQrCaptureView(),
        ],
      ),
    );
  }

  _renderQrCaptureView() {
    double topImageWidth = 75.0;
    double qrCodeImageWitdh = 135;
    return Positioned(
      top: MediaQuery.of(context).size.height,
      child: RepaintBoundary(
        key: repaintWidgetKey,
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: 667,
          decoration: BoxDecoration(
            color: Colors.black,
            image: DecorationImage(
                image: AssetImage("res/images/img_share_image_bg.png"),
                fit: BoxFit.fill),
          ),
          child: Stack(
            alignment: Alignment.topCenter,
            children: [
              Positioned(
                top: 164,
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(10),
                  child: Container(
                    color: Colors.white,
                    width: 335,
                    height: 365,
                    child: Column(
                      children: [
                        Expanded(
                            flex: 135,
                            child: Container(
                              constraints: BoxConstraints.expand(),
                              color: Colors.grey,
                              child: Column(
                                children: [
                                  Container(
                                      margin: EdgeInsets.only(top: 50),
                                      child: Text(
                                        "Name",
                                        style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                        ),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                  Container(
                                      margin: EdgeInsets.only(
                                          top: 20, left: 5, right: 5),
                                      child: Text(
                                        "desc",
                                        style: TextStyle(
                                            color: Colors.black,
                                            fontWeight: FontWeight.w400,
                                            fontSize: 20),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                ],
                              ),
                            )),
                        Expanded(
                            flex: 231,
                            child: Container(
                              color: Colors.white,
                              child: Column(
                                children: [
                                  Container(
                                    margin: EdgeInsets.only(top: 18),
                                    child: QrImage(
                                      data: _barCodeString,
                                      version: QrVersions.auto,
                                      padding: EdgeInsets.all(5),
                                      size: qrCodeImageWitdh,
                                      backgroundColor: Colors.white,
                                      errorCorrectionLevel:
                                          QrErrorCorrectLevel.H,
                                      embeddedImage: AssetImage(
                                          'res/images/icon_default_portrait.png'),
                                      embeddedImageStyle: QrEmbeddedImageStyle(
                                        size: Size(qrCodeImageWitdh / 5.0,
                                            qrCodeImageWitdh / 5.0),
                                      ),
                                    ),
                                  ),
                                  Container(
                                    margin: EdgeInsets.only(top: 15),
                                    child: Text(
                                      "time",
                                      style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                          fontSize: 14),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                  Container(
                                    margin: EdgeInsets.only(top: 5),
                                    child: Text(
                                      "text",
                                      style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                          fontSize: 13),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                ],
                              ),
                            )),
                      ],
                    ),
                  ),
                ),
              ),
              Positioned(
                top: 127,
                child: Container(
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(
                        Radius.circular((topImageWidth + 4) / 2.0)),
                    border: Border.all(color: Colors.white, width: 2),
                  ),
                  child: Container(
                    height: topImageWidth,
                    width: topImageWidth,
                    child: CircleAvatar(
                        radius: topImageWidth / 2.0,
                        child: Image.asset(
                          "res/images/icon_default_portrait.png",
                        )),
                  ),
                ),
              ),
              Positioned(
                bottom: 31,
                child: Image.asset(
                  "res/images/icon_default_portrait.png",
                  height: 21,
                  fit: BoxFit.contain,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

BaroneX avatar Feb 05 '21 05:02 BaroneX

Hi @BaroneX Thanks for the details, I attempted to reproduce using the new code sample with authorization pop up multiple, still no issue.

Preview

code sample
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:qr_flutter/qr_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: QrCodeWidget(),
      ),
    );
  }
}

class QrCodeWidget extends StatefulWidget {
  QrCodeWidget({Key key}) : super(key: key);

  @override
  _QrCodeWidgetState createState() => _QrCodeWidgetState();
}

class _QrCodeWidgetState extends State<QrCodeWidget> {
  final ScrollController controller =
      ScrollController(initialScrollOffset: -1, keepScrollOffset: true);
  ui.Image image;
  GlobalKey repaintWidgetKey = GlobalKey();
  String _barCodeString = "123456";

  _saveImage() async {
    PermissionStatus permission = await Permission.photos.request();
    bool isPhotoGranted = (permission.isUndetermined ||
        permission.isRestricted ||
        permission.isGranted);
    if (!isPhotoGranted) {
      return;
    }

    ByteData sourceByteData = await _capturePngToByteData();
    final result = await ImageGallerySaver.saveImage(
        sourceByteData.buffer.asUint8List(),
        quality: 60,
        name: "hello");
    if (result["isSuccess"]) {
      print("success");
    } else {
      print("fail");
    }
  }

  Future<ByteData> _capturePngToByteData() async {
    try {
      RenderRepaintBoundary boundary =
          repaintWidgetKey.currentContext.findRenderObject();
      double dpr = ui.window.devicePixelRatio;
      ui.Image image = await boundary.toImage(pixelRatio: dpr);
      ByteData _byteData =
          await image.toByteData(format: ui.ImageByteFormat.png);
      return _byteData;
    } catch (e) {
      print(e);
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.green,
      body: Stack(
        children: <Widget>[
          Container(
            child: CustomScrollView(
              slivers: <Widget>[
                SliverToBoxAdapter(
                  child: Container(
                    child: GestureDetector(
                      child: Container(
                        width: 110,
                        alignment: Alignment.center,
                        margin: EdgeInsets.only(top: 20),
                        height: 35,
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.all(Radius.circular(19)),
                            color: Colors.transparent,
                            border:
                                Border.all(color: Colors.white, width: 0.5)),
                        child: Text(
                          "save",
                          style: TextStyle(color: Colors.white, fontSize: 14),
                        ),
                      ),
                      onTap: () {
                        _saveImage();
                      },
                    ),
                  ),
                ),
              ],
              controller: controller,
            ),
          ),
          _renderQrCaptureView(),
        ],
      ),
    );
  }

  _renderQrCaptureView() {
    double topImageWidth = 75.0;
    double qrCodeImageWitdh = 135;
    return Positioned(
      top: MediaQuery.of(context).size.height,
      child: RepaintBoundary(
        key: repaintWidgetKey,
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: 667,
          decoration: BoxDecoration(
            color: Colors.black,
            image: DecorationImage(
                image: AssetImage("assets/dash.png"), fit: BoxFit.fill),
          ),
          child: Stack(
            alignment: Alignment.topCenter,
            children: [
              Positioned(
                top: 164,
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(10),
                  child: Container(
                    color: Colors.white,
                    width: 335,
                    height: 365,
                    child: Column(
                      children: [
                        Expanded(
                            flex: 135,
                            child: Container(
                              constraints: BoxConstraints.expand(),
                              color: Colors.grey,
                              child: Column(
                                children: [
                                  Container(
                                      margin: EdgeInsets.only(top: 50),
                                      child: Text(
                                        "Name",
                                        style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                        ),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                  Container(
                                      margin: EdgeInsets.only(
                                          top: 20, left: 5, right: 5),
                                      child: Text(
                                        "desc",
                                        style: TextStyle(
                                            color: Colors.black,
                                            fontWeight: FontWeight.w400,
                                            fontSize: 20),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                ],
                              ),
                            )),
                        Expanded(
                            flex: 231,
                            child: Container(
                              color: Colors.white,
                              child: Column(
                                children: [
                                  Container(
                                    margin: EdgeInsets.only(top: 18),
                                    child: QrImage(
                                      data: _barCodeString,
                                      version: QrVersions.auto,
                                      padding: EdgeInsets.all(5),
                                      size: qrCodeImageWitdh,
                                      backgroundColor: Colors.white,
                                      errorCorrectionLevel:
                                          QrErrorCorrectLevel.H,
                                      embeddedImage:
                                          AssetImage('assets/dash.png'),
                                      embeddedImageStyle: QrEmbeddedImageStyle(
                                        size: Size(qrCodeImageWitdh / 5.0,
                                            qrCodeImageWitdh / 5.0),
                                      ),
                                    ),
                                  ),
                                  Container(
                                    margin: EdgeInsets.only(top: 15),
                                    child: Text(
                                      "time",
                                      style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                          fontSize: 14),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                  Container(
                                    margin: EdgeInsets.only(top: 5),
                                    child: Text(
                                      "text",
                                      style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                          fontSize: 13),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                ],
                              ),
                            )),
                      ],
                    ),
                  ),
                ),
              ),
              Positioned(
                top: 127,
                child: Container(
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(
                        Radius.circular((topImageWidth + 4) / 2.0)),
                    border: Border.all(color: Colors.white, width: 2),
                  ),
                  child: Container(
                    height: topImageWidth,
                    width: topImageWidth,
                    child: CircleAvatar(
                        radius: topImageWidth / 2.0,
                        child: Image.asset(
                          "assets/dash.png",
                        )),
                  ),
                ),
              ),
              Positioned(
                bottom: 31,
                child: Image.asset(
                  "assets/dash.png",
                  height: 21,
                  fit: BoxFit.contain,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Looks like you're on a previous Flutter stable, Can you please upgrade to the latest stable and try again flutter channel stable flutter upgrade --force flutter doctor -v

and please provide this image con_default_portrait.png for testing Thank you

TahaTesser avatar Feb 05 '21 07:02 TahaTesser

@TahaTesser I update flutter to 1.22.6, but still have this problem, I tried many times,uninstall every time, the problem still occurs accidentally

Previously closed issue that seems to be same problem: #17687

I tried many times icon_default_portrait.png
IMG_3063 icon_default_portrait
code sample
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:qr_flutter/qr_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: QrCodeWidget(),
      ),
    );
  }
}

class QrCodeWidget extends StatefulWidget {
  QrCodeWidget({Key key}) : super(key: key);

  @override
  _QrCodeWidgetState createState() => _QrCodeWidgetState();
}

class _QrCodeWidgetState extends State<QrCodeWidget> {
  final ScrollController controller =
      ScrollController(initialScrollOffset: -1, keepScrollOffset: true);
  ui.Image image;
  GlobalKey repaintWidgetKey = GlobalKey(); 
  String _barCodeString = "123456";


  _saveImage() async {
    PermissionStatus permission = await Permission.photos.request();
    bool isPhotoGranted = (permission.isUndetermined ||
          permission.isRestricted ||
          permission.isGranted);
    if (!isPhotoGranted) {
      return;
    }

    ByteData sourceByteData = await _capturePngToByteData();
    final result = await ImageGallerySaver.saveImage(
        sourceByteData.buffer.asUint8List(),
        quality: 60,
        name: "hello");
    if (result["isSuccess"]) {
      print("success");
    } else {
      print("fail");
    }
  }

  Future<ByteData> _capturePngToByteData() async {
    try {
      RenderRepaintBoundary boundary =
          repaintWidgetKey.currentContext.findRenderObject();
      double dpr = ui.window.devicePixelRatio;
      ui.Image image = await boundary.toImage(pixelRatio: dpr);
      ByteData _byteData =
          await image.toByteData(format: ui.ImageByteFormat.png);
      return _byteData;
    } catch (e) {
      print(e);
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.green,
      body: Stack(
        children: <Widget>[
          Container(
            child: CustomScrollView(
              slivers: <Widget>[
                SliverToBoxAdapter(
                  child: Container(
                    child: GestureDetector(
                      child: Container(
                        width: 110,
                        alignment: Alignment.center,
                        margin: EdgeInsets.only(top: 20),
                        height: 35,
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.all(Radius.circular(19)),
                            color: Colors.transparent,
                            border:
                                Border.all(color: Colors.white, width: 0.5)),
                        child: Text(
                          "save",
                          style: TextStyle(color: Colors.white, fontSize: 14),
                        ),
                      ),
                      onTap: () {
                        _saveImage();
                      },
                    ),
                  ),
                ),
              ],
              controller: controller,
            ),
          ),
          _renderQrCaptureView(),
        ],
      ),
    );
  }

  _renderQrCaptureView() {
    double topImageWidth = 75.0;
    double qrCodeImageWitdh = 135;
    return Positioned(
      top: MediaQuery.of(context).size.height,
      child: RepaintBoundary(
        key: repaintWidgetKey,
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: 667,
          decoration: BoxDecoration(
            color: Colors.black,
            image: DecorationImage(
                image: AssetImage("res/images/img_share_image_bg.png"),
                fit: BoxFit.fill),
          ),
          child: Stack(
            alignment: Alignment.topCenter,
            children: [
              Positioned(
                top: 164,
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(10),
                  child: Container(
                    color: Colors.white,
                    width: 335,
                    height: 365,
                    child: Column(
                      children: [
                        Expanded(
                            flex: 135,
                            child: Container(
                              constraints: BoxConstraints.expand(),
                              color: Colors.grey,
                              child: Column(
                                children: [
                                  Container(
                                      margin: EdgeInsets.only(top: 50),
                                      child: Text(
                                        "Name",
                                        style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                        ),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                  Container(
                                      margin: EdgeInsets.only(
                                          top: 20, left: 5, right: 5),
                                      child: Text(
                                        "desc",
                                        style: TextStyle(
                                            color: Colors.black,
                                            fontWeight: FontWeight.w400,
                                            fontSize: 20),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                ],
                              ),
                            )),
                        Expanded(
                            flex: 231,
                            child: Container(
                              color: Colors.white,
                              child: Column(
                                children: [
                                  Container(
                                    margin: EdgeInsets.only(top: 18),
                                    child: QrImage(
                                      data: _barCodeString,
                                      version: QrVersions.auto,
                                      padding: EdgeInsets.all(5),
                                      size: qrCodeImageWitdh,
                                      backgroundColor: Colors.white,
                                      errorCorrectionLevel:
                                          QrErrorCorrectLevel.H,
                                      embeddedImage: AssetImage(
                                          'res/images/icon_default_portrait.png'),
                                      embeddedImageStyle: QrEmbeddedImageStyle(
                                        size: Size(qrCodeImageWitdh / 5.0,
                                            qrCodeImageWitdh / 5.0),
                                      ),
                                    ),
                                  ),
                                  Container(
                                    margin: EdgeInsets.only(top: 15),
                                    child: Text(
                                      "time",
                                      style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                          fontSize: 14),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                  Container(
                                    margin: EdgeInsets.only(top: 5),
                                    child: Text(
                                      "text",
                                      style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                          fontSize: 13),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                ],
                              ),
                            )),
                      ],
                    ),
                  ),
                ),
              ),
              Positioned(
                top: 127,
                child: Container(
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(
                        Radius.circular((topImageWidth + 4) / 2.0)),
                    border: Border.all(color: Colors.white, width: 2),
                  ),
                  child: Container(
                    height: topImageWidth,
                    width: topImageWidth,
                    child: CircleAvatar(
                        radius: topImageWidth / 2.0,
                        child: Image.asset(
                          "res/images/icon_default_portrait.png",
                        )),
                  ),
                ),
              ),
              Positioned(
                bottom: 31,
                child: Image.asset(
                  "res/images/icon_default_portrait.png",
                  height: 21,
                  fit: BoxFit.contain,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
flutter doctor -v
⚡ flutter doctor -v

[✓] Flutter (Channel stable, 1.22.6, on Mac OS X 10.15.5 19F101 darwin-x64, locale zh-Hans-CN)
    • Flutter version 1.22.6 at /Users/blake/flutter/flutter
    • Framework revision 9b2d32b605 (2 周前), 2021-01-22 14:36:39 -0800
    • Engine revision 2f0af37152
    • Dart version 2.10.5
    • Pub download mirror https://pub.flutter-io.cn
    • Flutter download mirror https://storage.flutter-io.cn

 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at /Users/blake/Library/Android/sdk
    • Platform android-29, build-tools 29.0.2
    • ANDROID_HOME = /Users/blake/Library/Android/sdk
    • 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-1343-b01)
    • All Android licenses accepted.

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

[✓] Android Studio (version 3.4)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 39.0.1
    • Dart plugin version 183.6270
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)

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

[✓] Connected device (1 available)
    • i (mobile) • 00008101-000D39681A22001E • ios • iOS 14.3

• No issues found!

BaroneX avatar Feb 06 '21 03:02 BaroneX

Hi @BaroneX I was able to finally reproduce the issue using your icon_default_portrait asset with the code sample on XR running iOS 14.4 on the stable However I tried to reproduce it on beta and master channels, wasn't able to reproduce

Preview

Screenshot 2021-02-08 at 1 21 48 PM
code sample
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:qr_flutter/qr_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: QrCodeWidget(),
      ),
    );
  }
}

class QrCodeWidget extends StatefulWidget {
  QrCodeWidget({Key key}) : super(key: key);

  @override
  _QrCodeWidgetState createState() => _QrCodeWidgetState();
}

class _QrCodeWidgetState extends State<QrCodeWidget> {
  final ScrollController controller =
      ScrollController(initialScrollOffset: -1, keepScrollOffset: true);
  ui.Image image;
  GlobalKey repaintWidgetKey = GlobalKey();
  String _barCodeString = "123456";

  _saveImage() async {
    PermissionStatus permission = await Permission.photos.request();
    bool isPhotoGranted = (permission.isUndetermined ||
        permission.isRestricted ||
        permission.isGranted);
    if (!isPhotoGranted) {
      return;
    }

    ByteData sourceByteData = await _capturePngToByteData();
    final result = await ImageGallerySaver.saveImage(
        sourceByteData.buffer.asUint8List(),
        quality: 60,
        name: "hello");
    if (result["isSuccess"]) {
      print("success");
    } else {
      print("fail");
    }
  }

  Future<ByteData> _capturePngToByteData() async {
    try {
      RenderRepaintBoundary boundary =
          repaintWidgetKey.currentContext.findRenderObject();
      double dpr = ui.window.devicePixelRatio;
      ui.Image image = await boundary.toImage(pixelRatio: dpr);
      ByteData _byteData =
          await image.toByteData(format: ui.ImageByteFormat.png);
      return _byteData;
    } catch (e) {
      print(e);
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.green,
      body: Stack(
        children: <Widget>[
          Container(
            child: CustomScrollView(
              slivers: <Widget>[
                SliverToBoxAdapter(
                  child: Container(
                    child: GestureDetector(
                      child: Container(
                        width: 110,
                        alignment: Alignment.center,
                        margin: EdgeInsets.only(top: 20),
                        height: 35,
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.all(Radius.circular(19)),
                            color: Colors.transparent,
                            border:
                                Border.all(color: Colors.white, width: 0.5)),
                        child: Text(
                          "save",
                          style: TextStyle(color: Colors.white, fontSize: 14),
                        ),
                      ),
                      onTap: () {
                        _saveImage();
                      },
                    ),
                  ),
                ),
              ],
              controller: controller,
            ),
          ),
          _renderQrCaptureView(),
        ],
      ),
    );
  }

  _renderQrCaptureView() {
    double topImageWidth = 75.0;
    double qrCodeImageWitdh = 135;
    return Positioned(
      top: MediaQuery.of(context).size.height,
      child: RepaintBoundary(
        key: repaintWidgetKey,
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: 667,
          decoration: BoxDecoration(
            color: Colors.black,
            image: DecorationImage(
                image: AssetImage("res/images/dash.png"), fit: BoxFit.fill),
          ),
          child: Stack(
            alignment: Alignment.topCenter,
            children: [
              Positioned(
                top: 164,
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(10),
                  child: Container(
                    color: Colors.white,
                    width: 335,
                    height: 365,
                    child: Column(
                      children: [
                        Expanded(
                            flex: 135,
                            child: Container(
                              constraints: BoxConstraints.expand(),
                              color: Colors.grey,
                              child: Column(
                                children: [
                                  Container(
                                      margin: EdgeInsets.only(top: 50),
                                      child: Text(
                                        "Name",
                                        style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                        ),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                  Container(
                                      margin: EdgeInsets.only(
                                          top: 20, left: 5, right: 5),
                                      child: Text(
                                        "desc",
                                        style: TextStyle(
                                            color: Colors.black,
                                            fontWeight: FontWeight.w400,
                                            fontSize: 20),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                ],
                              ),
                            )),
                        Expanded(
                            flex: 231,
                            child: Container(
                              color: Colors.white,
                              child: Column(
                                children: [
                                  Container(
                                    margin: EdgeInsets.only(top: 18),
                                    child: QrImage(
                                      data: _barCodeString,
                                      version: QrVersions.auto,
                                      padding: EdgeInsets.all(5),
                                      size: qrCodeImageWitdh,
                                      backgroundColor: Colors.white,
                                      errorCorrectionLevel:
                                          QrErrorCorrectLevel.H,
                                      embeddedImage: AssetImage(
                                          'res/images/icon_default_portrait.png'),
                                      embeddedImageStyle: QrEmbeddedImageStyle(
                                        size: Size(qrCodeImageWitdh / 5.0,
                                            qrCodeImageWitdh / 5.0),
                                      ),
                                    ),
                                  ),
                                  Container(
                                    margin: EdgeInsets.only(top: 15),
                                    child: Text(
                                      "time",
                                      style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                          fontSize: 14),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                  Container(
                                    margin: EdgeInsets.only(top: 5),
                                    child: Text(
                                      "text",
                                      style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                          fontSize: 13),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                ],
                              ),
                            )),
                      ],
                    ),
                  ),
                ),
              ),
              Positioned(
                top: 127,
                child: Container(
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(
                        Radius.circular((topImageWidth + 4) / 2.0)),
                    border: Border.all(color: Colors.white, width: 2),
                  ),
                  child: Container(
                    height: topImageWidth,
                    width: topImageWidth,
                    child: CircleAvatar(
                        radius: topImageWidth / 2.0,
                        child: Image.asset(
                          "res/images/icon_default_portrait.png",
                        )),
                  ),
                ),
              ),
              Positioned(
                bottom: 31,
                child: Image.asset(
                  "res/images/icon_default_portrait.png",
                  height: 21,
                  fit: BoxFit.contain,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

flutter doctor -v
[✓] Flutter (Channel stable, 1.22.6, on macOS 11.2 20D64 darwin-x64, locale en-GB)
    • Flutter version 1.22.6 at /Users/tahatesser/Code/flutter_stable
    • Framework revision 9b2d32b605 (2 weeks ago), 2021-01-22 14:36:39 -0800
    • Engine revision 2f0af37152
    • Dart version 2.10.5
[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, set ANDROID_SDK_ROOT to that location.
      You may also want to add it to your PATH environment variable.
[!] Xcode - develop for iOS and macOS (Xcode 12.4)
    • Xcode at /Volumes/Extreme/Xcode.app/Contents/Developer
    • Xcode 12.4, Build version 12D4e
    ✗ CocoaPods not installed.
        CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/platform-plugins
      To install:
        sudo gem install cocoapods
[!] Android Studio (version 4.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
[✓] VS Code (version 1.53.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.19.0
[✓] Connected device (1 available)
    • Taha’s iPhone (mobile) • 00008020-001059882212002E • ios • iOS 14.4
! Doctor found issues in 3 categories.
[✓] Flutter (Channel beta, 1.26.0-17.3.pre, on macOS 11.2 20D64 darwin-x64, locale en-GB)
    • Flutter version 1.26.0-17.3.pre at /Users/tahatesser/Code/flutter_beta
    • Framework revision 4b50ca7f7f (3 days ago), 2021-02-04 19:44:27 -0800
    • Engine revision 2c527d6c7e
    • Dart version 2.12.0 (build 2.12.0-259.8.beta)
[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.
[!] Xcode - develop for iOS and macOS
    • Xcode at /Volumes/Extreme/Xcode.app/Contents/Developer
    • Xcode 12.4, Build version 12D4e
    ✗ CocoaPods not installed.
        CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/platform-plugins
      To install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.
[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 4.1)
    • 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 1.8.0_242-release-1644-b3-6915495)
[✓] VS Code (version 1.53.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.19.0
[✓] Connected device (2 available)
    • Taha’s iPhone (mobile) • 00008020-001059882212002E • ios            • iOS 14.4
    • Chrome (web)           • chrome                    • web-javascript • Google Chrome 88.0.4324.146
! Doctor found issues in 2 categories.
[✓] Flutter (Channel master, 1.26.0-18.0.pre.212, on macOS 11.2 20D64 darwin-x64, locale en-GB)
    • Flutter version 1.26.0-18.0.pre.212 at /Users/tahatesser/Code/flutter_master
    • Framework revision 02d441ea55 (2 days ago), 2021-02-05 17:17:12 -0800
    • Engine revision b04955656c
    • Dart version 2.13.0 (build 2.13.0-0.0.dev)
[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.
[!] Xcode - develop for iOS and macOS
    • Xcode at /Volumes/Extreme/Xcode.app/Contents/Developer
    • Xcode 12.4, Build version 12D4e
    ✗ CocoaPods not installed.
        CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/platform-plugins
      To install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.
[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 4.1)
    • 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 1.8.0_242-release-1644-b3-6915495)
[✓] VS Code (version 1.53.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.19.0
[✓] Connected device (3 available)
    • Taha’s iPhone (mobile) • 00008020-001059882212002E • ios            • iOS 14.4
    • macOS (desktop)        • macos                     • darwin-x64     • macOS 11.2 20D64 darwin-x64
    • Chrome (web)           • chrome                    • web-javascript • Google Chrome 88.0.4324.146
! Doctor found issues in 2 categories.

Can you please upgrade to the latest beta and try again flutter channel beta flutter upgrade --force flutter doctor -v

Thank you

TahaTesser avatar Feb 08 '21 07:02 TahaTesser

@TahaTesser Sorry, I did not try the latest beta,My project needs to run on a stable version, I don’t want to introduce other uncertain issues. Now that you have reproduced this problem, can you determine what caused it and how can I avoid it? Thank you

BaroneX avatar Feb 18 '21 12:02 BaroneX

Hi @BaroneX It looks like it is fixed as I wasn't unable to reproduce it for me onbetaor master Can you please reproduce it in. a new project using a minimal code sample from https://github.com/flutter/flutter/issues/75316#issuecomment-774947510 on the latest beta channel Thank you

TahaTesser avatar Feb 18 '21 15:02 TahaTesser

@TahaTesser I tried the latest beta,still have this problem.

image

flutter doctor -v
[✓] Flutter (Channel beta, 1.26.0-17.6.pre, on Mac OS X 10.15.5 19F101 darwin-x64, locale zh-Hans-CN)
    • Flutter version 1.26.0-17.6.pre at /Users/blake/flutter/flutter
    • Framework revision a29104a69b (3 天前), 2021-02-16 09:26:56 -0800
    • Engine revision 21fa8bb99e
    • Dart version 2.12.0 (build 2.12.0-259.12.beta)
    • Pub download mirror https://pub.flutter-io.cn
    • Flutter download mirror https://storage.flutter-io.cn

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at /Users/blake/Library/Android/sdk
    • Platform android-29, build-tools 29.0.2
    • ANDROID_HOME = /Users/blake/Library/Android/sdk
    • 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-1343-b01)
    • All Android licenses accepted.

[!] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.3, Build version 12C33
    ! CocoaPods 1.9.0 out of date (1.10.0 is recommended).
        CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/platform-plugins
      To upgrade see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.

[✓] Android Studio (version 3.4)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 39.0.1
    • Dart plugin version 183.6270
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)

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

[✓] Connected device (1 available)
    • iPhone 11 Pro (mobile) • F48E91AE-1DE2-4F7D-81AD-9D0C08FA8866 • ios • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)

! Doctor found issues in 1 category.
code sample
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:qr_flutter/qr_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: QrCodeWidget(),
      ),
    );
  }
}

class QrCodeWidget extends StatefulWidget {
  QrCodeWidget({Key key}) : super(key: key);

  @override
  _QrCodeWidgetState createState() => _QrCodeWidgetState();
}

class _QrCodeWidgetState extends State<QrCodeWidget> {
  final ScrollController controller =
      ScrollController(initialScrollOffset: -1, keepScrollOffset: true);
  ui.Image image;
  GlobalKey repaintWidgetKey = GlobalKey();
  String _barCodeString = "123456";

  _saveImage() async {
    PermissionStatus permission = await Permission.photos.request();
    bool isPhotoGranted = (permission.isUndetermined ||
        permission.isRestricted ||
        permission.isGranted);
    if (!isPhotoGranted) {
      return;
    }

    ByteData sourceByteData = await _capturePngToByteData();
    final result = await ImageGallerySaver.saveImage(
        sourceByteData.buffer.asUint8List(),
        quality: 60,
        name: "hello");
    if (result["isSuccess"]) {
      print("success");
    } else {
      print("fail");
    }
  }

  Future<ByteData> _capturePngToByteData() async {
    try {
      RenderRepaintBoundary boundary =
          repaintWidgetKey.currentContext.findRenderObject();
      double dpr = ui.window.devicePixelRatio;
      ui.Image image = await boundary.toImage(pixelRatio: dpr);
      ByteData _byteData =
          await image.toByteData(format: ui.ImageByteFormat.png);
      return _byteData;
    } catch (e) {
      print(e);
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.green,
      body: Stack(
        children: <Widget>[
          Container(
            child: CustomScrollView(
              slivers: <Widget>[
                SliverToBoxAdapter(
                  child: Container(
                    child: GestureDetector(
                      child: Container(
                        width: 110,
                        alignment: Alignment.center,
                        margin: EdgeInsets.only(top: 20),
                        height: 35,
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.all(Radius.circular(19)),
                            color: Colors.transparent,
                            border:
                                Border.all(color: Colors.white, width: 0.5)),
                        child: Text(
                          "save",
                          style: TextStyle(color: Colors.white, fontSize: 14),
                        ),
                      ),
                      onTap: () {
                        _saveImage();
                      },
                    ),
                  ),
                ),
              ],
              controller: controller,
            ),
          ),
          _renderQrCaptureView(),
        ],
      ),
    );
  }

  _renderQrCaptureView() {
    double topImageWidth = 75.0;
    double qrCodeImageWitdh = 135;
    return Positioned(
      top: MediaQuery.of(context).size.height,
      child: RepaintBoundary(
        key: repaintWidgetKey,
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: 667,
          decoration: BoxDecoration(
            color: Colors.black,
            image: DecorationImage(
                image: AssetImage("res/images/icon_default_portrait.png"), fit: BoxFit.fill),
          ),
          child: Stack(
            alignment: Alignment.topCenter,
            children: [
              Positioned(
                top: 164,
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(10),
                  child: Container(
                    color: Colors.white,
                    width: 335,
                    height: 365,
                    child: Column(
                      children: [
                        Expanded(
                            flex: 135,
                            child: Container(
                              constraints: BoxConstraints.expand(),
                              color: Colors.grey,
                              child: Column(
                                children: [
                                  Container(
                                      margin: EdgeInsets.only(top: 50),
                                      child: Text(
                                        "Name",
                                        style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                        ),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                  Container(
                                      margin: EdgeInsets.only(
                                          top: 20, left: 5, right: 5),
                                      child: Text(
                                        "desc",
                                        style: TextStyle(
                                            color: Colors.black,
                                            fontWeight: FontWeight.w400,
                                            fontSize: 20),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                ],
                              ),
                            )),
                        Expanded(
                            flex: 231,
                            child: Container(
                              color: Colors.white,
                              child: Column(
                                children: [
                                  Container(
                                    margin: EdgeInsets.only(top: 18),
                                    child: QrImage(
                                      data: _barCodeString,
                                      version: QrVersions.auto,
                                      padding: EdgeInsets.all(5),
                                      size: qrCodeImageWitdh,
                                      backgroundColor: Colors.white,
                                      errorCorrectionLevel:
                                          QrErrorCorrectLevel.H,
                                      embeddedImage: AssetImage(
                                          'res/images/icon_default_portrait.png'),
                                      embeddedImageStyle: QrEmbeddedImageStyle(
                                        size: Size(qrCodeImageWitdh / 5.0,
                                            qrCodeImageWitdh / 5.0),
                                      ),
                                    ),
                                  ),
                                  Container(
                                    margin: EdgeInsets.only(top: 15),
                                    child: Text(
                                      "time",
                                      style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                          fontSize: 14),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                  Container(
                                    margin: EdgeInsets.only(top: 5),
                                    child: Text(
                                      "text",
                                      style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                          fontSize: 13),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                ],
                              ),
                            )),
                      ],
                    ),
                  ),
                ),
              ),
              Positioned(
                top: 127,
                child: Container(
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(
                        Radius.circular((topImageWidth + 4) / 2.0)),
                    border: Border.all(color: Colors.white, width: 2),
                  ),
                  child: Container(
                    height: topImageWidth,
                    width: topImageWidth,
                    child: CircleAvatar(
                        radius: topImageWidth / 2.0,
                        child: Image.asset(
                          "res/images/icon_default_portrait.png",
                        )),
                  ),
                ),
              ),
              Positioned(
                bottom: 31,
                child: Image.asset(
                  "res/images/icon_default_portrait.png",
                  height: 21,
                  fit: BoxFit.contain,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

BaroneX avatar Feb 19 '21 06:02 BaroneX

https://github.com/flutter/flutter/issues/75316#issuecomment-781426848 and https://github.com/flutter/flutter/issues/75316#issuecomment-781869829 seem to contradict one another. @TahaTesser are you able to reproduce this issue on all versions?

I think we have a theory of why this could be happening. When the "authorization dialog" pops up, the application resigns active and we must suspend all rendering. However, to snapshot the scene, we have to switch to the onscreen context which is now disabled by the sync switch (cc @gaaclarke). It might be easier to to reproduce this issue in the presence of the dialog. If we can verify this, we'll probably have to switch to snapshotting on the IO context while in the background or rework the sync switch.

chinmaygarde avatar Feb 22 '21 19:02 chinmaygarde

This sounds like UIApplication.State.background may more closely match the actual requirements for disabling the GPU, not UIApplication.State.active. I think active was chosen over background out of an abundance of caution. It's just a couple lines of code to change it, but is risky because it's hard to test (in an automated fashion).

gaaclarke avatar Feb 22 '21 21:02 gaaclarke

@chinmaygarde It is tricky to reproduce, I was only able to reproduce on the stable channel but the author confirms it still exists on other channels. Even on stable, sometimes it worked for me, sometimes it didn't in XR (14.4) physical device.

TahaTesser avatar Feb 23 '21 10:02 TahaTesser

I ran into the same problem, it occurs when multiple engines are used. When engine1 is used and recycled, then engine2 is created, and getImage in engine2, the problem occurs. Flutter (Channel stable, 2.0.5)

fayduan avatar May 28 '21 02:05 fayduan

when use EngineGroup , the problem occurs. The Image widget will gone.

frasker avatar Jul 01 '21 07:07 frasker

If this works on master, https://github.com/flutter/engine/pull/25196 may have fixed this based on my previous comment.

gaaclarke avatar Jul 01 '21 17:07 gaaclarke

Android platform has the same problem,stable branch 2.2.2, only occurs when using Engine Group on first engine be distroyed and the second engine created

frasker avatar Jul 02 '21 01:07 frasker

Use of flutterenginegroup causes the Image elements in the screenshot to disappear.

In IOS, I solve this problem by pre initializing an engine in appdelegate to host the pages that need screenshots.

In Android, there is no problem,You can get the perfect screenshot

Rempage avatar Sep 09 '21 07:09 Rempage

I suspect that on iOS we'll run into issues where an image was created as GPU resident in the foreground, and then snapshotting happens in the background in a CPU context and can't render the GPU resident image into the snapshot...

dnfield avatar Apr 01 '22 00:04 dnfield

I am trying to get screenshot but on Web And the Images are missing in the output

New-dev0 avatar Jun 26 '22 19:06 New-dev0

same issue

Gavin0x0 avatar Oct 14 '22 11:10 Gavin0x0

3.7.1 solved this problem

Rempage avatar Feb 07 '23 10:02 Rempage

I cannot reproduce this issue on the latest version of flutter using the code sample in https://github.com/flutter/flutter/issues/75316#issuecomment-781869829 updated for the latest version of flutter. I tried it over 150 times and in all cases, the images were rendered properly.

recording

https://user-images.githubusercontent.com/88313112/233621394-55077617-db06-48e4-a3fb-86456c918290.MP4

Given that the bug no longer reproduces, I'll be closing the issue. If anyone is still facing this issue on the latest versions of flutter, kindly file a new issue and provide detailed steps to reproduce the issue.

Thank you

code sample
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:qr_flutter/qr_flutter.dart';

void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: const QrCodeWidget(),
      ),
    );
  }
}

class QrCodeWidget extends StatefulWidget {
  const QrCodeWidget({Key? key}) : super(key: key);

  @override
  State<QrCodeWidget> createState() => _QrCodeWidgetState();
}

class _QrCodeWidgetState extends State<QrCodeWidget> {
  final ScrollController controller =
      ScrollController(initialScrollOffset: -1, keepScrollOffset: true);
  late ui.Image image;
  GlobalKey repaintWidgetKey = GlobalKey();
  String _barCodeString = "123456";

  _saveImage() async {
    PermissionStatus permission = await Permission.photos.request();
    bool isPhotoGranted = (permission.isPermanentlyDenied ||
        permission.isRestricted ||
        permission.isGranted);
    if (!isPhotoGranted) {
      return;
    }

    ByteData? sourceByteData = await _capturePngToByteData();
    if (sourceByteData == null) {
      return;
    }
    final result = await ImageGallerySaver.saveImage(
        sourceByteData.buffer.asUint8List(),
        quality: 60,
        name: "hello");
    if (result["isSuccess"]) {
      print("success");
    } else {
      print("fail");
    }
  }

  Future<ByteData?> _capturePngToByteData() async {
    try {
      RenderRepaintBoundary boundary = repaintWidgetKey.currentContext!
          .findRenderObject() as RenderRepaintBoundary;
      double dpr = ui.window.devicePixelRatio;
      ui.Image image = await boundary.toImage(pixelRatio: dpr);
      ByteData? _byteData =
          await image.toByteData(format: ui.ImageByteFormat.png);
      return _byteData;
    } catch (e) {
      print(e);
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.green,
      body: Stack(
        children: <Widget>[
          CustomScrollView(
            slivers: <Widget>[
              SliverToBoxAdapter(
                child: GestureDetector(
                  child: Container(
                    width: 110,
                    alignment: Alignment.center,
                    margin: const EdgeInsets.only(top: 20),
                    height: 35,
                    decoration: BoxDecoration(
                        borderRadius:
                            const BorderRadius.all(Radius.circular(19)),
                        color: Colors.transparent,
                        border: Border.all(color: Colors.white, width: 0.5)),
                    child: const Text(
                      "save",
                      style: TextStyle(color: Colors.white, fontSize: 14),
                    ),
                  ),
                  onTap: () {
                    _saveImage();
                  },
                ),
              ),
            ],
            controller: controller,
          ),
          _renderQrCaptureView(),
        ],
      ),
    );
  }

  _renderQrCaptureView() {
    const assetImage = AssetImage("res/images/icon_default_portrait.png");
    final imageAsset = Image.asset("res/images/icon_default_portrait.png");
    double topImageWidth = 75.0;
    double qrCodeImageWitdh = 135;
    return Positioned(
      top: MediaQuery.of(context).size.height,
      child: RepaintBoundary(
        key: repaintWidgetKey,
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: 667,
          decoration: const BoxDecoration(
            color: Colors.black,
            image: DecorationImage(image: assetImage, fit: BoxFit.fill),
          ),
          child: Stack(
            alignment: Alignment.topCenter,
            children: [
              Positioned(
                top: 164,
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(10),
                  child: Container(
                    color: Colors.white,
                    width: 335,
                    height: 365,
                    child: Column(
                      children: [
                        Expanded(
                            flex: 135,
                            child: Container(
                              constraints: const BoxConstraints.expand(),
                              color: Colors.grey,
                              child: Column(
                                children: [
                                  Container(
                                      margin: const EdgeInsets.only(top: 50),
                                      child: const Text(
                                        "Name",
                                        style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                        ),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                  Container(
                                      margin: const EdgeInsets.only(
                                          top: 20, left: 5, right: 5),
                                      child: const Text(
                                        "desc",
                                        style: TextStyle(
                                            color: Colors.black,
                                            fontWeight: FontWeight.w400,
                                            fontSize: 20),
                                        overflow: TextOverflow.ellipsis,
                                        maxLines: 1,
                                      )),
                                ],
                              ),
                            )),
                        Expanded(
                            flex: 231,
                            child: Container(
                              color: Colors.white,
                              child: Column(
                                children: [
                                  Container(
                                    margin: const EdgeInsets.only(top: 18),
                                    child: QrImage(
                                      data: _barCodeString,
                                      version: QrVersions.auto,
                                      padding: const EdgeInsets.all(5),
                                      size: qrCodeImageWitdh,
                                      backgroundColor: Colors.white,
                                      errorCorrectionLevel:
                                          QrErrorCorrectLevel.H,
                                      embeddedImage: assetImage,
                                      embeddedImageStyle: QrEmbeddedImageStyle(
                                        size: Size(qrCodeImageWitdh / 5.0,
                                            qrCodeImageWitdh / 5.0),
                                      ),
                                    ),
                                  ),
                                  Container(
                                    margin: const EdgeInsets.only(top: 15),
                                    child: const Text(
                                      "time",
                                      style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                          fontSize: 14),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                  Container(
                                    margin: const EdgeInsets.only(top: 5),
                                    child: const Text(
                                      "text",
                                      style: TextStyle(
                                          color: Colors.black,
                                          fontWeight: FontWeight.w400,
                                          fontSize: 13),
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ),
                                ],
                              ),
                            )),
                      ],
                    ),
                  ),
                ),
              ),
              Positioned(
                top: 127,
                child: Container(
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(
                        Radius.circular((topImageWidth + 4) / 2.0)),
                    border: Border.all(color: Colors.white, width: 2),
                  ),
                  child: SizedBox(
                    height: topImageWidth,
                    width: topImageWidth,
                    child: CircleAvatar(
                        radius: topImageWidth / 2.0, child: imageAsset),
                  ),
                ),
              ),
              Positioned(
                bottom: 31,
                child: Image.asset(
                  "res/images/icon_default_portrait.png",
                  height: 21,
                  fit: BoxFit.contain,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
flutter doctor -v
[✓] Flutter (Channel stable, 3.7.12, on macOS 13.3.1 22E261 darwin-arm64, locale en-GB)
    • Flutter version 3.7.12 on channel stable at /Users/nexus/dev/sdks/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 4d9e56e694 (3 days 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 33.0.0)
    • Android SDK at /Users/nexus/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • Java binary at: /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.9862592/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3)
    • Xcode at /Applications/Xcode-14.3.0.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 2022.1)
    • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/221.6008.13.2211.9619390/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.15+0-b2043.56-8887301)

[✓] Android Studio (version 2022.2)
    • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.9862592/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 17.0.6+0-17.0.6b802.4-9586694)

[✓] IntelliJ IDEA Ultimate Edition (version 2023.1)
    • IntelliJ at /Users/nexus/Applications/JetBrains Toolbox/IntelliJ IDEA Ultimate.app
    • Flutter plugin version 73.0.4
    • Dart plugin version 231.8109.91

[✓] IntelliJ IDEA Ultimate Edition (version 2023.1)
    • IntelliJ at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/231.8109.175/IntelliJ IDEA.app
    • 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

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

[✓] Connected device (3 available)
    • Nexus (mobile)  • 00008020-001875E83A38002E • ios            • iOS 16.4.1 20E252
    • macOS (desktop) • macos                     • darwin-arm64   • macOS 13.3.1 22E261 darwin-arm64
    • Chrome (web)    • chrome                    • web-javascript • Google Chrome 112.0.5615.137

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

• No issues found!
[!] Flutter (Channel master, 3.10.0-10.0.pre.39, on macOS 13.3.1 22E261 darwin-arm64, locale en-GB)
    • Flutter version 3.10.0-10.0.pre.39 on channel master at /Users/nexus/dev/sdks/flutters
    ! Warning: `flutter` on your path resolves to /Users/nexus/dev/sdks/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutters. Consider adding /Users/nexus/dev/sdks/flutters/bin to the front of your path.
    ! Warning: `dart` on your path resolves to /Users/nexus/dev/sdks/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutters. Consider adding /Users/nexus/dev/sdks/flutters/bin to the front of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision d186792c00 (7 hours ago), 2023-04-20 20:50:59 -0700
    • Engine revision 122c3b3820
    • Dart version 3.1.0 (build 3.1.0-26.0.dev)
    • DevTools version 2.23.1
    • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /Users/nexus/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • Java binary at: /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.9862592/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3)
    • Xcode at /Applications/Xcode-14.3.0.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 2022.1)
    • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/221.6008.13.2211.9619390/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.15+0-b2043.56-8887301)

[✓] Android Studio (version 2022.2)
    • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.9862592/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 17.0.6+0-17.0.6b802.4-9586694)

[✓] IntelliJ IDEA Ultimate Edition (version 2023.1)
    • IntelliJ at /Users/nexus/Applications/JetBrains Toolbox/IntelliJ IDEA Ultimate.app
    • Flutter plugin version 73.0.4
    • Dart plugin version 231.8109.91

[✓] IntelliJ IDEA Ultimate Edition (version 2023.1)
    • IntelliJ at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/231.8109.175/IntelliJ IDEA.app
    • 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

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

[✓] Connected device (3 available)
    • Nexus (mobile)  • 00008020-001875E83A38002E • ios            • iOS 16.4.1 20E252
    • macOS (desktop) • macos                     • darwin-arm64   • macOS 13.3.1 22E261 darwin-arm64
    • Chrome (web)    • chrome                    • web-javascript • Google Chrome 112.0.5615.137

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 1 category.

danagbemava-nc avatar Apr 21 '23 11:04 danagbemava-nc

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

github-actions[bot] avatar May 05 '23 12:05 github-actions[bot]