0

I am trying to take a Screenshot of Current Widget and wanted it to be stored in the gallery, I am not getting the desired answers of the question throughout the web..

These are the packages i am Currently using.

flip_card: ^0.5.0
screenshot:

I have my widget of Quotes, which is wrapped inside the flip_card Package widget,

    @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: DefaultAssetBundle.of(context).loadString("jsons/quotes.json"),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (!snapshot.hasData) {
            return Container(
              child: Center(
                child: SizedBox(
                  child: CircularProgressIndicator(),
                  height: 60.0,
                  width: 60.0,
                ),
              ),
            ); // I understand it will be empty for now
          } else {
            var myquotes = json.decode(snapshot.data.toString());
            int lengthofJSON = 1643;
            var rangeofQuotes = random(0, lengthofJSON);

        //var randomMyQuotes = myquotes[0].shuffle().first;
        return FlipCard(
          direction: FlipDirection.HORIZONTAL,
          front: Screenshot(
            controller: screenshotquotes,
            child: Card(
              // color: Colors.transparent,
              child: GradientCard(
                gradient: Gradients.buildGradient(
                    Alignment.topRight, Alignment.bottomLeft, [
                  Colors.blueAccent[700],
                  Colors.blue,
                  Colors.blueAccent[100],
                  // Colors.black54,
                  //  Colors.black87,
                  //  Colors.black87,
                ]),
                semanticContainer: false,
                child: Wrap(
                  children: [
                    Center(
                      child: Column(
                        children: [
                          Padding(
                              padding: EdgeInsets.all(
                                  MediaQuery.of(context).size.width / 20)),
                          Container(
                              child: Icon(CarbonIcons.quotes,
                                  color: Colors.white)),
                          Container(
                              padding: EdgeInsets.all(
                                  MediaQuery.of(context).size.width / 30),
                              child: Text(
                                  "${myquotes[rangeofQuotes]["text"]}",
                                  style: TextStyle(
                                      color: Colors.white,
                                      fontSize: (myquotes[rangeofQuotes]
                                                      ["text"]) //161
                                                  .length >
                                              90
                                          ? 12
                                          : 16))),
                          Container(
                              padding: EdgeInsets.all(
                                  MediaQuery.of(context).size.width / 30),
                              child: Text(
                                  "@${myquotes[rangeofQuotes]["author"]}",
                                  style: TextStyle(
                                      color: Colors.white,
                                      fontSize: 12,
                                      fontStyle: FontStyle.italic)))
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),

And in the Back I got a back: (widget) from the flip_card widget, Which looks like this,

back: Card(
            // color: Colors.transparent,
            child: GradientCard(
              gradient: Gradients.buildGradient(
                  Alignment.bottomRight, Alignment.topRight, [
                Colors.blueAccent[700],
                Colors.blue,
                Colors.blue[400],
                //Colors.blueAccent[700],
                // Colors.white,
              ]),
              semanticContainer: false,
              child: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Container(
                        padding: EdgeInsets.all(
                            MediaQuery.of(context).size.width / 30),
                        child: Text("Share or Download",
                            textAlign: TextAlign.center,
                            style: TextStyle(
                              color: Colors.white,
                              fontSize: 16,
                              fontWeight: FontWeight.bold,
                            ))),
                    Row(
                      children: [
                        Expanded(
                          child: Align(
                            alignment: Alignment.center,
                            child: Center(
                                child: CircleAvatar(
                              radius: 30,
                              backgroundColor: Colors.white,
                              child: IconButton(
                                onPressed: () {},
                                icon: Icon(CarbonIcons.share),
                              ),
                            )),
                          ),
                        ),
                        Expanded(
                          child: Align(
                            alignment: Alignment.center,
                            child: Center(
                                child: CircleAvatar(
                              radius: 30,
                              backgroundColor: Colors.white,
                              child: IconButton(
                                onPressed: () {
                                  screenshotquotes
                                      .capture()
                                      .then((Uint8List image) async {
                                    //Capture Done

                                    setState(() {
                                      _imageFile = image;
                                    });
                                  }).catchError((onError) {
                                    print(onError);
                                  });

                                  print("Quote Captured");
                                  ScaffoldMessenger.of(context)
                                      .showSnackBar(SnackBar(
                                          backgroundColor: Colors.blue[200],
                                          content: Row(
                                            children: [
                                              Expanded(
                                                  flex: 1,
                                                  child: Text("",
                                                      style: TextStyle(
                                                          color: Colors
                                                              .white))),
                                              Expanded(
                                                  flex: 5,
                                                  child: Text(
                                                    "Quotes, is captured sucessfully",
                                                  )),
                                              // FlatButton(
                                              //   child: Text("Undo"),
                                              //   color: Colors.white,
                                              //   onPressed: () async{
                                              //     await box.deleteAt(index);
                                              //     Navigator.pop(context);
                                              //   },
                                              // ),
                                            ],
                                          )));
                                },
                                icon: Icon(CarbonIcons.download),
                              ),
                            )),
                          ),
                        ),
                      ],
                    )
                  ],
                ),
              ),
            ),
          ),
        );
      }
    });
  }

  random(min, max) {
    var rn = new Random();
    return min + rn.nextInt(max - min);
  }
}

From all of these, i am neither getting a screenshotted image in the Internal folder of my App which is com.example.tooodo, nor i am getting something in the gallery.

I want to seek your attention in this. Thank you, May You get Great heights.

Pro Co
  • 341
  • 3
  • 10
  • https://stackoverflow.com/questions/51117958/how-to-take-a-screenshot-of-the-current-widget-flutter – Andrej May 06 '21 at 08:17
  • Do you know, the location, where the final image will be stored, @Andrej – Pro Co May 06 '21 at 08:25
  • If you use https://stackoverflow.com/a/51118092/13646430 method you will get the image bytes for the screenshot and then you can do anything you want with it. – Andrej May 06 '21 at 08:26

1 Answers1

0

You can use RepaintBoundary Class, like wrap your Widget in RepaintBoundary Class like this : return Scaffold( appbar:AppBar(), body:Container( child: RepaintBoundary( key : _repaintKey, child:Stack()) ));

don't forget to give key to RepaintBoundary like

 GlobalKey _repaintKey = new GlobalKey();

and now you can capture that part in RepaintBoundary

Future<Uint8List> captureBoundary() async {
try {
  RenderRepaintBoundary boundary =
      _repaintKey.currentContext.findRenderObject();
  Image savedImage = await boundary.toImage(pixelRatio: 3.0);
  ByteData byteData =
      await savedImage.toByteData(format: ImageByteFormat.png);
  UInt8List pngBytes = byteData.buffer.asUint8List();
  saveFile(widget.pickedImage.uri.path, pngBytes);
  return pngBytes;
} catch (e) {
  print(e);
}

}

here, saveFile() is called for saving captured image to phone storage, and inside saveFile

Future<bool> saveFile( var byteList) async {
Directory storageDir;
try {
  if (await requestPermission(Permission.storage)) {
    storageDir = await getExternalStorageDirectory();

    String newPath = '';
    List<String> folders = storageDir.path.split('/');
    for (int x = 1; x < folders.length; x++) {
      String folder = folders[x];
      if (folder != 'Android') {
        newPath += '/' + folder;
      } else {
        break;
      }
    }
    newPath = newPath + '/yourFolderName';
    storageDir = Directory(newPath);
  } else {
    if (await requestPermission(Permission.photos)) {
      storageDir = await getTemporaryDirectory();
    } else {
      return false;
    }
  }
  if (!await storageDir.exists()) {
    await storageDir.create(recursive: true);
  }
  if (await storageDir.exists()) {
    File savedFile = File(storageDir.path + "/yourfileName");
    String savedPath = storageDir.path + "/yourfileName";
    savedFile.writeAsBytesSync(byteList); //the byteList that you send from captureBoundary
    if (savedPath != null) {
      print("File saved");
    } else {
      print("Error saving");
    }
    return true;
  }
} catch (e) {
  print(e);
}
return false;

}

Hope,this will be helpful!

Yash Kadiya
  • 101
  • 1
  • 8
  • So Yash, Are you using any packages? – Pro Co May 06 '21 at 09:28
  • yes, for getting path of storage `path`, for permission `permission_handler` and you need to modify AndroidManifest.xml file to for storage access. – Yash Kadiya May 06 '21 at 09:33
  • Thanks Yash, it is showing me alot of errors, like, baseFileName is not Specified, saved Path is not Specified so and so. if you have initiallized some variables above you can specify.. – Pro Co May 06 '21 at 10:06
  • I've Edited the code just try again , by the way savedPath is String variable and baseFilename is just name you want to give your file. – Yash Kadiya May 06 '21 at 11:13