पायथन में वीडियो या एनिमेटेड जीआईएफ को प्रोग्राम करें?


221

मेरे पास छवियों की एक श्रृंखला है, जिनसे मैं एक वीडियो बनाना चाहता हूं। आदर्श रूप से मैं प्रत्येक फ्रेम के लिए एक फ्रेम अवधि निर्दिष्ट कर सकता था लेकिन एक निश्चित फ्रेम दर भी ठीक होगी। मैं यह wxPython में कर रहा हूं, इसलिए मैं एक wxDC को रेंडर कर सकता हूं या मैं पीएनजी की तरह फाइलों को सेव कर सकता हूं। क्या कोई पायथन लाइब्रेरी है जो मुझे इन फ़्रेमों से वीडियो (AVI, MPG, आदि) या एनिमेटेड GIF बनाने की अनुमति देगा?

संपादित करें: मैंने पहले ही पीआईएल की कोशिश की है और यह काम नहीं करता है। क्या कोई मुझे इस निष्कर्ष के साथ सही कर सकता है या किसी अन्य टूलकिट का सुझाव दे सकता है? यह लिंक पीआईएल के बारे में मेरे निष्कर्ष का बैकअप लेती है: http://www.somethinkodd.com/oddthinking/2005/12/06/python-imaging-library-pil-and-animated-gifs/

जवाबों:


281

मैं विज़्विस से images2gif का उपयोग नहीं करने की सलाह दूंगा क्योंकि इसमें PIL / तकिया की समस्याएं हैं और इसे सक्रिय रूप से बनाए नहीं रखा गया है (मुझे पता होना चाहिए, क्योंकि मैं लेखक हूं)।

इसके बजाय, कृपया इमेजियो का उपयोग करें , जिसे इस समस्या और अधिक हल करने के लिए विकसित किया गया था, और रहने का इरादा है।

त्वरित और गंदा समाधान:

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
भी पैरामीटर अवधि = 0.5 प्रत्येक फ्रेम के लिए 0.5 सेकंड की अवधि निर्धारित करता है।
एलो

3
ValueError: निर्दिष्ट फ़ाइल को 'i' में पढ़ने के लिए एक प्रारूप नहीं मिल सका - मुझे यह त्रुटि विंडोज़ 2.7 winpython पर मिल रही है। कोई सुराग?
वैंकू

1
@Vanko त्रुटि फ़ाइल के पठन से संबंधित प्रतीत होती है, आप कल्पना की कोशिश कर सकते हैं। यदि इसकी कई फ्रेम वाली मूवी है, तो पाठक ऑब्जेक्ट का उपयोग यहां करें: imageio.readthedocs.io/en/latest ……
Almar

2
@ एलेओ: "भी पैरामीटर अवधि = 0.5 प्रत्येक फ्रेम के लिए 0.5 सेकंड की अवधि निर्धारित करता है"। Imageio के लिए एक अवधि सुविधा है? यदि हां, तो यह दस्तावेज कहां है? मैंने सभी डॉक्स पढ़े और अवधि तर्क का कोई उल्लेख नहीं पाया।
क्रिस नील्सन

3
अति उत्कृष्ट! imageio in anacondaपैदावार True, याय!
उहोह

47

खैर, अब मैं ImageMagick का उपयोग कर रहा हूं। मैं अपने फ़्रेम को PNG फ़ाइलों के रूप में सहेजता हूं और फिर एक एनिमेटेड GIF बनाने के लिए ImageMagick के Convert.exe को Python से आमंत्रित करता हूं। इस दृष्टिकोण के बारे में अच्छी बात यह है कि मैं व्यक्तिगत रूप से प्रत्येक फ्रेम के लिए एक फ्रेम अवधि निर्दिष्ट कर सकता हूं। दुर्भाग्य से यह मशीन पर स्थापित ImageMagick पर निर्भर करता है। उनके पास पायथन रैपर है, लेकिन यह बहुत भद्दा और असमर्थित दिखता है। अभी भी अन्य सुझावों के लिए खुला है।


21
मैं एक अजगर लड़का हूं, लेकिन यहां ImageMagick बहुत आसान है। मैंने बस छवियों का अपना क्रम बनाया और कुछ इस तरह भाग गयाconvert -delay 20 -loop 0 *jpg animated.gif
निक

