Programlı olarak Python'da video veya animasyonlu GIF oluşturuyor mu?


221

Bir video oluşturmak istediğim bir dizi resmim var. İdeal olarak, her bir kare için bir kare süresi belirleyebilirim, ancak sabit bir kare hızı da iyi olur. Bunu wxPython'da yapıyorum, bu yüzden bir wxDC'ye işleyebilir veya resimleri PNG gibi dosyalara kaydedebilirim. Bu karelerden bir video (AVI, MPG, vb.) Veya animasyonlu bir GIF oluşturmamı sağlayacak bir Python kütüphanesi var mı?

Düzenleme: Zaten PIL denedim ve çalışmıyor gibi görünüyor. Birisi bu sonuçla beni düzeltebilir veya başka bir araç seti önerebilir mi? Bu bağlantı PIL ile ilgili sonucumu yedekliyor gibi görünüyor: http://www.somethinkodd.com/oddthinking/2005/12/06/python-imaging-library-pil-and-animated-gifs/

Yanıtlar:


281

PIL / Pillow ile ilgili sorunları olduğundan ve aktif olarak korunmadığı için visvis'ten images2gif kullanmamanızı tavsiye ederim (bilmeliyim, çünkü ben yazarım).

Bunun yerine, lütfen bu sorunu ve daha fazlasını çözmek için geliştirilen ve kalması amaçlanan imageio kullanın .

Hızlı ve kirli çözüm:

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

Daha uzun filmler için akış yaklaşımını kullanın:

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
ayrıca parametre süresi = 0,5 her kare için 0,5 saniyelik süreleri ayarlar.
Alleo

3
ValueError: 'i' modunda belirtilen dosyayı okumak için bir biçim bulunamadı - Windows 2.7 winpython'da bu hatayı alıyorum. Herhangi bir ipucu var mı?
Vanko

1
@Vanko, dosyanın okunmasıyla ilgili gibi görünüyor, imagio.mimread'i deneyebilir veya çok sayıda kareye sahip bir film varsa, şu şekilde okuyucu nesnesini kullanın: imageio.readthedocs.io/en/latest/…
Almar

2
@Alleo: "ayrıca parametre süresi = 0,5 her kare için 0,5 saniyelik süreleri ayarlar". İmageio için süre özelliği var mı? Varsa, bu nerede belgelenir? Tüm belgeleri okudum ve süre argümanından bahsetmedim.
Chris Nielsen

3
Mükemmel! imageio in anacondaverim True, yay!
uhoh

47

Şimdi ImageMagick kullanıyorum. Çerçevelerimi PNG dosyaları olarak kaydediyorum ve ardından animasyonlu bir GIF oluşturmak için ImageMagick'in convert.exe dosyasını Python'dan çağırıyorum. Bu yaklaşımla ilgili güzel olan şey, her bir kare için ayrı bir kare süresi belirleyebilmemdir. Ne yazık ki bu, makineye yüklenmiş olan ImageMagick'e bağlıdır. Python sarıcıları var ama oldukça berbat ve desteklenmiyor. Hala diğer önerilere açık.


21
Ben bir Python adamıyım ama ImageMagick'i burada çok daha kolay buldu. Ben sadece görüntü dizimi yaptım ve böyle bir şey koştumconvert -delay 20 -loop 0 *jpg animated.gif
Nick

Katılıyorum, bu karşılaştığım en iyi çözüm. İşte minimal bir örnek (Steve
B'in

ImageMagick'i kullanarak animasyonlu gif gibi kolayca yeniden boyutlandırabilirsinizconvert -delay 20 -resize 300x200 -loop 0 *jpg animated.gif
Jun Wang

@Nick, GIF yapmak için bu kodu nasıl çalıştırıyorsunuz? Spyder IDE'ye bir şey aktarmalı mıyım?
AY

@MOON Yukarıda eklediğim ImageMagic komutu sadece komut satırı üzerinden çalıştırılıyor.
Nick

43

Haziran 2009'dan itibaren orijinal olarak atıf yapılan blog gönderisinde yorumlarda animasyonlu GIF oluşturma yöntemi vardır . Senaryoları images2gif.py indirin (önceden images2gif.py , @geographika'nın izniyle güncelleme) .

