สร้างวิดีโอหรือ GIF แบบเคลื่อนไหวโดยทางโปรแกรมใน Python หรือไม่


221

ฉันมีชุดรูปภาพที่ฉันต้องการสร้างวิดีโอ โดยหลักการแล้วฉันสามารถระบุระยะเวลาของเฟรมสำหรับแต่ละเฟรมได้ แต่อัตราเฟรมคงที่ก็ดีเช่นกัน ฉันกำลังทำสิ่งนี้ใน wxPython ดังนั้นฉันจึงสามารถแสดงผลเป็น wxDC หรือสามารถบันทึกรูปภาพเป็นไฟล์เช่น PNG มีห้องสมุดไพ ธ อนที่จะอนุญาตให้ฉันสร้างวิดีโอ (AVI, MPG, ฯลฯ ) หรือภาพเคลื่อนไหว GIF จากเฟรมเหล่านี้หรือไม่?

แก้ไข: ฉันได้ลอง PIL แล้วและดูเหมือนจะไม่ทำงาน ใครสามารถแก้ไขฉันด้วยข้อสรุปนี้หรือแนะนำชุดเครื่องมืออื่นได้หรือไม่ ลิงก์นี้ดูเหมือนจะสำรองข้อสรุปของฉันเกี่ยวกับ PIL: http://www.somethinkodd.com/oddthinking/2005/12/06/python-imaging-library-pil-and-animated-gifs/

คำตอบ:


281

ฉันไม่แนะนำให้ใช้ images2gif จาก visvis เพราะมันมีปัญหากับ PIL / หมอนและไม่ได้รับการบำรุงรักษา (ฉันควรรู้เพราะฉันเป็นผู้เขียน)

โปรดใช้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)

37
length = 0.5 กำหนดช่วงเวลา 0.5 วินาทีสำหรับแต่ละเฟรม
Alleo

3
ValueError: ไม่พบรูปแบบการอ่านไฟล์ที่ระบุในโหมด 'i' - ฉันได้รับข้อผิดพลาดนี้ใน windows 2.7 winpython เบาะแสใด ๆ
Vanko

1
@Vanko ข้อผิดพลาดน่าจะเกี่ยวข้องกับการอ่านไฟล์คุณสามารถลอง imagio.mimread หรือถ้าเป็นภาพยนตร์ที่มีหลายเฟรมให้ใช้วัตถุผู้อ่านเช่นที่นี่: imageio.readthedocs.io/th/latest/ ......
Almar

2
@Alleo: "also parameter duration = 0.5 กำหนดระยะเวลา 0.5 วินาทีสำหรับแต่ละเฟรม" มีคุณสมบัติระยะเวลาสำหรับ imageio หรือไม่ ถ้ามีเอกสารนี้อยู่ที่ไหน ฉันอ่านเอกสารทั้งหมดและไม่สามารถหาข้อโต้แย้งเกี่ยวกับช่วงเวลาได้
Chris Nielsen

3
ยอดเยี่ยม imageio in anacondaอัตราผลตอบแทนTrueyay!
uhoh

47

ตอนนี้ฉันกำลังใช้ ImageMagick อยู่ ฉันบันทึกเฟรมเป็นไฟล์ PNG จากนั้นเรียกใช้ convert.exe ของ ImageMagick จาก Python เพื่อสร้าง GIF แบบเคลื่อนไหว สิ่งที่ดีเกี่ยวกับวิธีนี้คือฉันสามารถระบุระยะเวลาของเฟรมสำหรับแต่ละเฟรมเป็นรายบุคคล น่าเสียดายที่นี่ขึ้นอยู่กับ ImageMagick ที่ติดตั้งในเครื่อง พวกเขามีแผ่นปิด Python แต่มันดูเส็งเคร็งและไม่ได้รับการสนับสนุน ยังคงเปิดให้คำแนะนำอื่น ๆ


21
ฉันเป็นผู้ชาย Python แต่พบว่า ImageMagick ง่ายกว่ามากที่นี่ ฉันเพิ่งสร้างลำดับของภาพและวิ่งไปเรื่อย ๆconvert -delay 20 -loop 0 *jpg animated.gif
นิค

