[python] 파이썬에서 프로그래밍 방식으로 비디오 또는 애니메이션 GIF를 생성합니까?

비디오를 만들려는 일련의 이미지가 있습니다. 이상적으로는 각 프레임의 프레임 지속 시간을 지정할 수 있지만 고정 프레임 속도도 좋습니다. wxPython 에서이 작업을 수행하므로 wxDC로 렌더링하거나 PNG와 같은 파일에 이미지를 저장할 수 있습니다. 이 프레임에서 비디오 (AVI, MPG 등) 또는 애니메이션 GIF를 만들 수있는 Python 라이브러리가 있습니까?

편집 : 이미 PIL을 시도했지만 작동하지 않는 것 같습니다. 누군가이 결론으로 ​​나를 교정하거나 다른 툴킷을 제안 할 수 있습니까? 이 링크는 PIL에 관한 나의 결론을 뒷받침하는 것 같습니다 : http://www.somethinkodd.com/oddthinking/2005/12/06/python-imaging-library-pil-and-animated-gifs/



답변

visvis의 images2gif를 사용하지 않는 것이 좋습니다 .PIL / Pillow에 문제가 있고 적극적으로 유지 관리되지 않기 때문입니다 (저는 저자이기 때문에 알아야합니다).

대신 이 문제 등을 해결하기 위해 개발 된 imageio 를 사용하십시오 .

빠르고 더러운 솔루션 :

import imageio
images = []
for filename in filenames:
    images.append(imageio.imread(filename))
imageio.mimsave('/path/to/movie.gif', images)

더 긴 영화의 경우 스트리밍 방식을 사용하십시오.

import imageio
with imageio.get_writer('/path/to/movie.gif', mode='I') as writer:
    for filename in filenames:
        image = imageio.imread(filename)
        writer.append_data(image)


답변

글쎄, 이제 ImageMagick을 사용하고 있습니다. 프레임을 PNG 파일로 저장 한 다음 Python에서 ImageMagick의 convert.exe를 호출하여 애니메이션 GIF를 만듭니다. 이 방법의 좋은 점은 각 프레임의 프레임 지속 시간을 개별적으로 지정할 수 있다는 것입니다. 불행히도 이것은 컴퓨터에 설치된 ImageMagick에 따라 다릅니다. 그들은 파이썬 래퍼를 가지고 있지만 꽤 엉뚱하고 지원되지 않는 것 같습니다. 다른 제안에 여전히 열려 있습니다.


답변

2009 년 6 월 기준으로 원래 인용 된 블로그 게시물에는 댓글에 애니메이션 GIF를 만드는 방법이 있습니다 . images2gif.py 스크립트를 다운로드하십시오 (이전 images2gif.py , @geographika 제공 업데이트).

그런 다음 gif에서 프레임을 반전 시키려면

#!/usr/bin/env python

from PIL import Image, ImageSequence
import sys, os
filename = sys.argv[1]
im = Image.open(filename)
original_duration = im.info['duration']
frames = [frame.copy() for frame in ImageSequence.Iterator(im)]    
frames.reverse()

from images2gif import writeGif
writeGif("reverse_" + os.path.basename(filename), frames, duration=original_duration/1000.0, dither=0)


답변

PIL 만 사용하여 수행하는 방법은 다음 과 같습니다 ( pip install Pillow) :

import glob
from PIL import Image

# filepaths
fp_in = "/path/to/image_*.png"
fp_out = "/path/to/image.gif"

# https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#gif
img, *imgs = [Image.open(f) for f in sorted(glob.glob(fp_in))]
img.save(fp=fp_out, format='GIF', append_images=imgs,
         save_all=True, duration=200, loop=0)


답변

사용 하기 쉬운 images2gif.py 를 사용했습니다. 그래도 파일 크기가 두 배가 된 것 같습니다 ..

26110kb PNG 파일, 26 * 110kb = 2860kb를 예상했지만 my_gif.GIF는 5.7mb였습니다.

또한 GIF는 8 비트 였기 때문에 멋진 PNG는 GIF에서 약간 희미 해졌습니다.

내가 사용한 코드는 다음과 같습니다.

__author__ = 'Robert'
from images2gif import writeGif
from PIL import Image
import os

file_names = sorted((fn for fn in os.listdir('.') if fn.endswith('.png')))
#['animationframa.png', 'animationframb.png', 'animationframc.png', ...] "

images = [Image.open(fn) for fn in file_names]

print writeGif.__doc__
# writeGif(filename, images, duration=0.1, loops=0, dither=1)
#    Write an animated gif from the specified images.
#    images should be a list of numpy arrays of PIL images.
#    Numpy images of type float should have pixels between 0 and 1.
#    Numpy images of other types are expected to have values between 0 and 255.


#images.extend(reversed(images)) #infinit loop will go backwards and forwards.

filename = "my_gif.GIF"
writeGif(filename, images, duration=0.2)
#54 frames written
#
#Process finished with exit code 0

26 개 프레임 중 3 개는 다음과 같습니다.

26 개의 프레임 중 3 개가 있습니다

이미지를 축소하면 크기가 줄어 듭니다.

size = (150,150)
for im in images:
    im.thumbnail(size, Image.ANTIALIAS)

작은 gif


답변

비디오를 만들려면 opencv를 사용 하면됩니다.

#load your frames
frames = ...
#create a video writer
writer = cvCreateVideoWriter(filename, -1, fps, frame_size, is_color=1)
#and write your frames in a loop if you want
cvWriteFrame(writer, frames[i])


답변

이 게시물을 보았는데 해결책이 없었으므로 여기에 효과가있는 솔루션이 있습니다.

지금까지 다른 솔루션의 문제 :
1) 지속 시간이 수정되는 방법에 대한 명확한 해결책이 없습니다
.2) GIF에 필수적인 비 순차적 디렉토리 반복에 대한 해결책이 없습니다
.3) 파이썬의 이미지를 설치하는 방법에 대한 설명이 없습니다.

다음과 같이 imageio를 설치하십시오 : python3 -m pip install imageio

참고 : 프레임의 파일 이름에 색인이 정렬되어 정렬 될 수 있는지 확인해야합니다. 그렇지 않으면 GIF가 시작하거나 끝나는 위치를 알 수 없습니다.

import imageio
import os

path = '/Users/myusername/Desktop/Pics/' # on Mac: right click on a folder, hold down option, and click "copy as pathname"

image_folder = os.fsencode(path)

filenames = []

for file in os.listdir(image_folder):
    filename = os.fsdecode(file)
    if filename.endswith( ('.jpeg', '.png', '.gif') ):
        filenames.append(filename)

filenames.sort() # this iteration technique has no built in order, so sort the frames

images = list(map(lambda filename: imageio.imread(filename), filenames))

imageio.mimsave(os.path.join('movie.gif'), images, duration = 0.04) # modify duration as needed