Is their any way to convert .jpeg images to .gif in flutter?
You can use the image
package to created animated GIFs from multiple images.
First add it as a dependency:
dependencies:
image: ^3.0.2
Then to you can make a function to generate an animated GIF from multiple images:
List<int>? generateGIF(Iterable<Image> images) {
final Animation animation = Animation();
for(Image image in images) {
animation.addFrame(image);
}
return encodeGifAnimation(animation);
}
To use this function with multiple images that are in files from the camera
package in the form of XFile
s, you have to decode the images for each of those files and pass it to this function. The following code assumes you know that these are JPEG images:
List<XFile> imageFiles = ...;
final JpegDecoder decoder = JpegDecoder();
final List<Image> images = [];
for(var imgFile in imageFiles) {
Uint8List data = await imgFile.readAsBytes();
images.add(decoder.decodeImage(data));
}
List<int>? gifData = generateGIF(images);
John Park
Updated on December 29, 2022Comments
-
John Park over 1 year
Like my title, is there anyway to convert images to a video in flutter? (It doesn't have to be .gif necessarily)
To be more specific, I am using Google Firebase as my storage cloud server to upload pictures taken by camera plugin of flutter.
I want to convert my images to a video so that it looks like a time-lapse video. Any advice would be nice.
===============================
the pictures are taken by camera plugin which uses camera.dart, and it is stored it firebase storage like this:
onCapture(context) async { try { final p = await getTemporaryDirectory(); var now = DateTime.now(); var formattedDate = DateFormat('yy-MM-dd HH:mm:ss').format(now); final path = '${p.path}/$now.png'; await cameraController.takePicture(path).then((value) { print('here'); Navigator.push( context, MaterialPageRoute( builder: (context) => PreviewScreen( imgPath: path, fileName: '$formattedDate.png', pickedTime: '$formattedDate', ))); }); } catch (e) { showCameraException(e); } }
========================================
edit : Before constructing gif, i am having trouble downloading an image from firebase and putting this image on the canvas. I think I can use your code to make a gif once I do this.
import 'dart:io'; import 'dart:isolate'; import 'package:flutter/material.dart'; import 'package:image/image.dart' as IMG; import 'package:path/path.dart'; import 'package:path_provider/path_provider.dart'; import 'package:firebase_storage/firebase_storage.dart' as firebase_storage; import 'package:firebase_core/firebase_core.dart' as firebase_core; import 'package:provider/provider.dart'; import 'package:weighit/models/user_info.dart'; class ToGif extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Timelapse Video'), ), body: Container( child: Thumbnail(), ), ); } } class Thumbnail extends StatefulWidget { const Thumbnail({Key key}) : super(key: key); @override _ThumbnailState createState() => _ThumbnailState(); } class _ThumbnailState extends State<Thumbnail> { List<int> imgBytes; Isolate isolate; File image; @override void initState() { _asyncInit(); super.initState(); } static _isolateEntry(dynamic d) async { final ReceivePort receivePort = ReceivePort(); d.send(receivePort.sendPort); final config = await receivePort.first; print(config); final file = File(config['path']); final bytes = await file.readAsBytes(); IMG.Image image = IMG.decodeImage(bytes); IMG.Image thumbnail = IMG.copyResize( image, width: config['size'].width.toInt(), ); d.send(IMG.encodeNamedImage(thumbnail, basename(config['path']))); } _asyncInit() async { final receivePort = ReceivePort(); isolate = await Isolate.spawn(_isolateEntry, receivePort.sendPort); receivePort.listen((dynamic data) { if (data is SendPort) { if (mounted) { data.send({ 'path': image.path, 'size': Size(500, 500), }); } } else { if (mounted) { setState(() { imgBytes = data; }); } } }); } @override void dispose() { if (isolate != null) { isolate.kill(); } super.dispose(); } // Download on DocumnetDirectory, not temporary directory https://flutter-ko.dev/docs/cookbook/persistence/reading-writing-files Future<void> downloadFileExample() async { final appDocDir = await getApplicationDocumentsDirectory(); image = File('${appDocDir.path}/download-logo.png'); try { await firebase_storage.FirebaseStorage.instance // can not find proper reference path... .ref('gs://weighit-f506b.appspot.com/guny/21-04-26 10:56:21.png') .writeToFile(image); } on firebase_core.FirebaseException catch (e) { print('couldnt find the reference'); } } @override Widget build(BuildContext context) { final _user = Provider.of<TheUser>(context); return FutureBuilder( future: downloadFileExample(), builder: (context, snapshot) { //해당 부분은 data를 아직 받아 오지 못했을때 실행되는 부분을 의미한다. if (snapshot.hasData == false) { return Center(child: CircularProgressIndicator()); } //error가 발생하게 될 경우 반환하게 되는 부분 else if (snapshot.hasError) { return Padding( padding: const EdgeInsets.all(8.0), child: Text( 'Error: ${snapshot.error}', style: TextStyle(fontSize: 15), ), ); } else { return SizedBox( height: 500, width: 500, child: imgBytes != null ? Image.memory( imgBytes, fit: BoxFit.cover, ) : Container( decoration: BoxDecoration( gradient: LinearGradient( colors: [Colors.grey[100], Colors.grey[300]], begin: Alignment.centerLeft, end: Alignment.centerRight, ), ), ), ); } }, ); } }
-
Rachel Gallen about 3 yearsplease add a code sample of what you have tried so far
-
John Park about 3 years@RachelGallen sorry for the late reply, it was my mid-term exam week so I didn't have time to check! I will show my code, but I don't have any code that converts images to .gif since I don't have any clue :(
-
-
John Park about 3 yearsThank you for giving me an idea to implement timelapse video. But I tried your code, and it didn't work out well :( I am quite new to flutter, so I couldn't sought this out by myself
-
John Park about 3 yearsfirstly, as I import images package to my dart file, it caused an 'ambiguous import' error on declaring Image type. Declaring Animation class was also impossible due to ambiguous error. Also, Animation class is abstract class that couldn't be used... I tried my best to fix these errors but I couldn't help it
-
Christopher Moore about 3 years@JohnPark You need to import the library somewhere. Your IDE should be able to suggest the correct import, but here it is anyways
import 'package:image/image.dart';
-
John Park about 3 yearsThank you! i did that, and the problem was that there is another Image class included in material.dart. I fixed that problem by using 'as' prefix like 'import 'package:image/image.dart' as img;'
-
John Park about 3 yearsI have a new problem now... how do i get a path for image files??
-
Christopher Moore about 3 years@JohnPark What do you have so far? If you're getting it directly from the camera then you should be able to figure it out from the second block of code. If you're getting it from firebase storage, you need to download it as a
Uint8List
and put it into the second block of code in my answer. -
John Park about 3 yearsBefore generating gif, I am having trouble downloading an image from firebase and putting this on the canvas. I posted my code above :) I really appreciate your help
-
Christopher Moore about 3 years@JohnPark Please do not add additional information as answers. Please edit the code into the question and reduce it down as much as possible. You have code to download some firebase images. Make an attempt at downloading the data yourself and if you have problems, be as specific as possible.
-
John Park about 3 yearssorry that I am also new to stackoverflow and I was lacking of basic manners.. I will do my best to find the solutions by myself. Beside that, your answer helped a lot!