Ardından, örneğin bir gifteki kareleri tersine çevirmek için:

#!/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
Bu betiğin visvis.googlecode.com/hg/vvmovie/images2gif.py adresinden çok daha kaliteli çıktı sağlayan yeni bir sürümü var, paketten ayrı bağımsız bir komut dosyası olarak kullanılabilir.
geographika

1
Bu açıklamada bahsedilen komut dosyası, Mac'te kullanıldığında, yalnızca çalıştırıldığında bile ( __ == '__ main ' örneği adını kullanarak) sürekli olarak bir segmentasyon hatası veriyor . Düzgün çalışacağını umarak cevapta belirtilen senaryoyu deniyorum. EDIT - Yukarıdaki yanıtta başvurulan komut dosyasının Mac bilgisayarımda düzgün çalıştığını doğrulayabilirim.
scubbo

6
Aksine sadece Pip örneğin komut kullanımını indirmek daha pip install visvisBetiğinizde sonra from visvis.vvmovie.images2gif import writeGif.
Daniel Farrell

8
Bunu Windows 8'de Python 2.7.3 ile denedim ve UnicodeDecodeError'u alıyorum: 'ascii' codec bileşeni 6 pozisyonunda bayt 0xc8 kodunu çözemiyor: sıra (aralık) içinde sıra dışı değil. Piton images2gif.py çalışmasını
hesap cetveli

3
Ben visivis (ve images2gif) 'in yazarıyım ve bu amaçla kullanılmamasını öneriyorum. Imageio projesinin bir parçası olarak daha iyi bir çözüm üzerinde çalışıyorum (cevabımı görün).
Almar

40

İşte bunu kullanarak bunu nasıl tek PIL (ile yükleyin: 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
bu kabul edilen cevap olmalı, teşekkürler @Kris
ted930511

1
Yıldız değişkeni ne tutar ("* imgs")?
denisb411

3
Bu bir python dili özelliğidir. Tekrarlanabilir bir açma yapar . Sen kabaca açma gibi düşünebilirsiniz edebilirsiniz x = [a, b, c]etmek *xolarak düşünülebilir hangi a, b, c(çevreleyen parantez olmadan). Fonksiyon çağrıları ise bu eşanlamlı şunlardır: f(*x) == f(a, b, c). Tuple ambalajından çıkarmada, bir yinelenebilir öğeyi bir kafaya (ilk eleman) ve bir kuyruğa (geri kalanı) bölmek istediğiniz durumlarda özellikle yararlıdır, bu örnekte yaptığım şey budur.
Kris

25

İmages2gif.py kullandım kullanımı kolay kullandım. Yine de dosya boyutunu iki katına çıkardı.

26 110kb PNG dosyaları, beklediğim 26 * 110kb = 2860kb, ancak my_gif.GIF 5.7mb

GIF 8 bit olduğu için, güzel png'ler GIF'te biraz bulanıklaştı

İşte kullandığım kod:

__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

İşte 26 çerçeveden 3'ü:

İşte 26 çerçeveden 3'ü

görüntüleri küçültmek boyutu azalttı:

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

küçük gif


Bu konuda bir blog yazısı yaptım .. robert-king.com/#post2-python-makes-gif
robert king

2
Hata alıyorum .. Dosya: "C: \ Python27 \ lib \ images2gif.py", satır 418, writeGifToFile globalPalette = palettes [oluş.index (max (oluş))] ValueError: max () arg boş bir dizidir
Harry

meydana gelmesi büyük olasılıkla boştur. İmages2gif.py dosyamda "globalPalette" değişkeni yok.
robert king

bunu nasıl değiştirebilirim? Orada en son images2gif.py komut dosyasını kullanıyorum ( bit.ly/XMMn5h )
Harry

4
@robertking kodu ile ilgili bir hata fp.write(globalPalette) TypeError: must be string or buffer, not list
mesajı

19

Video oluşturmak için opencv kullanabilirsiniz ,

#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

Bu yazıyla karşılaştım ve çözümlerin hiçbiri işe yaramadı, işte benim işime yarayan çözümüm

Şimdiye kadar diğer çözümlerle ilgili sorunlar:
1) Sürenin nasıl değiştirildiğine dair açık bir çözüm yok
2) GIF'ler için gerekli olan sıra dışı dizin yinelemesi için çözüm yok
3) Python 3 için imageio'nun nasıl kurulacağına dair bir açıklama yok

imageio'yu şu şekilde yükleyin:imageio'yu python3 -m pip installio

Not: Çerçevelerinizin dosya adında sıralanabilmeleri için bir tür dizine sahip olduğundan emin olmak istersiniz, aksi takdirde GIF'in nerede başladığını veya bittiğini bilmenin hiçbir yolu yoktur

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
sortnumaralandırma şemanız baştaki sıfırları içermiyorsa beklenmedik sonuçlar verebilir. Ayrıca neden basit bir liste kavrayışı yerine haritayı kullandınız?
NOhs

filenames.append(os.path.join(path, filename))
Yapmayı

Nocosning Nohs, images = [imageio.imread(f) for f in filenames]daha temiz, daha hızlı ve daha pitoniktir.
Brandon Dube

6

Warren'ın geçen yıl söylediği gibi , bu eski bir soru. İnsanlar hala sayfayı görüntülüyor gibi göründüklerinden, onları daha modern bir çözüme yönlendirmek istiyorum. Blakev Dediğim gibi burada , bir Yastık örneği yoktur 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()

Not: Bu örnek güncel gifmakerdeğildir ( içe aktarılabilir bir modül değildir, yalnızca bir betiktir). Yastığın bir GifImagePlugin'i vardır (kaynağı GitHub'dadır ), ancak ImageSequence'daki doküman sınırlı desteği gösteriyor gibi görünüyor (sadece okuma)



5

Eski soru, birçok iyi cevap, ama yine de başka bir alternatifle ilgilenilebilir ...

numpngwGeçenlerde github (yukarı koymak modül https://github.com/WarrenWeckesser/numpngw numpy dizilerinden animasyonlu PNG dosyalarını yazabilir). ( Güncelleme : numpngwşimdi pypi'de: https://pypi.python.org/pypi/numpngw .)

Örneğin, bu komut dosyası:

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)

oluşturur:

animasyonlu png

Animasyonu görmek için animasyonlu PNG'yi (doğrudan veya bir eklenti ile) destekleyen bir tarayıcıya ihtiyacınız olacak.


Chrome şimdi de öyle, BTW. Bir soru - seq yinelenebilir mi? "Akışı" destekliyor musunuz (örn. Hedef APNG'yi açma ve bir döngüde tek tek kareler ekleme)?
Tomasz Gandor

Keyfi bir yinelenebilir veya akış desteklemiyor, ancak bu gelecekte yapılamayacağı anlamına gelmiyor. :) Github sayfasında önerilen geliştirmeyle ilgili bir sorun oluşturun . Bu özelliğe ilişkin API hakkında herhangi bir fikriniz varsa, lütfen bunları sorunda açıklayın.
Warren Weckesser

Reponuzla ilgili bir sorun çıkardığım garip bir hatayla karşılaştım.
mLstudent33

5

Yukarıda belirtildiği gibi, imageio bunu yapmanın harika bir yoludur. imageio ayrıca kare hızını ayarlamanıza izin verir ve aslında Python'da son karede bir tutma ayarlamanıza izin veren bir işlev yazdım. Bu işlevi, döngü oluşturmanın faydalı olduğu ancak anında yeniden başlatmanın olmadığı bilimsel animasyonlar için kullanıyorum. İşte bağlantı ve fonksiyon:

Python kullanarak GIF nasıl yapılır

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)

Bu yöntemi kullanarak GIF örneği



4

Windows7, python2.7, opencv 3.0 ile aşağıdakiler benim için çalışır:

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

Benim için çalışmasını sağlayan en kolay şey Python'da bir kabuk komutu çağırmak.