ฉันเห็นด้วยนี่เป็นทางออกที่ดีที่สุดที่ฉันเคยเจอ นี่คือตัวอย่างเล็กน้อย (ขึ้นอยู่กับรหัสตัวอย่างของ Steve B ผู้ใช้ที่โพสต์ที่stackoverflow.com/questions/10922285/ … ): pastebin.com/JJ6ZuXdz
andreasdr

เมื่อใช้ ImageMagick คุณสามารถปรับขนาด gif แบบเคลื่อนไหวได้อย่างง่ายดายเช่นconvert -delay 20 -resize 300x200 -loop 0 *jpg animated.gif
Jun Wang

@Nick คุณจะเรียกใช้รหัสนั้นเพื่อสร้าง GIF ได้อย่างไร ฉันควรนำเข้าทุกสิ่งใน Spyder IDE หรือไม่
ดวงจันทร์

@MOON คำสั่ง ImageMagic ที่ฉันเพิ่มไว้ด้านบนเป็นเพียงเรียกใช้ผ่านบรรทัดคำสั่ง
Nick

43

ณ เดือนมิถุนายน 2009 บล็อกโพสต์อ้างเดิมมีวิธีการที่จะสร้างภาพเคลื่อนไหว 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)

2
มีเวอร์ชันใหม่ของสคริปต์นี้ที่ให้ผลผลิตคุณภาพดีกว่ามากที่visvis.googlecode.com/hg/vvmovie/images2gif.pyมันสามารถใช้เป็นสคริปต์แบบสแตนด์อโลนแยกต่างหากจากแพ็คเกจ
geographika

1
สคริปต์ที่กล่าวถึงในความคิดเห็นนี้จะให้ข้อผิดพลาดในการแบ่งส่วนสำหรับฉันเมื่อใช้กับ Mac แม้เพียงแค่เรียกใช้ (ใช้ตัวอย่างชื่อ __ == '__ main ') ฉันลองใช้สคริปต์ที่กล่าวถึงในคำตอบหวังว่ามันจะทำงานได้อย่างถูกต้อง แก้ไข - ฉันสามารถยืนยันได้ว่าสคริปต์ที่อ้างถึงในคำตอบข้างต้นทำงานได้อย่างถูกต้องบน Mac ของฉัน
scubbo

6
มากกว่าเพียงแค่ดาวน์โหลดใช้งานสคริปต์ pip เช่นนั้นในสคริปต์ของคุณpip install visvis from visvis.vvmovie.images2gif import writeGif
Daniel Farrell

8
ฉันลองสิ่งนี้กับ Python 2.7.3 บน windows 8 และฉันได้รับ UnicodeDecodeError: ตัวแปลงสัญญาณ 'ascii' ไม่สามารถถอดรหัสไบต์ 0xc8 ในตำแหน่งที่ 6: ลำดับไม่อยู่ในช่วง (128) จากการรัน python images2gif.py
reckoner

3
ฉันเป็นผู้เขียน visivis (และ images2gif) และแนะนำให้ใช้เพื่อจุดประสงค์นี้ ฉันทำงานเกี่ยวกับวิธีแก้ปัญหาที่ดีกว่าซึ่งเป็นส่วนหนึ่งของโครงการ imageio (ดูคำตอบของฉัน)
Almar

40

นี่คือวิธีที่คุณใช้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)

4
นี่ควรเป็นคำตอบที่ได้รับการยอมรับขอบคุณ @Kris
ted930511

1
ตัวแปรเครื่องหมายดอกจันถือเป็นอะไร ("* imgs")
denisb411

3
นั่นเป็นคุณสมบัติของภาษาไพ ธ อน มันจะเปิดออก iterable คุณสามารถประมาณคิดว่ามันเป็นเอาออกx = [a, b, c]ไป*xซึ่งสามารถจะคิดว่าเป็นa, b, c(โดยไม่ต้องวงเล็บล้อมรอบ) ในการเรียกใช้ฟังก์ชันเหล่านี้มีความหมายเหมือนกัน: f(*x) == f(a, b, c). ในการเปิดตัว tuple จะมีประโยชน์อย่างยิ่งในกรณีที่คุณต้องการแยกการวนเป็นส่วนหัว (องค์ประกอบแรก) และส่วนท้าย (ส่วนที่เหลือ) ซึ่งเป็นสิ่งที่ฉันทำในตัวอย่างนี้
กริช

25

ฉันใช้images2gif.pyซึ่งใช้งานง่าย ดูเหมือนว่าจะเพิ่มขนาดไฟล์เป็นสองเท่า ..

26 ไฟล์ PNG ขนาด 110kb ฉันคาดว่า 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

นี่คือ 3 จาก 26 เฟรม:

นี่คือ 3 จาก 26 เฟรม

การหดขนาดรูปภาพลดขนาด:

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

gif ขนาดเล็ก


ฉันโพสต์บล็อกเกี่ยวกับสิ่งนี้ .. robert-king.com/#post2-python-makes-gif
robert king

2
ฉันได้รับข้อผิดพลาด .. ไฟล์ "C: \ Python27 \ lib \ images2gif.py", บรรทัด 418, ใน writeGifToFile globalPalette = palettes [เกิดขึ้น .index (สูงสุด (เกิดขึ้น))] ValueError: max () หาเรื่องเป็นลำดับว่าง
แฮร์รี่

เกิดขึ้นอาจว่างเปล่า ไฟล์ images2gif.py ของฉันไม่มีตัวแปร "globalPalette"
เบิร์

ฉันจะเปลี่ยนสิ่งนั้นได้อย่างไร ฉันใช้สคริปต์ images2gif.py ล่าสุดอยู่ที่นั่น ( bit.ly/XMMn5h )
แฮร์รี่

4
@robertking ด้วยรหัสผมได้รับข้อผิดพลาดว่าfp.write(globalPalette) TypeError: must be string or buffer, not list
LWZ

19

ในการสร้างวิดีโอคุณสามารถใช้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])

9

ฉันเจอโพสต์นี้และไม่มีวิธีแก้ปัญหาที่ได้ผลดังนั้นนี่คือโซลูชันของฉันที่ใช้งานได้

ปัญหาเกี่ยวกับวิธีแก้ไขปัญหาอื่น ๆ :
1)ไม่มีวิธีแก้ไขที่ชัดเจนเกี่ยวกับวิธีการแก้ไขระยะเวลา
2)ไม่มีวิธีแก้ปัญหาสำหรับการวนซ้ำไดเรกทอรีที่ไม่อยู่ในลำดับซึ่งจำเป็นสำหรับ GIFs
3)ไม่มีคำอธิบายวิธีติดตั้ง imageio สำหรับ python 3

ติดตั้ง imageio แบบนี้: python3 -m pip ติดตั้ง 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

1
sortอาจให้ผลลัพธ์ที่ไม่คาดคิดหากรูปแบบการกำหนดหมายเลขของคุณไม่รวมศูนย์นำหน้า ทำไมคุณถึงใช้แผนที่แทนความเข้าใจในรายการอย่างง่าย?
NOhs

ฉันขอแนะนำให้ทำfilenames.append(os.path.join(path, filename))
จริง

Secodning Nohs images = [imageio.imread(f) for f in filenames]นั้นสะอาดขึ้นเร็วขึ้นและไพเราะมากขึ้น
แบรนดอน Dube

6

เช่นเดียวกับวอร์เรนที่พูดเมื่อปีที่แล้วนี่เป็นคำถามเก่า เนื่องจากผู้คนยังคงดูหน้าเว็บอยู่ฉันต้องการเปลี่ยนเส้นทางไปยังโซลูชันที่ทันสมัยกว่า เช่นเดียวกับ blakev กล่าวว่าที่นี่มีเป็นตัวอย่างที่หมอนบนGitHub

 import ImageSequence
 import Image
 import gifmaker
 sequence = []

 im = Image.open(....)

 # im is your original image
 frames = [frame.copy() for frame in ImageSequence.Iterator(im)]

 # write GIF animation
 fp = open("out.gif", "wb")
 gifmaker.makedelta(fp, frames)
 fp.close()

หมายเหตุ: ตัวอย่างนี้ล้าสมัย ( gifmakerไม่ใช่โมดูลที่สามารถอิมพอร์ตได้เพียงสคริปต์) หมอนมีGifImagePlugin (แหล่งที่มาอยู่บน GitHub ) แต่doc บน ImageSequenceดูเหมือนจะบ่งบอกถึงการสนับสนุนที่ จำกัด (อ่านอย่างเดียว)


5

มันไม่ได้เป็นห้องสมุดหลาม แต่ mencoder สามารถทำเช่นนั้น: การเข้ารหัสจากไฟล์ภาพที่นำเข้าหลาย คุณสามารถรัน mencoder จากไพ ธ อนเช่นนี้:

import os

os.system("mencoder ...")

5

คำถามเก่า ๆ คำตอบที่ดีมากมาย แต่อาจมีทางเลือกอื่น ...

numpngwโมดูลที่ฉันเพิ่งวางบน GitHub ( https://github.com/WarrenWeckesser/numpngw ) สามารถเขียน PNG ไฟล์ภาพเคลื่อนไหวจากอาร์เรย์ numpy ( อัปเดต : numpngwตอนนี้ใช้งาน pypi: https://pypi.python.org/pypi/numpngw .)

ตัวอย่างเช่นสคริปต์นี้:

import numpy as np
import numpngw


img0 = np.zeros((64, 64, 3), dtype=np.uint8)
img0[:32, :32, :] = 255
img1 = np.zeros((64, 64, 3), dtype=np.uint8)
img1[32:, :32, 0] = 255
img2 = np.zeros((64, 64, 3), dtype=np.uint8)
img2[32:, 32:, 1] = 255
img3 = np.zeros((64, 64, 3), dtype=np.uint8)
img3[:32, 32:, 2] = 255
seq = [img0, img1, img2, img3]
for img in seq:
    img[16:-16, 16:-16] = 127
    img[0, :] = 127
    img[-1, :] = 127
    img[:, 0] = 127
    img[:, -1] = 127

numpngw.write_apng('foo.png', seq, delay=250, use_palette=True)

สร้าง:

png แบบเคลื่อนไหว

คุณจะต้องมีเบราว์เซอร์ที่รองรับ PNG แบบเคลื่อนไหว (ไม่ว่าโดยตรงหรือกับปลั๊กอิน) เพื่อดูภาพเคลื่อนไหว


Chrome ตอนนี้ก็ทำเช่นนั้น BTW คำถามหนึ่งข้อ - สามารถเป็นคำถามซ้ำได้หรือไม่ คุณสนับสนุน "การสตรีม" (เช่นเปิด APNG เป้าหมายและเพิ่มเฟรมทีละหนึ่งในลูป) หรือไม่
Tomasz Gandor

ไม่รองรับการทำซ้ำหรือการสตรีมโดยพลการ แต่ไม่ได้หมายความว่าไม่สามารถทำได้ในอนาคต :) สร้างปัญหาในหน้า githubด้วยการปรับปรุงที่เสนอ หากคุณมีแนวคิดใด ๆ เกี่ยวกับ API สำหรับคุณลักษณะนี้โปรดอธิบายเกี่ยวกับปัญหานี้
Warren Weckesser

ฉันมีข้อผิดพลาดแปลก ๆ ซึ่งฉันทำปัญหากับ repo ของคุณ
mLstudent33

5

ในฐานะที่เป็นหนึ่งในสมาชิกที่กล่าวถึงข้างต้น imageio เป็นวิธีที่ดีในการทำเช่นนี้ imageio ยังช่วยให้คุณกำหนดอัตราเฟรมและที่จริงฉันเขียนฟังก์ชั่นใน Python ที่อนุญาตให้คุณตั้งค่าไว้ที่เฟรมสุดท้าย ฉันใช้ฟังก์ชั่นนี้สำหรับแอนิเมชั่นเชิงวิทยาศาสตร์ที่การวนซ้ำนั้นมีประโยชน์ แต่การรีสตาร์ททันทีไม่ได้ นี่คือลิงค์และฟังก์ชั่น:

