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

Tkinter Python Discussion :

Affichage d'un gif animé sur tkinter


Sujet :

Tkinter Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2020
    Messages : 17
    Points : 14
    Points
    14
    Par défaut Affichage d'un gif animé sur tkinter
    Bonjour à vous les matineux,

    Cela fait longtemps que je souhaite utiliser un gif animé dans mes petits programmes tkinter et je voudrais bien y arriver un jour, j'ai testé tout les codes proposés sur internet mais il y a toujours le même problème : la qualité est toute froissée.

    Je ne serai pas encore capable de créer un script permettant de le faire alors je teste sur ce que je peux :

    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
    import tkinter as tk
     
    root = tk.Tk()
     
    framelist = []      # List to hold all the frames
    frame_index = 0     # Frame index
     
    while True:
        try:
            # Read a frame from GIF file
            part = 'gif -index {}'.format(frame_index)
            frame = tk.PhotoImage(file='image_en_question', format=part)
        except:
            last_frame = frame_index - 1    # Save index for last frame
            break               # Will break when GIF index is reached
        framelist.append(frame)
        frame_index += 1        # Next frame index
     
    def animate(frame_number):
        if frame_number > last_frame:
            frame_number = 0
        label.config(image=framelist[frame_number]) 
        root.after(50, animate, frame_number+1)
     
    label = tk.Label(root, bg='#202020')
    label.pack()
     
    animate(0)  # Start animation
     
    root.mainloop()
    Voici un exemple testé avec notre cher trump sur l'original et sur le résultat affiché sur tkinter.

    Je voudrais savoir d'où vient le problème pour pouvoir bourré mes programmes de déco inutiles, est ce que ça vient du script en question? de l'image à cause de certaines couleurs? de la résolution? Ou je ne sais pas je suis pas très doué

    Si quelqu'un a une réponse bien que possiblement évidente, je suis preneur merci d'avance

  2. #2
    Expert éminent
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 095
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 095
    Points : 9 581
    Points
    9 581
    Par défaut
    hello,
    avec ce code cela semble fonctionner :
    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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    from __future__ import division 
    from tkinter import *
    from PIL import Image,ImageTk
    import threading
    from time import sleep
     
     
     
    def anim_gif(name):
        ## Returns { 'frames', 'delay', 'loc', 'len' }
        im = Image.open('d:/temp/trump.gif')
        gif = { 'frames': [],
                'delay': 100,
                'loc' : 0,
                'len' : 0 }
        pics = []
        try:
            while True:
                pics.append(im.copy())
                im.seek(len(pics))
        except EOFError: pass
     
     
        temp = pics[0].convert('RGBA')
        gif['frames'] = [ImageTk.PhotoImage(temp)]
        temp = pics[0]
        for item in pics[1:]:
            temp.paste(item)
            gif['frames'].append(ImageTk.PhotoImage(temp.convert('RGBA')))
     
     
        try: gif['delay'] = im.info['duration']
        except: pass
        gif['len'] = len(gif['frames'])
        return gif
     
     
    def ratio(a,b):
        if b < a: d,c = a,b
        else: c,d = a,b
        if b == a: return 1,1
        for i in reversed(xrange(2,int(round(a / 2)))):
            if a % i == 0 and b % i == 0:
                a /= i
                b /= i
        return (int(a),int(b))
     
     
    class App(Frame):
        def show(self,image=None,event=None):
            self.display.create_image((0,0),anchor=NW,image=image)   
     
     
        def animate(self,event=None):
            self.show(image=self.gif['frames'][self.gif['loc']])
            self.gif['loc'] += 1
            if self.gif['loc'] == self.gif['len']:
                self.gif['loc'] = 0
            if self.cont:
                threading.Timer((self.gif['delay'] / 1000),self.animate).start()
     
     
        def kill(self,event=None):
            self.cont = False
            sleep(0.1)
            self.quit()
     
     
        def __init__(self,master):
            Frame.__init__(self,master)
            self.grid(row=0,sticky=N+E+S+W)
            self.rowconfigure(1,weight=2)
            self.rowconfigure(3,weight=1)
            self.columnconfigure(0,weight=1)
            self.title = Label(self,text='No title')
            self.title.grid(row=0,sticky=E+W)
            self.display = Canvas(self)
            self.display.grid(row=1,sticky=N+E+S+W)
            self.user = Label(self,text='Posted by No Username')
            self.user.grid(row=2,sticky=E+W)
            self.comment = Text(self,height=4,width=40,state=DISABLED)
            self.comment.grid(row=3,sticky=N+E+S+W)
            self.cont = True
            self.gif = anim_gif('test.gif')
            self.animate()
     
     
            root.protocol("WM_DELETE_WINDOW",self.kill)
     
     
     
     
    root = Tk()
    root.rowconfigure(0,weight=1)
    root.columnconfigure(0,weight=1)
    app = App(root)
    app.mainloop()
     
     
    try: root.destroy()
    except: pass
    A noter que le script utilise pillow et qu'il y a une conversion image en RGBA

    Résultat :

    Nom : tk_Trump.gif
Affichages : 1617
Taille : 626,5 Ko

    A noter qu'avec PyQt5 on peut directement lire un gif animé avec QMovie.

    Exemple de code :

    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
    from PyQt5 import QtCore, QtGui, QtWidgets
    import sys
     
     
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName("MainWindow")
            MainWindow.resize(300, 300)
            self.centralwidget = QtWidgets.QWidget(MainWindow)
            self.centralwidget.setObjectName("centralwidget")
     
     
            # create label
            self.label = QtWidgets.QLabel(self.centralwidget)
            self.label.setGeometry(QtCore.QRect(25, 25, 200, 200))
            self.label.setObjectName("label")
     
     
            # add label to main window
            MainWindow.setCentralWidget(self.centralwidget)
     
     
            # set qmovie as label
            self.movie = QtGui.QMovie("d:/temp/trump.gif")
            self.label.setMovie(self.movie)
            self.label.setScaledContents(True)
            self.movie.start()
     
     
    if __name__ == "__main__":
        app = QtWidgets.QApplication(sys.argv)
        window = QtWidgets.QMainWindow()
        ui = Ui_MainWindow()
        ui.setupUi(window)
        window.show()
        sys.exit(app.exec_())

    Ami calmant, J.P

  3. #3
    Membre expérimenté
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 904
    Points : 1 591
    Points
    1 591
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par jurassic pork Voir le message
    hello,
    avec ce code cela semble fonctionner :
    Bonjour,
    Je lis le code et je ne vois aucun appel à la fonction ration()...
    ?

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2020
    Messages : 17
    Points : 14
    Points
    14
    Par défaut
    Citation Envoyé par jurassic pork Voir le message
    hello,
    avec ce code cela semble fonctionner :
    Re

    Merci pour ton code t'es une machine !

    J'ai essayé avec l'image gif de trump en question, ton code permet d'afficher toutes les couleurs sauf que celles ci paraissent différentes et mélangés : https://streamable.com/kwpeou

    A vrai dire je voulais animé ce gif en particulier, et j'y arrive avec le script que tu as fait donc c'est bon pour moi merci beaucoup

  5. #5
    Expert éminent
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 095
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 095
    Points : 9 581
    Points
    9 581
    Par défaut
    hello,
    Citation Envoyé par teddyfresnes Voir le message
    Re
    Merci pour ton code t'es une machine !
    J'ai essayé avec l'image gif de trump en question, ton code permet d'afficher toutes les couleurs sauf que celles ci paraissent différentes et mélangés : https://streamable.com/kwpeou
    A vrai dire je voulais animé ce gif en particulier, et j'y arrive avec le script que tu as fait donc c'est bon pour moi merci beaucoup
    Ce n'est pas moi qui est fait le code et ATTENTION ! il ne faut pas utiliser ce code : je viens de m'apercevoir qu'il y a des fuites mémoire dedans et aussi une utilisation CPU excessive.

    La partie incriminée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        def animate(self,event=None):        
            self.show(image=self.gif['frames'][self.gif['loc']])
            self.gif['loc'] += 1
            if self.gif['loc'] == self.gif['len']:
                self.gif['loc'] = 0
            if self.cont:
                threading.Timer((self.gif['delay'] / 1000),self.animate).start()
    Voici un code beaucoup plus propre qui utilise moins de CPU :
    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
    import tkinter as tk
    from PIL import Image, ImageTk
     
    from itertools import count, cycle
     
    class ImageLabel(tk.Label):
        """
        A Label that displays images, and plays them if they are gifs
        :im: A PIL Image instance or a string filename
        """
        def load(self, im):
            if isinstance(im, str):
                im = Image.open(im)
            frames = []
     
            try:
                for i in count(1):
                    frames.append(ImageTk.PhotoImage(im.copy()))
                    im.seek(i)
            except EOFError:
                pass
            self.frames = cycle(frames)
     
            try:
                self.delay = im.info['duration']
            except:
                self.delay = 100
     
            if len(frames) == 1:
                self.config(image=next(self.frames))
            else:
                self.next_frame()
     
        def unload(self):
            self.config(image=None)
            self.frames = None
     
        def next_frame(self):
            if self.frames:
                self.config(image=next(self.frames))
                self.after(self.delay, self.next_frame)
     
    #demo :
    root = tk.Tk()
    lbl = ImageLabel(root)
    lbl.pack()
    lbl.load('d:/temp/trump3.gif')
    root.mainloop()

    Citation Envoyé par teddyfresnes Voir le message
    Voici un exemple testé avec notre cher trump sur l'original et sur le résultat affiché sur tkinter.
    Je voudrais savoir d'où vient le problème pour pouvoir bourré mes programmes de déco inutiles, est ce que ça vient du script en question? de l'image à cause de certaines couleurs? de la résolution? Ou je ne sais pas je suis pas très doué
    Je crois que j'ai trouvé d'où vient le problème. J' ai récupéré un équivalent de ton gif animé sur internet et en fait dedans il y a utilisation sur quelques trames du canal alpha (qui sert à la transparence) . Si j'enlève de ce gif animé les trames qui utilisent le canal alpha, il n'y a plus de problème de visualisation. Par contre en utilisant une version différente de ce gif animé qui contient pourtant de la transparence il n'y a pas de problème.

    A noter qu'en utilisant pyQt5 et le QMovie (voir mon message précédent) celui-ci arrive à lire et visualiser correctement le gif animé avec transparence qui posait problème.

    Ami calmant, J.P

  6. #6
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2020
    Messages : 17
    Points : 14
    Points
    14
    Par défaut
    Citation Envoyé par jurassic pork Voir le message
    hello,
    Ce n'est pas moi qui est fait le code et ATTENTION ! il ne faut pas utiliser ce code : je viens de m'apercevoir qu'il y a des fuites mémoire dedans et aussi une utilisation CPU excessive.
    C'est vrai que le code d'avant semblait assez lourd, il y avait même un léger délai avant l'affichage du gif

    Je vais donc prendre ce code qui fonctionne parfaitement ^^

    Concernant la qualité, je me doutais qu'il y avait un problème de transparence avec les trous qu'on pouvait remarquer dans les gifs importés, je suppose que j'ai réussi à récupérer un gif sans cette fameuse trame alpha qui me causait des soucis, par contre, je ne sais pas comment me débarrasser de la transparence sur les autres gifs animés

    Niveau pyQt5 j'avais déjà préluder mon programme en tkinter je ne compte pas changer de bibliothèque même si tk privilège plus l'apprentissage graphique que l'optimisation et la qualité, enfin bref, ce qui compte, c'est que ça fonctionne donc merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Gif animé sur un bouton
    Par g_barthe dans le forum wxPython
    Réponses: 2
    Dernier message: 02/09/2008, 15h28
  2. [WD12] Gif animé sur fenetre soeur
    Par devste dans le forum WinDev
    Réponses: 6
    Dernier message: 16/06/2008, 16h13
  3. Gif animé sur excel
    Par moilou2 dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 15/02/2008, 15h01
  4. gif animé sur form et si possible sur boutton
    Par netah25 dans le forum C++Builder
    Réponses: 4
    Dernier message: 14/05/2007, 19h45
  5. gifs animés sur image jpg
    Par DARDI dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 03/03/2007, 11h22

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