मैं सहमत हूं, यह सबसे अच्छा समाधान है जो मुझे आया है। यहाँ एक न्यूनतम उदाहरण है (उपयोगकर्ता स्टीव बी के उदाहरण कोड के आधार पर stackoverflow.com/questions/10922285/… ): pastebin.com/JJ6ZuXdz
andreasdr

ImageMagick का उपयोग करके, आप आसानी से एनिमेटेड जिफ़ का भी आकार बदल सकते हैं जैसेconvert -delay 20 -resize 300x200 -loop 0 *jpg animated.gif
Jun Wang

@ क्लिक करें, आप GIF बनाने के लिए उस कोड को कैसे चलाएंगे? क्या मुझे स्पाइडर आईडीई में कुछ भी आयात करना चाहिए?
मून

@MOON ImageMagic कमांड जो मैंने ऊपर जोड़ा है, बस कमांड लाइन के माध्यम से चलाया जाता है।
निक

43

जून 2009 तक मूल रूप से उद्धृत ब्लॉग पोस्ट में टिप्पणियों में एनिमेटेड जीआईएफ बनाने की एक विधि है । स्क्रिप्ट 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
इस टिप्पणी में उल्लिखित स्क्रिप्ट लगातार मैक पर उपयोग किए जाने पर मेरे लिए एक विभाजन दोष देती है, यहां तक ​​कि जब बस चलती है ( नाम __ == '__ मुख्य ' उदाहरण का उपयोग करके )। मैं उत्तर में वर्णित स्क्रिप्ट की कोशिश कर रहा हूं, उम्मीद है कि यह ठीक से काम करेगा। EDIT - मैं पुष्टि कर सकता हूं कि ऊपर दिए गए उत्तर में संदर्भित स्क्रिप्ट मेरे मैक पर सही ढंग से काम करती है।
स्क्रब

6
इसके बजाय सिर्फ स्क्रिप्ट का उपयोग करें जैसे कि पाइप का उपयोग करें pip install visvis, फिर अपनी स्क्रिप्ट में from visvis.vvmovie.images2gif import writeGif
डैनियल फैरेल

8
मैंने इसे विंडोज 8 पर पायथन 2.7.3 के साथ आजमाया और मुझे यूनिकोडडाउज़ररूट मिलता है: 'एससीआईआई' कोडक 0 बाइट 0xc8 को 6 की स्थिति में डिकोड नहीं कर सकता: ऑर्डिनल रेंज में नहीं (128)। अजगर छवियों को चलाने से 2gif.py
reckoner

3
मैं विज़िविस (और images2gif) का लेखक हूं और इस उद्देश्य के लिए इसका उपयोग करने के खिलाफ सलाह देता हूं। मैं इमेजियो प्रोजेक्ट के हिस्से के रूप में एक बेहतर समाधान पर काम कर रहा हूं (मेरा उत्तर देखें)।
अल्मार

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")?
डेनिसब 411 21

3
यह एक अजगर भाषा की विशेषता है। यह iterable अनपैकिंग करता है । आप मोटे तौर पर खोल के रूप में यह सोच सकते हैं x = [a, b, c]करने के लिए *xजो के रूप में सोचा जा सकता है a, b, c(संलग्न कोष्ठकों के बिना)। फ़ंक्शन कॉल में ये पर्यायवाची हैं f(*x) == f(a, b, c):। ट्यूपल अनपैकिंग में यह उन मामलों में विशेष रूप से उपयोगी है जहां आप एक चलने योग्य को एक सिर (पहला तत्व) और एक पूंछ (बाकी) में विभाजित करना चाहते हैं, जो कि मैं इस उदाहरण में करता हूं।
क्रिश

25

मैंने images2gif.py का उपयोग किया जो उपयोग करना आसान था। यह फ़ाइल का आकार दोगुना लगता है, हालांकि ..

26 110kb PNG फाइलें, मुझे 26 * 110kb = 2860kb की उम्मीद थी, लेकिन my_gif.GIF 5.7mb था

क्योंकि GIF 8bit था, अच्छा 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)

छोटा जिफ


मैंने इस बारे में एक ब्लॉग पोस्ट बनाया .. robert-king.com/#post2-python-makes-gif
robert

2
मैं त्रुटियों .. फ़ाइल "C: \ Python27 \ lib \ images2gif.py", लाइन 418, में writeGifToFile globalPalette = पट्टियाँ [occur.index (अधिकतम (होते हैं))] ValueError: अधिकतम () आर्ग एक खाली अनुक्रम है
हैरी