วิธีสร้าง GIF ด้วย Python

import matplotlib.pyplot as plt
import os
import imageio

def gif_maker(gif_name,png_dir,gif_indx,num_gifs,dpi=90):
    # make png path if it doesn't exist already
    if not os.path.exists(png_dir):
        os.makedirs(png_dir)

    # save each .png for GIF
    # lower dpi gives a smaller, grainier GIF; higher dpi gives larger, clearer GIF
    plt.savefig(png_dir+'frame_'+str(gif_indx)+'_.png',dpi=dpi)
    plt.close('all') # comment this out if you're just updating the x,y data

    if gif_indx==num_gifs-1:
        # sort the .png files based on index used above
        images,image_file_names = [],[]
        for file_name in os.listdir(png_dir):
            if file_name.endswith('.png'):
                image_file_names.append(file_name)       
        sorted_files = sorted(image_file_names, key=lambda y: int(y.split('_')[1]))

        # define some GIF parameters

        frame_length = 0.5 # seconds between frames
        end_pause = 4 # seconds to stay on last frame
        # loop through files, join them to image array, and write to GIF called 'wind_turbine_dist.gif'
        for ii in range(0,len(sorted_files)):       
            file_path = os.path.join(png_dir, sorted_files[ii])
            if ii==len(sorted_files)-1:
                for jj in range(0,int(end_pause/frame_length)):
                    images.append(imageio.imread(file_path))
            else:
                images.append(imageio.imread(file_path))
        # the duration is the time spent on each image (1/duration is frame rate)
        imageio.mimsave(gif_name, images,'GIF',duration=frame_length)

ตัวอย่าง GIF ที่ใช้วิธีนี้



4

ด้วย windows7, python2.7, opencv 3.0 สิ่งต่อไปนี้เหมาะสำหรับฉัน:

import cv2
import os

vvw           =   cv2.VideoWriter('mymovie.avi',cv2.VideoWriter_fourcc('X','V','I','D'),24,(640,480))
frameslist    =   os.listdir('.\\frames')
howmanyframes =   len(frameslist)
print('Frames count: '+str(howmanyframes)) #just for debugging

for i in range(0,howmanyframes):
    print(i)
    theframe = cv2.imread('.\\frames\\'+frameslist[i])
    vvw.write(theframe)

3

สิ่งที่ง่ายที่สุดที่ทำให้ฉันทำงานได้คือการเรียกคำสั่ง shell ใน Python

หากรูปภาพของคุณถูกจัดเก็บเช่น dummy_image_1.png, dummy_image_2.png ... dummy_image_N.png คุณสามารถใช้ฟังก์ชั่นนี้ได้:

import subprocess
def grid2gif(image_str, output_gif):
    str1 = 'convert -delay 100 -loop 1 ' + image_str  + ' ' + output_gif
    subprocess.call(str1, shell=True)

เพิ่งดำเนินการ:

grid2gif("dummy_image*.png", "my_output.gif")

สิ่งนี้จะสร้างไฟล์ gif ของคุณ my_output.gif


2

ภารกิจสามารถทำให้เสร็จได้โดยการรันสคริปต์ python สองบรรทัดจากโฟลเดอร์เดียวกันกับลำดับของไฟล์รูปภาพ สำหรับไฟล์ที่จัดรูปแบบ png สคริปต์คือ -

from scitools.std import movie
movie('*.png',fps=1,output_file='thisismygif.gif')

1
พยายาม ... ไม่ได้ผลสำหรับฉันภายใต้ Python 2.6 ส่งคืน: "ฟังก์ชัน scitools.easyviz.movie รันคำสั่ง: / convert -delay 100 g4testC _ *. png g4testC.gif / พารามิเตอร์ไม่ถูกต้อง - 100"
Dan H

ปัญหาไม่ได้อยู่กับ Python อย่างแน่นอน ติดตั้ง imagemagick บนระบบของคุณอีกครั้งและลองอีกครั้ง
ArKE