Görüntüleriniz dummy_image_1.png, dummy_image_2.png ... dummy_image_N.png gibi saklanırsa, şu işlevi kullanabilirsiniz:

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

Sadece çalıştırın:

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

Bu, gif dosyanızı my_output.gif oluşturacaktır.


2

Görev, iki satırlı python betiği, resim dosyalarının sırası ile aynı klasörden çalıştırılarak tamamlanabilir. PNG formatlı dosyalar için komut dosyası -

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

1
Denedim ... benim için Python 2.6 altında çalışmadı. Döndü: "scitools.easyviz.movie işlevi şu komutu çalıştırır: / convert -delay 100 g4testC _ *. Png g4testC.gif / Geçersiz Parametre - 100"
Dan H

Sorun Python ile kesin değil. Imagemagick'i sisteminize yeniden yükleyin ve tekrar deneyin.
ArKE

2

Tek bir satır kodu arıyordum ve uygulamamda çalışmak için aşağıdakileri buldum. İşte yaptım:

İlk Adım: ImageMagick'i aşağıdaki bağlantıdan yükleyin

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

resim açıklamasını buraya girin

İkinci Adım: cmd çizgisini görüntülerin (benim durumumda .png biçiminde) yerleştirildiği klasöre yönlendirin

resim açıklamasını buraya girin

Üçüncü Adım: Aşağıdaki komutu yazın

magick -quality 100 *.png outvideo.mpeg

resim açıklamasını buraya girin

Fikir için teşekkürler FogleBird!


0

Ben sadece aşağıdakileri denedim ve çok yararlı oldu:

Önce kütüphaneleri Figtodatve images2gifyerel dizininizi indirin.

İkincisi bir dizideki rakamları toplayın ve animasyonlu bir gif'e dönüştürün:

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

Ben pil takımından geldi ImageSequence modülü, hangi daha iyi (ve daha fazla standart) GIF aninmation için teklifler. Bu sefer Tk'nin after () yöntemini de kullanıyorum , bu da time.sleep () ' dan daha iyi .

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 yapan basit bir işlev:

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

Anladığım kadarıyla görüntüleri bir GIF'e dönüştürmek istediniz ancak, orijinal biçim MP4 ise, FFmpeg kullanabilirsiniz :

ffmpeg -i input.mp4 output.gif

-1

Gerçekten inanılmaz ... Hepsi Tkinter ve klasik PIL modülü ile yapılabildiği anda, animasyonlu bir GIF oynatmak için özel bir paket öneriyor!

İşte kendi GIF animasyon yöntemim (Bir süre önce oluşturdum). Çok basit:

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()

Animasyonu durdurmak için kendi araçlarınızı ayarlayabilirsiniz. Oynat / duraklat / çık düğmeleriyle tam sürümü almak isteyip istemediğinizi bize bildirin.

Not: Ardışık karelerin bellekten mi yoksa dosyadan mı (disk) okunacağından emin değilim. İkinci durumda, hepsinin aynı anda okuması ve bir diziye (listeye) kaydedilmesi daha verimli olacaktır. (Öğrenmekle ilgilenmiyorum! :)


1
sleepBir GUI'nin ana iş parçacığını aramak genellikle iyi bir ideal değildir . afterBir işlevi periyodik olarak çağırmak için yöntemi kullanabilirsiniz .
Bryan Oakley

Haklısın, ama mesele bu değil, değil mi? Mesele tüm yöntemdir. Yani, buna bir tepki bekliyorum!
Apostolos

1
Sadece cevabınızı nasıl geliştireceğiniz konusunda tavsiyeler vermeye çalışıyordum.
Bryan Oakley

BTW, normalde tk.after()kendimi kullanıyorum. Ama burada kodu olabildiğince basit hale getirmem gerekiyordu. Bu GIF animasyon yöntemini kullanan kişi kendi gecikme işlevini uygulayabilir.
Apostolos

Sonunda! Evet, bu gerçekten çok iyi bir nokta. Konu dışıydım! Teşekkürler @Novel. (Diğerlerinin bunu nasıl kaçırdığını görmek ilginç, örneğin zaman gecikmesi yönteminden bahseden Bryan!)
Apostolos
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.