75

I currently try to make a movie out of images, but i could not find anything helpful .

Here is my code so far:

import time

from PIL import  ImageGrab

x =0

while True:
    try:
        x+= 1
        ImageGrab().grab().save('img{}.png'.format(str(x))
    except:
        movie = #Idontknow
        for _ in range(x):
            movie.save("img{}.png".format(str(_)))

movie.save()
Amir
  • 10,056
  • 9
  • 43
  • 71
Victor
  • 1,287
  • 1
  • 8
  • 10

5 Answers5

134

You could consider using an external tool like ffmpeg to merge the images into a movie (see answer here) or you could try to use OpenCv to combine the images into a movie like the example here.

I'm attaching below a code snipped I used to combine all png files from a folder called "images" into a video.

import cv2
import os

image_folder = 'images'
video_name = 'video.avi'

images = [img for img in os.listdir(image_folder) if img.endswith(".png")]
frame = cv2.imread(os.path.join(image_folder, images[0]))
height, width, layers = frame.shape

video = cv2.VideoWriter(video_name, 0, 1, (width,height))

for image in images:
    video.write(cv2.imread(os.path.join(image_folder, image)))

cv2.destroyAllWindows()
video.release()

It seems that the most commented section of this answer is the use of VideoWriter. You can look up it's documentation in the link of this answer (static) or you can do a bit of digging of your own. The first parameter is the filename, followed by an integer (fourcc in the documentation, the codec used), the FPS count and a tuple of the dimensions of the frame. If you really like digging in that can of worms, here's the fourcc video codecs list.

BoboDarph
  • 2,461
  • 1
  • 11
  • 15
  • 4
    This actually not always does work for ubuntu https://github.com/ContinuumIO/anaconda-issues/issues/223 – Marat Zakirov Dec 19 '17 at 15:49
  • Thank you for posting this solution! It's getting me past loads of problems that I had using other solutions. – Mike from PSG Feb 08 '18 at 00:36
  • 13
    It worked on Ubuntu when i created like video = cv2.VideoWriter(video_name, cv2.VideoWriter_fourcc(*'XVID'), 30, (width,height)) But didn't work when: video = cv2.VideoWriter(video_name, -1, 1, (width,height)) – Отгонтөгс Миймаа Oct 11 '18 at 09:54
  • 1
    FWIW, on my Window 10 with Python 3.6 and opencv 3.3.1, I got a ffmpeg conversion error. Changing the "fourcc" argument, which handles video codecs (2nd argument) of cv2.VideoWriter from -1 to 0 solved it. – Soltius Jan 07 '19 at 14:56
  • i had tried this, it shows a problem on codec error while it playing...i want to know how we can mention codec here? can anyone help me? – Kumar S Feb 14 '19 at 08:13
  • Where do you get `cv2` package from? I've installed `opencv 4.1.1` at `python 3.6`, but I cannot import `cv2` – icemtel Sep 13 '19 at 10:22
  • 1
    how can you precise the framerate ? – nassim Nov 24 '19 at 20:10
  • 7
    @nassim `cv2.VideoWriter(output_filename, fourcc, fps, self._window_shape)` found [Here](https://www.programcreek.com/python/example/72134/cv2.VideoWriter) – Bolli Nov 19 '20 at 13:34
  • 1
    Thanks for the good answer. I would suggest as an improvement to explain and link to the documentation of the VideoWriter (the relevant part). This would make it more easy to get to know which datatypes are needed and what the individual parameters do. – Osmosis D. Jones May 21 '21 at 09:49
  • 1
    Just wanted to highlight that `cv2.VideoWriter` expects the dims in WIDTH then HEIGHT which is different than most the other `cv2` functions – pellucidcoder Dec 03 '21 at 20:11
47

Thanks , but i found an alternative solution using ffmpeg:

def save():
    os.system("ffmpeg -r 1 -i img%01d.png -vcodec mpeg4 -y movie.mp4")

But thank you for your help :)

Victor
  • 1,287
  • 1
  • 8
  • 10
26

Here is a minimal example using moviepy. For me this was the easiest solution.

import os
import moviepy.video.io.ImageSequenceClip
image_folder='folder_with_images'
fps=1

image_files = [os.path.join(image_folder,img)
               for img in os.listdir(image_folder)
               if img.endswith(".png")]
clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(image_files, fps=fps)
clip.write_videofile('my_video.mp4')
Mr_and_Mrs_D
  • 29,590
  • 35
  • 170
  • 347
trygvrad
  • 419
  • 5
  • 3
  • Moviepy https://zulko.github.io/moviepy/examples/examples.html is a great library! – meduz Sep 30 '20 at 11:54
  • I got "OSError: broken data stream when reading image file", which could be resolved with : https://stackoverflow.com/a/47958486/10794682 You can sort your images with "..in sorted(os.listdir(image_folder))..". Note: if your images are numbered, you can either use "natural sorting" (https://stackoverflow.com/a/5967539/10794682) or write a loop: image_files = [] for img_number in range(1,20): image_files.append(path_to_images + 'image_folder/image_' + str(img_number) + '.png') – ConZZito May 12 '21 at 14:41
14

I use the ffmpeg-python binding. You can find more information here.

import ffmpeg
(
    ffmpeg
    .input('/path/to/jpegs/*.jpg', pattern_type='glob', framerate=25)
    .output('movie.mp4')
    .run()
)
jiashenC
  • 1,613
  • 2
  • 15
  • 30
1

When using moviepy's ImageSequenceClip it is important that the images are in an ordered sequence.

While the documentation states that the frames can be ordered alphanumerically under the hood, I found this not to be the case.

So, if you are having problems, make sure to manually order the frames first.

Bendemann
  • 642
  • 12
  • 24