घटित शायद खाली है। मेरी images2gif.py फ़ाइल में कोई "GlobalPalette" चर नहीं है।
रोबर्ट राजा

मैं इसे कैसे बदल सकता हूँ? मैं सबसे हाल की छवियाँ 2gif.py स्क्रिप्ट का उपयोग कर रहा हूँ वहाँ ( bit.ly/XMMn5h )
हैरी 3

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) ऑर्डर डायरेक्टरी पुनरावृत्ति से बाहर के लिए कोई समाधान नहीं, जो कि GIF
3 के लिए आवश्यक है ) अजगर 3 के लिए इमेजियो कैसे स्थापित करें इसका कोई विवरण नहीं

इस तरह इमेजियो स्थापित करें: python3 -m pip स्थापित इमेजियो

नोट: आप यह सुनिश्चित करना चाहेंगे कि आपके फ़्रेम में फ़ाइल नाम में किसी प्रकार का अनुक्रमणिका हो ताकि उन्हें सॉर्ट किया जा सके, अन्यथा आपके पास यह जानने का कोई तरीका नहीं होगा कि 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यदि आपकी नंबरिंग योजना में अग्रणी शून्य शामिल नहीं हैं, तो अप्रत्याशित परिणाम मिल सकते हैं। आपने साधारण सूची समझ के बजाय मानचित्र का उपयोग क्यों किया?
नं

मैं करने की सलाह देता हूंfilenames.append(os.path.join(path, filename))
trueter

सिकोडिंग नोह, images = [imageio.imread(f) for f in filenames]क्लीनर, तेज, और अधिक पायथोनिक है।
ब्रैंडन दुबे

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 पर है ), लेकिन ImageSequence पर डॉक्टर को सीमित समर्थन (केवल पढ़ने के लिए) का संकेत लगता है



5

पुराना सवाल, बहुत सारे अच्छे जवाब, लेकिन एक अन्य विकल्प में अभी भी रुचि हो सकती है ...

numpngwमॉड्यूल है कि मैं हाल ही में GitHub (पर डाल https://github.com/WarrenWeckesser/numpngw ) NumPy सरणी से एनिमेटेड PNG फ़ाइलें लिख सकते हैं। ( अपडेट : 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 (सीधे या प्लगइन के साथ) का समर्थन करता है।


क्रोम अब, BTW भी ​​करता है। एक सवाल - क्या सीकर को इससे कोई नुकसान हो सकता है? क्या आप "स्ट्रीमिंग" (यानी लक्ष्य APNG खोलना, और एक लूप में एक-एक करके फ्रेम जोड़ना) का समर्थन करते हैं?
टॉमस गैंडर

यह एक मनमाना चलने या स्ट्रीमिंग का समर्थन नहीं करता है, लेकिन इसका मतलब यह नहीं है कि यह भविष्य में नहीं हो सकता है। :) प्रस्तावित वृद्धि के साथ जीथब पृष्ठ पर एक मुद्दा बनाएं । यदि आपके पास इस सुविधा के लिए एपीआई के बारे में कोई विचार है, तो कृपया उन्हें समस्या में वर्णित करें।
वॉरेन वीकेसर

मुझे कुछ अजीब त्रुटि हुई जो मैंने आपके रेपो पर एक मुद्दा बनाया।
mLstudent33

5

जैसा कि ऊपर उल्लेखित एक सदस्य है, इमेजियो ऐसा करने का एक शानदार तरीका है। इमेजियो आपको फ्रेम दर को सेट करने की भी अनुमति देता है, और मैंने वास्तव में पायथन में एक फ़ंक्शन लिखा है जो आपको अंतिम फ्रेम पर पकड़ स्थापित करने की अनुमति देता है। मैं इस फ़ंक्शन का उपयोग वैज्ञानिक एनिमेशन के लिए करता हूं जहां लूपिंग उपयोगी है लेकिन तत्काल पुनरारंभ नहीं है। यहाँ लिंक और फ़ंक्शन है:

पायथन का उपयोग करके जीआईएफ कैसे बनाएं

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)

इस विधि का उपयोग करके जीआईएफ का उदाहरण दें



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

सबसे आसान चीज जो मेरे लिए काम करती है वह पायथन में एक शेल कमांड को बुला रही है।

यदि आपकी छवियां 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

चित्र फ़ाइलों के अनुक्रम के समान फ़ोल्डर से दो पंक्ति पायथन स्क्रिप्ट चलाकर कार्य पूरा किया जा सकता है। Png स्वरूपित फ़ाइलों के लिए स्क्रिप्ट है -

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

1
कोशिश की ... पायथन 2.6 के तहत मेरे लिए काम नहीं किया। लौटा: "scitools.easyviz.movie फ़ंक्शन कमांड चलाता है: / कन्वर्ट -delay 100 g4testC _ *। png g4testC.gif / अमान्य पैरामीटर - 100"
Dan H

समस्या पाइथन के साथ नहीं है। अपने सिस्टम पर इमेजमाजिक को फिर से इंस्टॉल करें और पुनः प्रयास करें।
अरके

2

मैं एक ही लाइन कोड की तलाश में था और अपने आवेदन के लिए काम करने के लिए निम्नलिखित पाया। मैंने जो किया था यह रहा:

पहला चरण: नीचे दिए गए लिंक से ImageMagick स्थापित करें

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

यहां छवि विवरण दर्ज करें

दूसरा चरण: उस फ़ोल्डर में cmd ​​लाइन को इंगित करें जहां चित्र (मेरे मामले में। Png प्रारूप) रखे गए हैं

यहां छवि विवरण दर्ज करें

तीसरा चरण: निम्न कमांड टाइप करें

magick -quality 100 *.png outvideo.mpeg

यहां छवि विवरण दर्ज करें

इस विचार के लिए धन्यवाद FogleBird!


0

मैंने बस निम्नलिखित की कोशिश की और बहुत उपयोगी था:

सबसे पहले पुस्तकालयों Figtodatऔर images2gifअपने स्थानीय निर्देशिका को डाउनलोड करें ।

दूसरे आंकड़े को एक सरणी में इकट्ठा करें और उन्हें एनिमेटेड जिफ़ में परिवर्तित करें:

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

मैं पीआईएल के इमेजसपेंस मॉड्यूल पर आया था , जो जीआईएफ ऐनमिनेशन को बेहतर (और अधिक मानक) प्रदान करता है। मैं इस बार Tk के बाद () विधि का भी उपयोग करता हूं , जो समय से बेहतर है। सो ()

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

मैं समझता हूं कि आपने छवियों को जिफ़ में बदलने के बारे में पूछा है; हालाँकि, यदि मूल प्रारूप MP4 है, तो आप FFmpeg का उपयोग कर सकते हैं :

ffmpeg -i input.mp4 output.gif

-1

यह वास्तव में अविश्वसनीय है ... सभी इस समय एनिमेटेड GIF खेलने के लिए कुछ विशेष पैकेज का प्रस्ताव कर रहे हैं, जो कि यह टिंकर और क्लासिक पीआईएल मॉड्यूल के साथ किया जा सकता है!

यहां मेरी खुद की 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समय-समय पर किसी फ़ंक्शन को कॉल करने के लिए विधि का उपयोग कर सकते हैं ।
ब्रायन ओकले

आप सही हैं, लेकिन यह बिल्कुल भी बात नहीं है, है ना? बिंदु पूरी विधि है। इसलिए, मैं उस पर प्रतिक्रिया की अपेक्षा करूंगा!
अपोस्टोलोस

1
मैं सिर्फ यह सलाह देने की कोशिश कर रहा था कि आपके उत्तर को कैसे बेहतर बनाया जाए।
ब्रायन ओकले

BTW, मैं आम तौर पर tk.after()खुद का उपयोग करता हूं। लेकिन यहां मुझे कोड को यथासंभव सरल बनाने की आवश्यकता थी। जो कोई भी इस GIF एनीमेशन विधि का उपयोग करता है वह अपना विलंब फ़ंक्शन लागू कर सकता है।
अपोस्टोलोस

अंत में! हाँ, यह वास्तव में एक बहुत अच्छा बिंदु है। मैं ऑफ-टॉपिक था! धन्यवाद, @ नोवेल। (यह देखना दिलचस्प है कि दूसरों ने इसे कैसे याद किया, उदाहरण के लिए, ब्रायन, जो समय देरी विधि के बारे में बात कर रहे थे!)
एपोस्टोलोस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.