Reputation: 9622
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.
Upvotes: 9
Views: 29176
Reputation: 274
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])
Upvotes: 0
Reputation: 4241
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'
Upvotes: 1
Reputation: 400
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.
Upvotes: 7
Reputation: 1201
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.
Upvotes: 18