Mohammad Alamoudi
Mohammad Alamoudi

Reputation: 415

Convert Widget to Image.png and Save it In Created Directory Flutter

I want my app when install first thing create specific directory in internal storage and a button when clicked it's convert specific widget(screen) to image.png then save it in that created directory.

I need full code for that. I've been looking, but I haven't found an effective way.

Upvotes: 0

Views: 2340

Answers (2)

Hadiuzzaman
Hadiuzzaman

Reputation: 482

Here is the complete implementation

import 'package:path_provider/path_provider.dart';
import 'dart:io';
class WidgetScreenshotExample extends StatefulWidget {
  const WidgetScreenshotExample({super.key});

  @override
  State<WidgetScreenshotExample> createState() =>
      _WidgetScreenshotExampleState();
}

class _WidgetScreenshotExampleState extends State<WidgetScreenshotExample> {
  final globalKey = GlobalKey();

  Future<Uint8List> takeScreenshot() async {
    //Get the render object from context.
    final boundary =
        globalKey.currentContext?.findRenderObject() as RenderRepaintBoundary;
    //Convert to the image
    final image = await boundary.toImage();
    final bytes = await image.toByteData(format: ImageByteFormat.png);
    Uint8List memoryImageData = bytes!.buffer.asUint8List();
    return memoryImageData;
  }

  Future<String> saveImage(Uint8List bytes) async {
    final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
    String path = "";
    try {
      Directory root = await getTemporaryDirectory();
      String directoryPath = '${root.path}/appName';
      // Create the directory if it doesn't exist
      await Directory(directoryPath).create(recursive: true);
      String filePath = '$directoryPath/$timestamp.jpg';
      final file = await File(filePath).writeAsBytes(bytes);
      path = file.path;
    } catch (e) {
      debugPrint(e.toString());
    }
    return path;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: RepaintBoundary(
        key: globalKey,
        child: Container(
          color: Colors.red,
          padding: const EdgeInsets.all(20),
          child: const Text('Your Widget'),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.save),
        onPressed: () async {
          final imageData = await takeScreenshot();
          await saveImage(imageData);
        },
      ),
    );
  }
}

Upvotes: 0

Jim
Jim

Reputation: 7601

this function is all your need for screenshot a widget and save locally:

static GlobalKey _repaintKey = GlobalKey();

Widget _yourWidget(){
  return Stack(
    key: _repaintKey,
    children: [
    ],
  );
}

Future<void> _takeScreenShot(context) async {
    RenderRepaintBoundary boundary = _repaintKey.currentContext.findRenderObject();
    ui.Image image = await boundary.toImage();
    ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    Uint8List pngBytes = byteData.buffer.asUint8List();
    final path = join(
      (await getTemporaryDirectory()).path, "screenshot${DateTime.now().toIso8601String()}.png");
    File imgFile = File(path);
    imgFile.writeAsBytes(pngBytes).then((value) {
      Navigator.of(context).pushNamed(Routes.uploadImage, arguments: value.uri.path);
    }).catchError((onError) {
      print(onError);
    });
}

Upvotes: 0

Related Questions