2

ฉันกำลังมองหารหัสบรรทัดเดียวและพบว่าสิ่งต่อไปนี้สามารถใช้ได้กับแอปพลิเคชันของฉัน นี่คือสิ่งที่ฉันทำ:

ขั้นตอนแรก: ติดตั้ง ImageMagick จากลิงค์ด้านล่าง

https://www.imagemagick.org/script/download.php

ป้อนคำอธิบายรูปภาพที่นี่

ขั้นตอนที่สอง: ชี้บรรทัด cmd ไปยังโฟลเดอร์ที่วางรูปภาพ (ในรูปแบบ. png ในกรณีของฉัน)

ป้อนคำอธิบายรูปภาพที่นี่

ขั้นตอนที่สาม: พิมพ์คำสั่งต่อไปนี้

magick -quality 100 *.png outvideo.mpeg

ป้อนคำอธิบายรูปภาพที่นี่

ขอบคุณ FogleBird สำหรับความคิด!


0

ฉันลองต่อไปนี้และมีประโยชน์มาก:

ก่อนดาวน์โหลดห้องสมุดFigtodatและimages2gifไดเรกทอรีท้องถิ่นของคุณ

รวบรวมตัวเลขในอาร์เรย์และแปลงเป็น gif แบบเคลื่อนไหว:

import sys
sys.path.insert(0,"/path/to/your/local/directory")
import Figtodat
from images2gif import writeGif
import matplotlib.pyplot as plt
import numpy

figure = plt.figure()
plot   = figure.add_subplot (111)

plot.hold(False)
    # draw a cardinal sine plot
images=[]
y = numpy.random.randn(100,5)
for i in range(y.shape[1]):
    plot.plot (numpy.sin(y[:,i]))  
    plot.set_ylim(-3.0,3)
    plot.text(90,-2.5,str(i))
    im = Figtodat.fig2img(figure)
    images.append(im)

writeGif("images.gif",images,duration=0.3,dither=0)

0

ฉันเข้ามาในโมดูลImageSequenceของ PIL ซึ่งมีข้อเสนอ GIF ที่ดีกว่า (และมาตรฐานมากกว่า) ฉันยังใช้ Tk ของหลัง ()วิธีการในเวลานี้ซึ่งดีกว่าtime.sleep ()

from Tkinter import * 
from PIL import Image, ImageTk, ImageSequence

def stop(event):
  global play
  play = False
  exit() 

root = Tk()
root.bind("<Key>", stop) # Press any key to stop
GIFfile = {path_to_your_GIF_file}
im = Image.open(GIFfile); img = ImageTk.PhotoImage(im)
delay = im.info['duration'] # Delay used in the GIF file 
lbl = Label(image=img); lbl.pack() # Create a label where to display images
play = True;
while play:
  for frame in ImageSequence.Iterator(im):
    if not play: break 
    root.after(delay);
    img = ImageTk.PhotoImage(frame)
    lbl.config(image=img); root.update() # Show the new frame/image

root.mainloop()

0

ฟังก์ชั่นง่าย ๆ ที่ทำให้ GIF:

import imageio
import pathlib
from datetime import datetime


def make_gif(image_directory: pathlib.Path, frames_per_second: float, **kwargs):
    """
    Makes a .gif which shows many images at a given frame rate.
    All images should be in order (don't know how this works) in the image directory

    Only tested with .png images but may work with others.

    :param image_directory:
    :type image_directory: pathlib.Path
    :param frames_per_second:
    :type frames_per_second: float
    :param kwargs: image_type='png' or other
    :return: nothing
    """
    assert isinstance(image_directory, pathlib.Path), "input must be a pathlib object"
    image_type = kwargs.get('type', 'png')

    timestampStr = datetime.now().strftime("%y%m%d_%H%M%S")
    gif_dir = image_directory.joinpath(timestampStr + "_GIF.gif")

    print('Started making GIF')
    print('Please wait... ')

    images = []
    for file_name in image_directory.glob('*.' + image_type):
        images.append(imageio.imread(image_directory.joinpath(file_name)))
    imageio.mimsave(gif_dir.as_posix(), images, fps=frames_per_second)

    print('Finished making GIF!')
    print('GIF can be found at: ' + gif_dir.as_posix())


