python imageio mp4 video from a set of png images
Asked Answered
C

4

9

How do I make an mp4 video from a set of png images with the module imageio? I've tried this:

import imageio
import glob
writer = imageio.get_writer('test.mp4', fps=20)
for png_path in glob.glob('*.png'):
    im = imageio.imread(png_path),
    writer.append_data(im[:, :, 1])
writer.close()

I've also tried replacing im[:, :, 1] with im. What am I doing wrong? I'm happy to use another module.

Craig answered 12/12, 2017 at 14:32 Comment(1)
are your images numbered padded? as test.001.jpgBorrego
A
17

You don't need to modify the image through im[:, :, 1]. For example, the code below takes all images starting with name in a folder specified by path and creates a videofile called "test.mp4"

fileList = []
for file in os.listdir(path):
    if file.startswith(name):
        complete_path = path + file
        fileList.append(complete_path)

writer = imageio.get_writer('test.mp4', fps=20)

for im in fileList:
    writer.append_data(imageio.imread(im))
writer.close()

All images have to be the same size so you should resize them before appending them to the video file. You can modify the fps through fps, I just set it at 20 because I was following your code.

Alded answered 13/12, 2017 at 5:55 Comment(1)
In case others need it, install ffmpeg plugin for mp4 writing with: pip install imageio[ffmpeg]Heather
B
7

A better version of your code combined with Mr K. would be:

import imageio
import glob
import os
writer = imageio.get_writer('test.mp4', fps=20)
for file in glob.glob(os.path.join(path,f'{name}*.png')):
    im = imageio.imread(file)
    writer.append_data(im)
writer.close()

P.S. Don't forget to add image resizing code before appending them to the video file.

Boxhaul answered 17/6, 2021 at 7:44 Comment(1)
You could add the code for th resizing here...Wondawonder
A
1

Wrapping up answers, a short and simple "pythonesque" solution is to use that function:

import imageio
def make_mp4(moviename, fnames, fps):
    with imageio.get_writer(moviename, mode='I', fps=fps) as writer:
        for fname in fnames:
            writer.append_data(imageio.imread(fname))
return 'done'

in conjunction with a loop my_loop creating the images with a function create_image_as_numpy such as:

fnames = []
np_dtype = np.uint8
for i_loop, _ in enumerate(my_loop):
    imgnp = create_image_as_numpy(...)
    fname = f'/tmp/frame_{i_loop}.png'
    imageio.imwrite(fname, imgnp.astype(np_dtype))

    fnames.append(fname)

make_mp4(video_name, fnames, fps=24)

I like to use the /tmp folder (on Linux and MacOs) as it gets flushed at every reboot. Do do that flushing explictly, one can do:

import os
import imageio
def make_mp4(moviename, fnames, fps):
    with imageio.get_writer(moviename, mode='I', fps=fps) as writer:
        for fname in fnames:
            writer.append_data(imageio.imread(fname))
    for fname in fnames: os.remove(fname)
    return 'done'
Aprylapse answered 15/1, 2024 at 8:0 Comment(0)
C
0

Not sure why, but for me, mimsave worked while the get_writer method kept giving a corrupted file. If you have a list of image data (e.g. np.ndarray of shape HxWx3), it looks like this:

imageio.mimsave(mov_path, [image1, image2, image3])
Cisneros answered 14/6, 2024 at 19:3 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.