Create gif from saved images

I have 3000 images.They are the result of calculations on Julia. This images is a graphic of probablity density function (PDF), time series and lyapunov spectrum. How can i create gif from images PDF, time series and lyapunov spectrum ?
Images of PDF have name type of “* PDF” where * is number. Similarly for time series and Lyapunov spectrum that is “* timeseries”; “* spectrum”.

Might be related to Plotting a sequence of images as a gif

it won’t help me. I tried this

With Plots you can create an animation from your png files only if these files have the names “000001.png”, …“003000.png”,
because the file names for animation frames are predefined here https://github.com/JuliaPlots/Plots.jl/blob/master/src/animation.jl#L16
If the pngs are already generated and saved in a folder, and you don’t want to repeat the computations that led to your images it would be nice if there was a way to change their names through code. I don’t know whether this is posssible or not.

Once your pngs have the right name, then define the vector of their names, and animate your frames:

import Printf.@sprintf
import Plots:Animation, buildanimation  
nframes =3000                
fnames = [@sprintf("%06d.png", k) for k  in 1:nframes]   
anim = Animation("PDF", fnames); #PDF is the folder name which contains the pngs
buildanimation(anim, "path-to-gif/your-animation-name.gif", fps = 12, show_msg=false) #set a suitable fps

But if you can repeat the computations that generated your pngs, then you can create an animation, usually, with Plots,jl.

2 Likes

Thank you. i try this

Hi! I hope you solved your problem with @empet’s excellent advice.

If you find you’re doing this type of thing often, you might find it useful to have FFMPEG.jl in your toolbox. FFMPEG is the “Swiss Army knife” of image and video processing, and it’s conveniently wrapped in a Julia package.

If all your PNG files are named in the same way, you can write code such as this:

using FFMPEG
imagesdirectory = "/tmp/temp/"
framerate = 30
gifname = "/tmp/output.gif"
FFMPEG.ffmpeg_exe(`-framerate $(framerate) -f image2 -i $(imagesdirectory)/%10d.png -y $(gifname)`)

In this command, the %10d.png matches all files named with just 10 digits followed by “.png”. If your first file was 00001-timeseries.png you would use %05d-timeseries.png. The -y overwrites the GIF output file if it already exists.

You can use similar commands to create ‘real’ videos - this function:

FFMPEG.ffmpeg_exe(`-framerate $(framerate) -f image2 -i $(imagesdirectory)/%10d.png -vf "scale=1920:1080" -c:v libx264 -pix_fmt yuv420p -y "/tmp/output-video.mov"`)

rescales every image then outputs a video in a MPEG 4 container file.

(In a test I just did with this bigger output, the GIF file size for 150 frames was 198Mb, the equivalent movie was 4Mb. Presumably a fair amount of lossy compression going on.)

4 Likes

Thank you. That helped me. The previous answer also worked, but required extra steps to rename the files

1 Like

I have a problem when creating a gif. Path to folder is correct, he is worked for saving files

For example this is worked:

fig.savefig("res_HR_full_small/full/$i.png")

and this code don’t work:

imagesdirectory = "res_HR_full_small/full/"

framerate = 30
gifname = "res_HR_full_small/full/output.gif"

FFMPEG.ffmpeg_exe(`-framerate $(framerate) -f image2 -i $(imagesdirectory)/%1000d.png -y $(gifname)`)

Also i used cd() for test:

The files should be named consistently with regard to the number of digits, lpad() is useful:

for i in 1:10
    println(lpad(i, 10, "0"))
end

Then, the number of digits is specified in the command. So %10d.png for 10 digit filenames such as 0000000010.png. (so not %1000d…)

1 Like

I need rename all files ?

You’ll probably have to do that anyway - at the moment they’re not in order since the last file appears in the list before the second file - unless you sort the list by numerical value.

Okay, i try
How fix this line code for correct save file ?

fig.savefig("res_HR_full_small/full/$i.png")

Use lpad() to make filenames all the same length, so replace $i with

   $(lpad(i, 10, "0"))
2 Likes

Thank you

I created gif but it has broken images. For example this is images



and this gif
output

Output:

I’m glad you got it working. But now your question moves into a different area - video quality, color palettes, etc.

Assuming all your input files are correct … I can suggest a few things, since video stuff isn’t my thing.

  • try making sure there’s a solid background for each image, such as pure white. Animated GIFs don’t always like “transparent” backgrounds.

  • try another output format; GIF is OK for smaller purposes, but it looks like other video formats might do better

  • ffmpeg lets you work with GIF color palettes. It’s out of scope for this question and my knowledge, but searching the internet may lead you to some useful sources, such as this, where the (possibly biased :slight_smile: ) author writes:

    The issue seems to be that FFmpeg’s native gif encoder doesn’t take into account the colors in the source image, and as an indexed color format, that just won’t do for a GIF.

2 Likes

Okay, thank you

i try create video and this help. Now i have correct colors in animation
again thank you

It would be great to paste your solution here if possible to help others :slight_smile:

Okay
That is code for video:

using FFMPEG
imagesdirectory = pwd()
gifname = "\\output.gif"
gifname = imagesdirectory * gifname

framerate = 10

FFMPEG.ffmpeg_exe(`-framerate $(framerate) -f image2 -i $(imagesdirectory)/%5d.png -vf "scale=1200:900" -c:v libx264 -pix_fmt yuv420p -y "C:\\Users\\olenin.s\\Desktop\\test\\output-video.mov"`)

This is code for rename files:

for i in range(1, 1001)
    mv("$i.png", "$(lpad(i, 5, "0")).png")
end

but before run this code need go to directory with files
commalnd for switch directory:

cd("directory")

also command to know current directory:

pwd()

code for save images ( I using package PyPlot):

filename = "$(lpad(1, 4, "0")).png"
directory = "C:\\Users\\olenin.s\\Desktop\\res_HR_full_small\\"
directory = directory * filename

fig.savefig(directory)
1 Like