Can we export custom painter used animation controller to a gif image or continuous images or event a video such as mp4 file?
2 Answers
Yes I did it one time (2 years ago) and I converted a Flutter Animation to a mp4 file. unfortunately I couldn't find the code. please follow the steps to make what you want.
capture your widget with
RenderRepaintBoundary
like below code https://api.flutter.dev/flutter/rendering/RenderRepaintBoundary/toImage.htmlclass PngHome extends StatefulWidget { const PngHome({super.key}); @override State<PngHome> createState() => _PngHomeState(); } class _PngHomeState extends State<PngHome> { GlobalKey globalKey = GlobalKey(); Future<void> _capturePng() async { final RenderRepaintBoundary boundary = globalKey.currentContext!.findRenderObject()! as RenderRepaintBoundary; final ui.Image image = await boundary.toImage(); final ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png); final Uint8List pngBytes = byteData!.buffer.asUint8List(); print(pngBytes); } @override Widget build(BuildContext context) { return RepaintBoundary( key: globalKey, child: Center( child: TextButton( onPressed: _capturePng, child: const Text('Hello World', textDirection: TextDirection.ltr), ), ), ); } }
save each image like this
import 'package:path_provider/path_provider.dart'; import 'dart:io'; Uint8List imageInUnit8List = // store unit8List image here ; final tempDir = await getTemporaryDirectory(); File file = await File('${tempDir.path}/image.png').create(); file.writeAsBytesSync(imageInUnit8List);
you need to capture each frame of your Animation and save it to a directory. with special naming for example (
1.png
,2.png
....1000.png
)@override Widget build(BuildContext context) { return AnimatedBuilder( animation: _controller, child: theChildWidet() // important use child for performance builder: (BuildContext context, Widget? child) { CaptureScreenAndSave(_controller.value) /// <- capture each frame return Transform.rotate( angle: _controller.value * 2.0 * math.pi, child: child, ); }, ); }
install
ffmpeg
https://pub.dev/packages/ffmpeg_kit_flutter and use it to execute FFMPEG commandimport 'package:ffmpeg_kit_flutter/ffmpeg_kit.dart'; FFmpegKit.execute('your command').then((session) async { final returnCode = await session.getReturnCode(); if (ReturnCode.isSuccess(returnCode)) { // SUCCESS } else if (ReturnCode.isCancel(returnCode)) { // CANCEL } else { // ERROR } });
search for a command to convert your images with
ffmpeg
to Gif Or Mp4 (some thing like these Example1 or Example2)

- 2,593
- 16
- 26
-
Thank you for the response. In the second step, does that mean I have to create a loop to run 1000 times and capture images each time? Should I have a delay set with each loop? Also, doesn't that take a lot of time to process - just to run the loop? – Danny Feb 21 '23 at 04:15
-
1your welcome !,@Danny , in your Animation builder in Builder method, you can call captureAndSave method. because build method calls on each frame of your animation. I updated the answer – Sajjad Feb 22 '23 at 08:32
-
1we need 25 Frame per second but Flutter renders 60 frame per second, so I think we can improve performance with skipping some frame and using compute for multithreading https://api.flutter.dev/flutter/foundation/compute-constant.html – Sajjad Feb 22 '23 at 08:43
-
1what I tested isn't heavy . so I think multithreading is enough . no need to skip frames. – Sajjad Feb 22 '23 at 08:45
-
Thank you again! I will look into it. I wasn't aware of `compute constant`. I think this is a good way to go. – Danny Feb 22 '23 at 08:49
you can use screenshot library. by wrapping the parent container with Screenshot library you can convert widget to multiple images and those images can be converted to a gif but I think it is tricky, not efficient, and difficult to implement. you can give it a try.

- 645
- 7
- 8