def main():
    fps = 2
    png_dir = pathlib.Path('C:/temp/my_images')
    make_gif(png_dir, fps)

if __name__ == "__main__":
    main()

0

ฉันเข้าใจว่าคุณถามเกี่ยวกับการแปลงภาพเป็น gif อย่างไรก็ตามหากรูปแบบดั้งเดิมเป็น MP4 คุณสามารถใช้FFmpeg :

ffmpeg -i input.mp4 output.gif

-1

มันเหลือเชื่อจริงๆ ... ทุกคนกำลังเสนอแพ็คเกจพิเศษสำหรับเล่น GIF แบบเคลื่อนไหวในขณะนี้ที่สามารถทำได้ด้วย Tkinter และโมดูล PIL สุดคลาสสิค!

นี่คือวิธีการเคลื่อนไหว GIF ของฉันเอง (ฉันได้สร้างมานานแล้ว) ง่ายมาก:

from Tkinter import * 
from PIL import Image, ImageTk
from time import sleep

def stop(event):
  global play
  play = False
  exit() 

root = Tk()
root.bind("<Key>", stop) # Press any key to stop
GIFfile = {path_to_your_GIF_file}    
im = Image.open(GIFfile); img = ImageTk.PhotoImage(im)
delay = float(im.info['duration'])/1000; # Delay used in the GIF file 
lbl = Label(image=img); lbl.pack() # Create a label where to display images
play = True; frame = 0
while play:
  sleep(delay);
  frame += 1
  try:
    im.seek(frame); img = ImageTk.PhotoImage(im)
    lbl.config(image=img); root.update() # Show the new frame/image
  except EOFError:
    frame = 0 # Restart

root.mainloop()

คุณสามารถตั้งค่าวิธีการของคุณเองเพื่อหยุดภาพเคลื่อนไหว แจ้งให้เราทราบหากคุณต้องการรับเวอร์ชันเต็มด้วยปุ่มเล่น / หยุด / เลิก

หมายเหตุ: ฉันไม่แน่ใจว่าเฟรมที่ต่อเนื่องนั้นถูกอ่านจากหน่วยความจำหรือจากไฟล์ (ดิสก์) ในกรณีที่สองมันจะมีประสิทธิภาพมากขึ้นถ้าพวกเขาทั้งหมดอ่านพร้อมกันและบันทึกลงในอาร์เรย์ (รายการ) (ฉันไม่ค่อยสนใจที่จะทราบ! :)


1
โดยทั่วไปแล้วจะไม่เหมาะอย่างยิ่งที่จะโทรsleepในเธรดหลักของ GUI คุณสามารถใช้afterวิธีนี้เพื่อเรียกใช้ฟังก์ชันเป็นระยะ
ไบรอัน Oakley

คุณพูดถูก แต่นี่ไม่ใช่ประเด็นเลยใช่ไหม จุดคือวิธีการทั้งหมด ดังนั้นฉันคาดหวังว่าจะตอบสนองต่อสิ่งนั้น!
Apostolos

1
ฉันแค่พยายามให้คำแนะนำเกี่ยวกับวิธีการปรับปรุงคำตอบของคุณ
ไบรอัน Oakley

BTW ฉันปกติใช้tk.after()ตัวเอง แต่ที่นี่ฉันต้องทำให้รหัสง่ายที่สุดเท่าที่จะทำได้ ใครก็ตามที่ใช้วิธีภาพเคลื่อนไหว GIF นี้สามารถใช้ฟังก์ชั่นการหน่วงเวลาของตัวเองได้
Apostolos

ในที่สุด! ใช่นี่เป็นจุดที่ดีมาก ฉันอยู่นอกหัวข้อ! ขอบคุณ @Novel (สนใจที่จะดูว่าคนอื่นพลาดเรื่องนี้อย่างไรเช่นไบรอันซึ่งกำลังพูดถึงวิธีการหน่วงเวลา!)
Apostolos
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.