IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Calcul scientifique Python Discussion :

Créer un gif annimé avec PIL


Sujet :

Calcul scientifique Python

  1. #1
    Membre éprouvé

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 654
    Points : 1 150
    Points
    1 150
    Par défaut Créer un gif annimé avec PIL
    Bonjour,

    Je tente de faire un gif annimé d'un graph 3D (matplotlib). J'ai pas mal cherché et je suis suis tombé sur pas mal d'exemples qui soit ne fonctionnaient pas, soit n'étaient pas adpaté à mon besoin.

    Je génère un certain nombre de fichier PNG qui sont des "vues" d'un graph. Je cherche ensuite à les assembler en un GIF annimé. Voici un bout de code qui génère un nuage de point (provenant du site de matplotlib):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    from mpl_toolkits.mplot3d import Axes3D
    from mpl_toolkits.mplot3d.art3d import Poly3DCollection
    import matplotlib.pyplot as plt
     
    # Create some random data
    def randrange(n, vmin, vmax):
        return (vmax - vmin) * np.random.rand(n) + vmin
    n = 100
    xx = randrange(n, 23, 32)
    yy = randrange(n, 0, 100)
    zz = randrange(n, -50, -25)
     
    # Create a figure and a 3D Axes
    fig = plt.figure()
    ax = Axes3D(fig)
    ax.scatter(xx,yy,zz, c='k')
    Je génère l'ensemble de mes fichiers images comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    from PIL import Image
     
    png_folder = r'c:\users\Bidon\temp\PNG_FILES'
    if not os.path.exists(png_folder):
        os.makedirs(png_folder)
     
    images = []
    for i in xrange(0,360,10):
        ax.view_init(elev=10, azim=i)
        png_name = png_folder + '\\' + 'file' + str(i) + '.png'
        plt.savefig(png_name)
        im = Image.open(png_name)
        im.convert("P") 
        images.append(im)
    J'ai trouvé un snippet provenant de la libraire Pillow pemettant de générer mes GIFs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    from PIL import Image, ImageChops
    from PIL.GifImagePlugin import getheader, getdata
     
    def gifmaker(fp, sequence):
        """Convert list of image frames to a GIF animation file"""
        frames = 0
        previous = None
        for im in sequence:
            #
            # FIXME: write graphics control block before each frame
            if not previous:
                # global header
                for s in getheader(im) + getdata(im):
                    fp.write(s)
            else:
                # delta frame
                delta = ImageChops.subtract_modulo(im, previous)
                bbox = delta.getbbox()
                if bbox:
                    # compress difference
                    for s in getdata(im.crop(bbox), offset = bbox[:2]):
                        fp.write(s)
                else:
                    # FIXME: what should we do in this case?
                    pass
            previous = im.copy()
            frames += 1
        fp.write(";")
        return frames
    Si je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    # write GIF animation
    with open('mongif.gif', 'wb') as fp:
        gifmaker(fp, images)
    J'obtiens l'erreur suivante:

    ImageFile._save(im, fp, [("gif", (0,0)+im.size, 0, RAWMODE[im.mode])])
    KeyError: 'RGBA'
    Les seules infos en lien avec ce problem indiquent de convertir les images au format 'P', ce que je fais avec :
    J'avoue ne rien connaitre en traitement d'images. Si l'un de vous pouvais m'expliquer ce qui est incorrect, ce serait vraiment genial.

    Ciao ciao

  2. #2
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2013
    Messages
    388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2013
    Messages : 388
    Points : 692
    Points
    692
    Par défaut
    Salut.
    Il faudrait plutôt faire :
    J'ai essayé, sans succès. Je n'ai pas trouvé de doc sur le module GifImagePlugin qui à l'origine du problème.
    Mais c'est bien plus facile de le faire avec la fonction convert de ImageMagick. Que tu peux appeler avec Subprocess.
    Images attachées Images attachées  

  3. #3
    Membre éprouvé

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 654
    Points : 1 150
    Points
    1 150
    Par défaut
    Bonjour __Dardanos__.

    Depuis j'ai continué à glaner des infos sur le net. Effectivement ImageMagick semble être la solution la plus plébiscité. J’ai tout de même une réserve, je ne l’ai pas précisé dans mon précédent message mais je travaille sur un PC windows entreprise où l’on doit passer par tout un process de demande/validation pour installer quelque chose. Autant dire que ce sera le parcours du combattant pour le faire installer.

    Entre temps, j’ai regardé de plus près le module Animation de Matplotlib. On peut déjà faire des choses bien sympa. Il y a une fonction pour sauvegarder l’animation crée au format MP4 à l’aide de ffmpeg. Ce qui est bien c’est qu’il n’est pas nécessaire de l’installer mais juste de préciser l’emplacement de l’exécutable.
    Voici ce que cela donne avec l’exemple employé jusqu’ici (basé sur l’excellent blog http://jakevdp.github.io/blog/2013/0...-system-in-3d/):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    """
    Animation of 3D matplotlib graph
    """
    import numpy as np
     
    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.pyplot as plt
    from matplotlib import animation
     
    # Create some random data
    def randrange(n, vmin, vmax):
        return (vmax - vmin) * np.random.rand(n) + vmin
    n = 100
    xx = randrange(n, -50, 50)
    yy = randrange(n, -100, 100)
    zz = randrange(n, -50, 50)
     
    # Set up figure & 3D axis for animation
    fig = plt.figure()
    ax = fig.add_axes([0, 0, 1, 1], projection='3d')
    #ax.axis('off')
     
    # Set up points 
    pts = ax.plot([], [], [], 'o', c='k', ms=6)
     
    # Prepare the axes limits
    ax.set_xlim((-70, 70))
    ax.set_ylim((-70, 70))
    ax.set_zlim((-70, 70))
     
    # Initialization function: plot scatter graph 
    def init():
        pts[0].set_data(xx, yy)
        pts[0].set_3d_properties(zz)
        return pts
     
    # animation function.  This will be called sequentially with the frame number    
    def animate(i):
        ax.view_init(elev=10, azim=i)
        fig.canvas.draw()
        return pts
     
    # instantiate the animator.    
    anim = animation.FuncAnimation(fig, animate, init_func=init,
                                   frames=500, interval=30, blit=True)
     
    # Save as mp4. This requires mplayer or ffmpeg to be installed
    #anim.save('test.mp4', fps=15, extra_args=['-vcodec', 'libx264'])
     
    plt.show()
    Je ne poste pas le résultat mais a vidéo est de bonne qualité. L’avantage ici c’est que l’on peut visualiser le rendu grâce à plt.show() avant de faire la conversion au format vidéo.

    Bon, ce que je veux c’est quand même de produire un GIF animé. Alors j’ai vais voir si je ne peux pas me contenter de l’exécutable convert.exe de ImageMagick à l’image de ffmpeg.

    Sinon j’ai trouvé deux modules, l’un basé sur PIL l’autre sur ImageMagick qui semblent faire le boulot:
    • Moviepy, dans lequel il y a un exemple d’utilisation ImageMagick et même de ffmpeg pour faire des GIFS assez poussés (redimensionnement, freeze de certains éléments…). https://github.com/Zulko/moviepy
    • images2gif, entièrement en python mais qui me sort un message d’erreur proche de celui obtenu avec la function gifmaker(). https://gist.github.com/jonschoning/7216290


    Je continue de chercher et je posterais les différentes solutions. Y'a étonnamment assez peu d'exemples de dispo.

    Ciao ciao,

    J

Discussions similaires

  1. Créer un damier avec PIL
    Par programmeurdu37 dans le forum Calcul scientifique
    Réponses: 12
    Dernier message: 27/12/2014, 11h36
  2. Preloader annimé avec GIF
    Par richton95 dans le forum Windows Presentation Foundation
    Réponses: 5
    Dernier message: 25/09/2009, 16h17
  3. [Eclipse] créer un service Windows avec Eclipse
    Par tck-lt dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 19/09/2005, 18h28
  4. [DisplayTag] Créer un lien dynamique avec javascript
    Par babylone7 dans le forum Taglibs
    Réponses: 3
    Dernier message: 20/04/2005, 11h23
  5. [graphics2D] gif annimé
    Par soad dans le forum 2D
    Réponses: 3
    Dernier message: 25/01/2005, 10h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo