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 :

Actualisation de l'image dans le Canvas


Sujet :

Tkinter Python

  1. #21
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Comme suspecté dans un message précédent, vos images sont assez grandes pour que les calculs pour fabriquer une nouvelle image prenne quelques secondes. La solution simple est d'insérer des .update_idletasks dans la boucle pour que le rafraichissement de l'écran se fasse en attendant. Mais je n'arrive pas à la faire fonctionner pour ce widget.
    La solution normale serait de faire ces calculs dans un Thread (i.e. en parallèle)... mais sa mise en place est compliquée.
    Essayez de confirmer que l'affichage est plus fluide avec de petites images.
    Croisez les doigts pour qu'un lecteur trouve une solution "utilisable".
    Le problème se reproduit simplement avec le code suivant:
    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
    import Tkinter as tk
    import time
     
    def do_update(value):
        print (value)
        for x in range(600):
            for y in range(600):
                pass
            time.sleep(0.003)
     
    root = tk.Tk()
     
    scale = tk.Scale(root, from_=-150, to=250, resolution=25, orient='horizontal',
             length=250, width=10, tickinterval=50)
    scale.pack()
    scale['command'] = do_update
    tk.mainloop()
    La double boucle glandouille juste histoire de simuler le calcul de la nouvelle image.... et on veut juste un peu de magie pour rafraichir l'affichage pendant ce temps là.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  2. #22
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 608
    Points : 2 072
    Points
    2 072
    Par défaut
    Voici ce que j'avais fait il y a quelques temps.
    Ceci fonctionne pour Windows en python3.
    La conversion en gif est différente sous linux.
    Le passage par gif permet peut-être d'éviter le problème précédemment soulevé ?
    Perso, je n'arrive pas à faire tourner ton programme sous python2 : erreur d'encodage apparemment.
    Comme je ne travaille plus sous python2, je ne creuse pas...

    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
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    from PIL import Image as Im
    import os
    from tkinter import Entry, Label, Tk
    from tkinter import Canvas, PhotoImage, Button
     
    def recup():
        """
        récupération du nom de fichier et de l'extension
        ouverture de l'image
        """
        nom_fich=entr1.get()
        nom_ext = entr2.get()
        # ext1 = '.jpg'
        ext2 = '.gif'
        global cible_gif, source_gif
        global cible_jpg, source_jpg
        source_jpg = nom_fich + '.' + nom_ext
        source_gif = nom_fich + ext2
        cible_jpg = nom_fich + 'conv' + '.' + nom_ext
        cible_gif = nom_fich + 'conv' + ext2
        global mon_image, largeur, hauteur
        mon_image = Im.open(source_jpg)
        mon_image.save(source_gif)
        largeur,hauteur = mon_image.size
     
    def sauvegarde():
        """
        sauvegarde de l'image visualisée dans le
        format souhaité
        """
        sauv_fich=entr3.get()
        sauv_ext = entr4.get()
        # ext1 = '.jpg'
        sauv_complet = sauv_fich + '.' + sauv_ext
        mon_image = Im.open(cible_jpg)
        mon_image.save(sauv_complet)
     
    def jpg_gif(nom1,nom2):
        """ 
        conversion de format, par exemple jpg en gif
        à l'aide de imagemagick (sous linux seulement ?)
        """
        os.system('convert %s %s' % (nom1,nom2))
     
    def binarisation(image):
        image2 = Im.new('RGB',(largeur,hauteur))
        for colonne in range(largeur):
            for ligne in range(hauteur):
                pixel=image.getpixel((colonne,ligne))
                moyenne = (pixel[0] + pixel[1] + pixel[2])/3
                if moyenne < 128:
                    image2.putpixel((colonne,ligne),(0,0,0))
                else:
                    image2.putpixel((colonne,ligne),(255,255,255))
        return(image2)
     
    def niveaux_gris(image):
        image2 = Im.new('RGB',(largeur,hauteur))
        for colonne in range(largeur):
            for ligne in range(hauteur):
                pixel=image.getpixel((colonne,ligne))
                moyenne = int((pixel[0] + pixel[1] + pixel[2])/3)
                image2.putpixel((colonne,ligne),(moyenne,moyenne,moyenne))
        return(image2)
     
    def negatif_NB(image):
        image = binarisation(image)
        image2 = Im.new('RGB',(largeur,hauteur))
        for colonne in range(largeur):
            for ligne in range(hauteur):
                pixel=image.getpixel((colonne,ligne))
                neg = 255 - pixel[0]
                image2.putpixel((colonne,ligne),(neg,neg,neg))
        return(image2)
     
    def negatif_gris(image):
        image = niveaux_gris(image)
        image2 = Im.new('RGB',(largeur,hauteur))
        for colonne in range(largeur):
            for ligne in range(hauteur):
                pixel=image.getpixel((colonne,ligne))
                neg = 255 - pixel[0]
                image2.putpixel((colonne,ligne),(neg,neg,neg))
        return(image2)
     
    def negatif_couleur(image1):
        image2 = Im.new('RGB',(largeur,hauteur))
        for colonne in range(largeur):
            for ligne in range(hauteur):
                pixel=image1.getpixel((colonne,ligne))
                rouge = 255 - pixel[0]
                vert = 255 - pixel[1]
                bleu = 255 - pixel[2]
                image2.putpixel((colonne,ligne),(rouge,vert,bleu))
        return(image2)
     
    def sepia(image):
        image = niveaux_gris(image)
        image2 = Im.new('RGB',(largeur,hauteur))
        for colonne in range(largeur):
            for ligne in range(hauteur):
                pixel=image.getpixel((colonne,ligne))
                vert=pixel[1]
                if pixel[0]<=62:
                    rouge = int(pixel[0]*1.1)
                    bleu = int(pixel[2]*0.9)
                elif pixel[0]<192:
                    rouge=int(pixel[0]*1.15)
                    bleu = int(pixel[2]*0.85)
                else:
                    rouge=int(min(pixel[0]*1.08,255))
                    bleu=int(pixel[2]*0.93)
                image2.putpixel((colonne,ligne),(rouge,vert,bleu))
        return(image2)
     
    def conv_binarisation():
        """ conversion noir et blanc puis conversion de format
        pour avoir les aperçus dans tkinter"""
        recup()
        res = binarisation(mon_image)
        res.save(cible_jpg)
        res.save(cible_gif)
    #    jpg_gif(source_jpg,source_gif)
    #    jpg_gif(cible_jpg,cible_gif)
        rafraichissement()
     
    def conv_negatif_NB():
        """ conversion niveaux de gris puis conversion de format
        pour avoir les aperçus dans tkinter"""
        recup()
        res = negatif_NB(mon_image)
        res.save(cible_jpg)
        res.save(cible_gif)
    #    jpg_gif(source_jpg,source_gif)
    #    jpg_gif(cible_jpg,cible_gif)
        rafraichissement()
     
    def conv_niveaux_gris():
        """ conversion niveaux de gris puis conversion de format
        pour avoir les aperçus dans tkinter"""
        recup()
        res = niveaux_gris(mon_image)
        res.save(cible_jpg)
        res.save(cible_gif)
    #    jpg_gif(source_jpg,source_gif)
    #    jpg_gif(cible_jpg,cible_gif)
        rafraichissement()
     
    def conv_negatif_gris():
        """ conversion négatif gris puis conversion de format
        pour avoir les aperçus dans tkinter"""
        recup()
        res = negatif_gris(mon_image)
        res.save(cible_jpg)
        res.save(cible_gif)
    #    jpg_gif(source_jpg,source_gif)
    #    jpg_gif(cible_jpg,cible_gif)
        rafraichissement()
     
    def conv_negatif_couleur():
        """ conversion négatif couleur puis conversion de format
        pour avoir les aperçus dans tkinter"""
        recup()
        res = negatif_couleur(mon_image)
        res.save(cible_jpg)
        res.save(cible_gif)
    #    jpg_gif(source_jpg,source_gif)
    #    jpg_gif(cible_jpg,cible_gif)
        rafraichissement()
     
    def conv_sepia():
        """ conversion négatif couleur puis conversion de format
        pour avoir les aperçus dans tkinter"""
        recup()
        res = sepia(mon_image)
        res.save(cible_jpg)
        res.save(cible_gif)
    #    jpg_gif(source_jpg,source_gif)
    #    jpg_gif(cible_jpg,cible_gif)
        rafraichissement()
     
    def rafraichissement():
        """
        rafarichissement des images source et cible dans les fenêtres de visualisation
        """
        global photo1, photo2
        can1 = Canvas(fen1, width =160, height =160, bg ='white')
        can1.grid(row =1, column =3, rowspan =3, padx =10, pady =5)
        can2 = Canvas(fen1, width =160, height =160, bg ='white')
        can2.grid(row =1, column =5, rowspan =3, padx =10, pady =5)
        if os.path.isfile(source_gif) == True:
            photo1 = PhotoImage(file = source_gif)
            image1 = can1.create_image(80, 80, image =photo1)
        if os.path.isfile(cible_gif) == True:
            photo2 = PhotoImage(file = cible_gif)
            image2 = can2.create_image(80, 80, image =photo2)
     
    fen1 = Tk()
     
    txt1 = Label(fen1, text ='Nom de fichier (sans extension)')
    entr1 = Entry(fen1)
    txt1.grid(row =1, column=1, sticky ='EW')
    entr1.grid(row =1, column =2)
     
    txt2 = Label(fen1, text ='Extension')
    entr2 = Entry(fen1)
    txt2.grid(row =2, column=1, sticky ='EW')
    entr2.grid(row =2, column =2)
     
    txt3 = Label(fen1, text ='Nom de fichier de sauvegarde')
    entr3 = Entry(fen1)
    txt3.grid(row =4, column=4, sticky ='EW')
    entr3.grid(row =4, column =5)
     
    txt4 = Label(fen1, text ='Extension de sauvegarde')
    entr4 = Entry(fen1)
    txt4.grid(row =5, column=4, sticky ='EW')
    entr4.grid(row =5, column =5)
     
    ## Bouton pour convertir
    # Button(fen1,text='Nouvelle acquisition',command=recup).grid(row=4 , column=3, sticky='NESW')
    ## Boutons pour convertir
    Button(fen1,text='Binarisation (N&B)',command=conv_binarisation).grid(row=4 , column=1, sticky='NESW')
    Button(fen1,text='Niveaux de gris',command=conv_niveaux_gris).grid(row=5 , column=1, sticky='NESW') 
    Button(fen1,text='Négatif N&B',command=conv_negatif_NB).grid(row=6 , column=1, sticky='NESW') 
    Button(fen1,text='Négatif gris',command=conv_negatif_gris).grid(row=7 , column=1, sticky='NESW') 
    Button(fen1,text='Négatif couleur',command=conv_negatif_couleur).grid(row=8 , column=1, sticky='NESW')
    Button(fen1,text='Sépia',command=conv_sepia).grid(row=9 , column=1, sticky='NESW')
    ## Raffraichissement
    # Button(fen1,text='Rafraichissement',command=rafraichissement).grid(row=5 , column=3, sticky='NESW')
    # Sauvegarde
    Button(fen1,text='Sauvegarde',command=sauvegarde).grid(row=7 , column=5, sticky='NESW')
    # fermeture
    Button(fen1,text='Quitter',command=fen1.destroy).grid(row=7 , column=3,columnspan=2, sticky='NESW')
     
    # démarrage :
    fen1.mainloop()
    Pas d'aide par mp.

  3. #23
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 608
    Points : 2 072
    Points
    2 072
    Par défaut
    J'ai modifié ton programme afin qu'il fonctionne sous python3.
    C'est vrai que c'est étonnant, ce comportement.
    Voici le code pour ceux qui voudraient le tester :
    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
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    # -*- coding: cp1252 -*-
     
    ##### Import #####
    import tkinter as tk
    import tkinter.filedialog as Selector # Module permettant de selectionner l'image que l'on veut
    import webbrowser               # webbrowser permet l'ouverture de l'image avec la visionneuse de photos Windows
    import PIL
    from PIL import Image, ImageTk
    from tkinter.messagebox import *      # Permet l'ouverture de boîtes de dialogue standard pour l’affichage de messages
     
    ##### Fonctions #####
     
    def ActualisationDeImage () :
        Fond.destroy()                              # On detruit l'ancienne image
     
        NouvelleImage = Image.open(fichierSortie)   # Le paramètre image représente l'image que l'on veux insérer
     
        NouvellePhoto = ImageTk.PhotoImage(NouvelleImage)   # Avec la fonction ImageTk.PhotoImage (), on peut créer une image compatible Tkinter,
                                                            # qu'on pourra afficher dans un Canvas par la méthode create_image(position, **options)
                                                            # où position réprésente les 2 coordonnées du coin en haut à gauche de l'image,
                                                            # sachant que l'image sera aussi positionnée par rapport au paramètre anchor
                                                            # qui par défaut vaut CENTER. 
     
        NouveauFond = tk.Canvas(fenetre, width = NouvelleImage.size[0], height = NouvelleImage.size[1])
     
                                                            # Le Canvas ne s'adapte pas par défaut à la place que prennent 
                                                            # les éléments que l'on à dessiner dedans. Donc si l'image que 
                                                            # l'on veux insére est trop grande, on peut être assuré qu'elle sera
                                                            # entièrement visible en renseignant les paramètres width et height à la création du Canvas.
     
        NouveauFond.create_image(0, 0, anchor = tk.NW, image=NouvellePhoto)  # Pour que l'image soit positionnée en haut à gauche du Canvas,
                                                                             # on doit utiliser la position 0, 0 et rajouter le paramètre anchor = Tk.NW
        NouveauFond.place (x=2, y=2) # On place le Nouveau Fond
        NouveauFond.mainloop()       # On ouvre la Nouvelle Image 
     
     
     
    def NouvelleImage () :       
        webbrowser.open(fichierSortie)
     
     
    def ImageDeDepart () :       
        webbrowser.open(fichierEntree)
     
     
    def MessageAide () :
        showinfo(' AIDE ' , "Les boutons couleurs permettent de changer la couleur de l'image. Les boutons filtres appliquent des filtres sur la photo. \
    Par exemple, le bouton niveau de gis, change l'image en niveau de gris. Le bouton posterise permet de transformer l'image en une peinture. \
    Le seuillage permet de reduire les couleurs de l'image en seulement deux couleurs, le noir et le blanc. Le négatif, permet d'inverser \
    les couleurs de l'image. Ensuite, les boutons de redimenssionnement permettent de redimanssionner l'image. Les boutons de deplacement de l'image \
    font tourner l'image sur elle-même et dans différentes positions (90 - 180 - 270 degrés).")
     
     
     
    def couleurCyan () :                # Martin  
        for y in range(H): # on balaie toutes les lignes de l’image source, de 0 à H-1
            for x in range(L): # pour chaque ligne on balaie toutes les colonnes, de 0 à L-1
                pixel = im1.getpixel((x,y)) # en stockant le pixel (x,y) dans une liste p à tois éléments
                                    # p[0] est la composante rouge, p[1] la composante verte, et p[2] la composante bleue
                r = 0
                v = pixel[1]  
                b = pixel[2]
                im2.putpixel((x,y),(r,v,b)) # on écrit le pixel modifié sur l’image destination
                im1.putpixel((x,y),(r,v,b))
     
     
     
        im2.save(fichierSortie) # on stocke l’image résultante
        ActualisationDeImage () # On actualise l'image qui se trouve dans le Canvas
     
     
     
    def couleurRouge () :             # Martin  
        for y in range(H): # on balaie toutes les lignes de l’image source, de 0 à H-1
            for x in range(L): # pour chaque ligne on balaie toutes les colonnes, de 0 à L-1
                pixel = im1.getpixel((x,y)) # en stockant le pixel (x,y) dans une liste p à tois éléments
                                    # p[0] est la composante rouge, p[1] la composante verte, et p[2] la composante bleue
                r = pixel[0]
                v = 0  
                b = 0
                im2.putpixel((x,y),(r,v,b)) # on écrit le pixel modifié sur l’image destination
                im1.putpixel((x,y),(r,v,b))
     
     
     
        im2.save(fichierSortie) # on stocke l’image résultante    
        ActualisationDeImage () # On actualise l'image qui se trouve dans le Canvas
     
     
     
    def couleurBleu () :                  
        for y in range(H): # on balaie toutes les lignes de l’image source, de 0 à H-1
            for x in range(L): # pour chaque ligne on balaie toutes les colonnes, de 0 à L-1
                pixel = im1.getpixel((x,y)) # en stockant le pixel (x,y) dans une liste p à tois éléments
                                    # p[0] est la composante rouge, p[1] la composante verte, et p[2] la composante bleue
                r = 0
                v = 0  
                b = pixel[2]
                im2.putpixel((x,y),(r,v,b)) # on écrit le pixel modifié sur l’image destination
                im1.putpixel((x,y),(r,v,b))
     
     
     
        im2.save(fichierSortie) # on stocke l’image résultante
        ActualisationDeImage () # On actualise l'image qui se trouve dans le Canvas
     
     
     
    def luminosite(nouvellevaleur):      
        for y in range (H):
            for x in range (L):
                pixel = im1.getpixel((x, y))
     
                R = pixel[0]+ int(nouvellevaleur)   # On augmente de int(nouvellevaleur) la valeur des pixels Rouge (Valeur comprise entre [0,255])
                V = pixel[1]+ int(nouvellevaleur)   # On augmente de int(nouvellevaleur) la valeur des pixels Vert (Valeur comprise entre [0,255])
                B = pixel[2]+ int(nouvellevaleur)   # On augmente de int(nouvellevaleur) la valeur des pixels Bleu (Valeur comprise entre [0,255])
     
                if R < 0: R = 0         # Comme la valeur doit-être comprise entre [0,255], il faut donc suprimer les valeurs inférieurs à 0 et
                if R > 255: R = 255     # supérieurs à 255
     
                if V < 0: V = 0
                if V > 255: V = 255
     
                if B < 0: B = 0
                if B > 255: B = 255
     
                im2.putpixel ((x,y) ,(R,V,B))
                im1.putpixel((x,y),(R,V,B))
     
     
     
        im2.save(fichierSortie) # on stocke l’image résultante
        ActualisationDeImage ()
     
     
     
     
    def ModifDimensions () :  
     
        Hauteur = eval(Champ1.get())                        #On récupère la valeur de la hauteur saisie par l'utilisateur
        Largeur = eval(Champ2.get())                        #on récupère la valeur de la largeur saisie par l'utilisateur
     
        im2 = im1.resize((Hauteur,Largeur), Image.NEAREST)  # Fonction mathématiques qui permet de récuperer les valeurs données par l'utilisateur
        im2.save(fichierSortie)
        ActualisationDeImage ()                             # On actualise l'image qui se trouve dans le Canvas
     
     
    def Rotation90degresgauche () :   
        global nombrerotation
        nombrerotation = nombrerotation + 1
        im2 = im1.rotate(nombrerotation*90)     # On utilise la fonction "rotate" qui permet la rotation d'une image
        im2.save(fichierSortie)                 # on stocke l’image résultante
        ActualisationDeImage ()                 # On actualise l'image qui se trouve dans le Canvas
     
     
    def Rotation90degresdroite () :  
        global nombrerotation
        nombrerotation = nombrerotation + 1
        im2 = im1.rotate(nombrerotation*(-90))  # On utilise la fonction "rotate" qui permet la rotation d'une image
        im2.save(fichierSortie)                 # on stocke l’image résultante
        ActualisationDeImage ()                 # On actualise l'image qui se trouve dans le Canvas
     
     
     
    #####Création de la Fenêtre #####
     
    #Titre de la fenetre
    fenetre = tk.Tk()       # On met Tk.Tk(), car Tk() est deja utilisé plus bas
    fenetre.title ("Retouche photo")
     
    # Les images qui vont être utilisées doivent-être définies
    fichierEntree = Selector.askopenfilename(filetypes=[('all files','.*'), ('png files','.png')])   # Image d'entrée, qui est a selectionner.
     
    fichierSortie = Selector.asksaveasfilename(title=" POUR SAUVEGARDER, IL FAUT METTRE L'EXTENSION DE L'IMAGE: .PNG, .JPEG, .GIF, ...")
    # Image crée après la sauvegarde. On doit donner le nom et l'endroit où l'image sera sauvegardée.
     
     
     
    # Création d'un widget Canvas (zone graphique)
    Canvas = tk.Canvas(fenetre, width = 1050, height =600, bg ="gray")
    Canvas.pack()
     
    image = Image.open(fichierEntree)   # Le paramètre image représente l'image que l'on veux insérer
     
    photo = ImageTk.PhotoImage(image)   # Avec la fonction ImageTk.PhotoImage (), on peut créer une image compatible Tkinter,
                                        # qu'on pourra afficher dans un Canvas par la méthode create_image(position, **options)
                                        # où position réprésente les 2 coordonnées du coin en haut à gauche de l'image,
                                        # sachant que l'image sera aussi positionnée par rapport au paramètre anchor qui par défaut vaut CENTER. 
     
    Fond = tk.Canvas(fenetre, width = image.size[0], height = image.size[1]) # Le Canvas ne s'adapte pas par défaut à la place que prennent 
                                                                             # les éléments que l'on à dessiner dedans. Donc si l'image que 
                                                                             # l'on veux insére est trop grande, on peut être assuré qu'elle sera
                                                                             # entièrement visible en renseignant les paramètres width et height
                                                                             # à la création du Canvas.
     
     
    Fond.create_image(0, 0, anchor = tk.NW, image=photo)    # Pour que l'image soit positionnée en haut à gauche du Canvas,
                                                            #on doit utiliser la position 0, 0 et rajouter le paramètre anchor = Tk.NW
    Fond.place (x=2, y=2)
     
     
     
    # On definit la Largeur et la Longueur de l'image ainsi que la creation de l'image d'entrée et de sortie
    # Ces valeurs seront utiles pour chaque fonction qui sera appliquée sur l'image par la suite
     
    im1 = Image.open(fichierEntree) # ouverture du fichier image
    L = im1.size[0] # L = largeur de l’image, en pixels
    H = im1.size[1] # H = hauteur de l'image, en pixels
    im2 = Image.new("RGB",(L,H)) # création de l’image destination
    # « vide » pour l’instant
     
     
    ###### Boutons ######
     
    #Création d'un widget Luminosité 
    Luminosite=tk.Label(fenetre, text=" Luminosite ", font="Comic 10")
    Luminosite.place (x=695, y=35)
     
    Valeur = tk.StringVar() # On definit Valeur
    Valeur.set(0)        # On donne la valeur que prendra le curseur au départ
     
        # Création d'un widget Curseur
    echelle = tk.Scale(fenetre,from_=-150,to=250, resolution=25, orient=tk.HORIZONTAL, length=250, width=10, tickinterval=50, variable=Valeur, command=luminosite)
    echelle.place(x=780, y=15)
     
     
     
    # Création d'un widget Couleurs 
    Couleurs=tk.Label(fenetre, text=" Couleurs", font="Comic 10")
    Couleurs.place (x=695, y=103)
     
        # Création d'un widget Button Couleur Cyan 
    BoutonCouleurCyan = tk.Button(fenetre, text ='Cyan', command = couleurCyan, fg='black', bg='cyan', font="Comic 10")
    BoutonCouleurCyan.place(x=764, y=100)
     
        # Création d'un widget Button Couleur Rouge 
    BoutonCouleurRouge = tk.Button(fenetre, text ='Rouge', command = couleurRouge, fg='black', bg='red', font="Comic 10")
    BoutonCouleurRouge.place(x=906, y=100)
     
        # Création d'un widget Button Couleur Bleu 
    BoutonCouleurBleu = tk.Button(fenetre, text ='Bleu', command = couleurBleu, fg='white', bg='blue', font="Comic 10")
    BoutonCouleurBleu.place(x=1011, y=100)
     
     
     
    # Création d'un widget Rotation     
    Rotation45degres=tk.Label(fenetre, text=" Rotation ", font="Comic 10")
    Rotation45degres.place (x=695, y=250)
     
        # Pour la fonction rotation de l'image, il faut definir la valeur que prend le Nombre de Rotation
    nombrerotation = 0 
     
        #Création d'un widget Button Rotation 90° vers la droite  
    photorotationdroite = tk.PhotoImage(file='rotationdroite.gif')
    BoutonRotation90degresdroite = tk.Button(fenetre, image=photorotationdroite, command = Rotation90degresdroite)
    BoutonRotation90degresdroite.place(x=910, y=250)
     
        #Création d'un widget Button Rotation 90° vers la gauche 
    photorotationgauche = tk.PhotoImage(file='rotationgauche.gif')
    BoutonRotation90degresgauche = tk.Button(fenetre, image=photorotationgauche , command = Rotation90degresgauche)
    BoutonRotation90degresgauche.place(x=830, y=250)
     
     
     
    #Création d'un widget Modification des Dimensions   
    ModifDimension=tk.Label(fenetre,text=" Dimensions ", font="Comic 10")
    ModifDimension.place(x=695, y=340)
     
        #Création d'un label Hauteur en pixels  
    hauteurpix = tk.Label(fenetre,text="Hauteur en pixels", font="Comic 9")
    hauteurpix.place(x=795, y=340)
     
        #Création d'un label Largeur en pixels   
    largeurpix=tk.Label(fenetre,text="Largeur en pixels", font="Comic 9")
    largeurpix.place(x=795, y=380)
     
        # Création d'un widget Entry (champ de saisie hauteur de l'image)
    Hauteur = tk.IntVar()
    Champ1 = tk.Entry(fenetre, textvariable= Hauteur)
    Champ1.focus_set()
    Champ1.place(x=925, y=340)
     
        # Création d'un widget Entry (champ de saisie largeur de l'image)
    Largeur = tk.IntVar()
    Champ2 = tk.Entry(fenetre, textvariable= Largeur)
    Champ2.focus_set()
    Champ2.place(x=925, y=380)
     
        # Création d'un widget Button (bouton Valider)
    BoutonValider = tk.Button(fenetre, text ='Valider', command = ModifDimensions, font="Comic 9")
    BoutonValider.place(x=925, y=420)
     
     
     
    # Création d'un widget Button pour afficher un message d'aide
    ButtonMessageAide = tk.Button(fenetre, text = "?", command = MessageAide, font="Comic 14", bg = "blue", fg = "white")
    ButtonMessageAide.place(x=1022, y=563)
     
     
    # Création d'un widget Button pour afficher l'image de depart
    ButtonImageDeDepart = tk.Button(fenetre, text = "Afficher l'image de depart", command = ImageDeDepart, font="Comic 10")
    ButtonImageDeDepart.place(x=692, y=540)
     
     
    # Création d'un widget Button pour afficher la nouvelle image
    BoutonNouvelleImage = tk.Button(fenetre, text ='Afficher la nouvelle image', command=NouvelleImage, font="Comic 10")
    BoutonNouvelleImage.place(x=857, y=540)
     
     
    # Création d'un widget Button (bouton Quitter)
    BoutonQuitter = tk.Button(fenetre, text =' Quitter ', command = fenetre.destroy, font="Comic 9")
    BoutonQuitter.place(x=695, y=480)
     
     
    fenetre.mainloop()  # Permet l'ouverture de la fenetre
    Les images gif que j'ai prises en pj.Nom : rotationdroite.gif
Affichages : 1295
Taille : 1,5 KoNom : rotationgauche.gif
Affichages : 1300
Taille : 1,5 Ko
    Pas d'aide par mp.

  4. #24
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Citation Envoyé par marco056 Voir le message
    Le passage par gif permet peut-être d'éviter le problème précédemment soulevé ?
    .GIF ou .JPEG ou... c'est la représentation de l'image sur disque. Une fois lue en mémoire, on doit se retrouver avec le même nombre de pixels et de couleurs. On ne change pas la "taille" du problème.

    Citation Envoyé par marco056
    J'ai modifié ton programme afin qu'il fonctionne sous python3.
    C'est vrai que c'est étonnant, ce comportement.
    Ce comportement n'a rien d'étonnant: pendant le calcul de la nouvelle image, on gèle les mises à jour du GUI.
    La question est comment arriver à le mettre à jour sans passer par des Threads.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #25
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2016
    Messages : 15
    Points : 1
    Points
    1
    Par défaut
    J'ai essayé en utilisant une image en format .gif. Plus de problème concernant le curseur, cependant, j'obtiens pour tous les filtres ainsi que le changement de luminosité la même erreur :
    [Exception in Tkinter callback
    Traceback (most recent call last):
    File "C:\Python27\lib\lib-tk\Tkinter.py", line 1536, in __call__
    return self.func(*args)
    File "E:\projet final\Programme Final\Retouche photo.py", line 215, in luminosite
    R = pixel[0]+ int(nouvellevaleur) # On augmente de int(nouvellevaleur) la valeur des pixels Rouge (Valeur comprise entre [0,255])
    TypeError: 'int' object has no attribute '__getitem__'


    Il n'y a que les rotations et le changement de taille de l'image qui fonctionnent. Ce sont les seules modifications qui ne touchent pas aux pixels (dans le cas de la taille de l'image, nous n'opérons pas de réelles modifications aux pixels).

    J'ai modifié ton programme afin qu'il fonctionne sous python3.
    Merci beaucoup !
    Cependant je n'utilise pas Python 3 parce que j'ai perdu énormément de temps avec PIL (qui n'est toujours pas installé d'ailleurs), ce qui explique le fait que j'utilise toujours Python 2.7 :/

  6. #26
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 608
    Points : 2 072
    Points
    2 072
    Par défaut
    Grosse amélioration : vire tous tes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    im1.putpixel((x,y),(r,v,b))


    [edit] Souci avec les gif car les pixels récupérés ne sont pas des tuples mais des entiers.

    P.S. Quand tu auras terminé, ton programme m'intéresse...
    Pas d'aide par mp.

  7. #27
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par flolievre Voir le message
    J'ai essayé en utilisant une image en format .gif. Plus de problème concernant le curseur, cependant, j'obtiens pour tous les filtres ainsi que le changement de luminosité la même erreur : /
    Pour toutes les transformations qui modifient les couleurs primaires, il faut convertir (ou avoir converti) la "palette" GIF en RGB via Image.convert:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    from PIL import Image
     
    image = Image.open('toto.gif')
    image = image.convert('RGB')
    Et vu ce qu'est la palette des couleurs d'une Image GIF, c'est le seul moyen d'accéder aux couleurs primaires.

    Pour ce qui est du curseur, sans convert('rgb'), le callback "luminosite" plante rapidement au lieu de durer plusieurs secondes: le rafraichissement n'est pas gelé.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #28
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 608
    Points : 2 072
    Points
    2 072
    Par défaut
    Je pense parler du même souci de callback "luminosité" :
    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
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    # -*- coding: cp1252 -*-
     
    ##### Import #####
    import tkinter as tk
    import tkinter.filedialog as Selector # Module permettant de selectionner l'image que l'on veut
    import webbrowser               # webbrowser permet l'ouverture de l'image avec la visionneuse de photos Windows
    import PIL
    from PIL import Image, ImageTk
    from tkinter.messagebox import *      # Permet l'ouverture de boîtes de dialogue standard pour l’affichage de messages
     
    fichierEntree = 'lena.gif'
    image = Image.open(fichierEntree)
    #image=image.convert('RGB')
    fichierSortie = 'lena2.jpg'
     
    ##### Fonctions #####
     
    def ActualisationDeImage () :
        Fond.destroy()                              # On detruit l'ancienne image
     
        NouvelleImage = Image.open(fichierSortie)   # Le paramètre image représente l'image que l'on veux insérer
     
        NouvellePhoto = ImageTk.PhotoImage(NouvelleImage)   # Avec la fonction ImageTk.PhotoImage (), on peut créer une image compatible Tkinter,
                                                            # qu'on pourra afficher dans un Canvas par la méthode create_image(position, **options)
                                                            # où position réprésente les 2 coordonnées du coin en haut à gauche de l'image,
                                                            # sachant que l'image sera aussi positionnée par rapport au paramètre anchor
                                                            # qui par défaut vaut CENTER. 
     
        NouveauFond = tk.Canvas(fenetre, width = NouvelleImage.size[0], height = NouvelleImage.size[1])
     
                                                            # Le Canvas ne s'adapte pas par défaut à la place que prennent 
                                                            # les éléments que l'on à dessiner dedans. Donc si l'image que 
                                                            # l'on veux insére est trop grande, on peut être assuré qu'elle sera
                                                            # entièrement visible en renseignant les paramètres width et height à la création du Canvas.
     
        NouveauFond.create_image(0, 0, anchor = tk.NW, image=NouvellePhoto)  # Pour que l'image soit positionnée en haut à gauche du Canvas,
                                                                             # on doit utiliser la position 0, 0 et rajouter le paramètre anchor = Tk.NW
        NouveauFond.place (x=2, y=2) # On place le Nouveau Fond
        NouveauFond.mainloop()       # On ouvre la Nouvelle Image
     
     
     
     
    def NouvelleImage () :       
        webbrowser.open(fichierSortie)
     
     
    def ImageDeDepart () :       
        webbrowser.open(fichierEntree)
     
     
    def MessageAide () :
        showinfo(' AIDE ' , "Les boutons couleurs permettent de changer la couleur de l'image. Les boutons filtres appliquent des filtres sur la photo. \
    Par exemple, le bouton niveau de gis, change l'image en niveau de gris. Le bouton posterise permet de transformer l'image en une peinture. \
    Le seuillage permet de reduire les couleurs de l'image en seulement deux couleurs, le noir et le blanc. Le négatif, permet d'inverser \
    les couleurs de l'image. Ensuite, les boutons de redimenssionnement permettent de redimanssionner l'image. Les boutons de deplacement de l'image \
    font tourner l'image sur elle-même et dans différentes positions (90 - 180 - 270 degrés).")
     
     
     
    def couleurCyan () :                # Martin  
        for y in range(H): # on balaie toutes les lignes de l’image source, de 0 à H-1
            for x in range(L): # pour chaque ligne on balaie toutes les colonnes, de 0 à L-1
                pixel = image.getpixel((x,y)) # en stockant le pixel (x,y) dans une liste p à tois éléments
                                    # p[0] est la composante rouge, p[1] la composante verte, et p[2] la composante bleue
                r = 0
                v = pixel[1]  
                b = pixel[2]
                im2.putpixel((x,y),(r,v,b)) # on écrit le pixel modifié sur l’image destination
     
        im2.save(fichierSortie) # on stocke l’image résultante
        ActualisationDeImage () # On actualise l'image qui se trouve dans le Canvas
     
     
     
    def couleurRouge () :             # Martin  
        for y in range(H): # on balaie toutes les lignes de l’image source, de 0 à H-1
            for x in range(L): # pour chaque ligne on balaie toutes les colonnes, de 0 à L-1
                pixel = image.getpixel((x,y)) # en stockant le pixel (x,y) dans une liste p à tois éléments
                                    # p[0] est la composante rouge, p[1] la composante verte, et p[2] la composante bleue
                r = pixel[0]
                v = 0  
                b = 0
                im2.putpixel((x,y),(r,v,b)) # on écrit le pixel modifié sur l’image destination
     
        im2.save(fichierSortie) # on stocke l’image résultante    
        ActualisationDeImage () # On actualise l'image qui se trouve dans le Canvas
     
     
     
    def couleurBleu () :                  
        for y in range(H): # on balaie toutes les lignes de l’image source, de 0 à H-1
            for x in range(L): # pour chaque ligne on balaie toutes les colonnes, de 0 à L-1
                pixel = image.getpixel((x,y)) # en stockant le pixel (x,y) dans une liste p à tois éléments
                                    # p[0] est la composante rouge, p[1] la composante verte, et p[2] la composante bleue
                r = 0
                v = 0  
                b = pixel[2]
                im2.putpixel((x,y),(r,v,b)) # on écrit le pixel modifié sur l’image destination
     
        im2.save(fichierSortie) # on stocke l’image résultante
        ActualisationDeImage () # On actualise l'image qui se trouve dans le Canvas
     
     
     
    def luminosite(nouvellevaleur):      
        for y in range (H):
            for x in range (L):
                pixel = image.getpixel((x, y))
     
                r = pixel[0]+ int(nouvellevaleur)   # On augmente de int(nouvellevaleur) la valeur des pixels Rouge (Valeur comprise entre [0,255])
                v = pixel[1]+ int(nouvellevaleur)   # On augmente de int(nouvellevaleur) la valeur des pixels Vert (Valeur comprise entre [0,255])
                b = pixel[2]+ int(nouvellevaleur)   # On augmente de int(nouvellevaleur) la valeur des pixels Bleu (Valeur comprise entre [0,255])
     
                if r < 0: r = 0         # Comme la valeur doit-être comprise entre [0,255], il faut donc suprimer les valeurs inférieurs à 0 et
                if r > 255: r = 255     # supérieurs à 255
     
                if v < 0: v = 0
                if v > 255: v = 255
     
                if b < 0: b = 0
                if b > 255: b = 255
     
                im2.putpixel ((x,y) ,(r,v,b))
     
        im2.save(fichierSortie) # on stocke l’image résultante
        ActualisationDeImage ()
     
     
    def ModifDimensions () :  
     
        Hauteur = eval(Champ1.get())                        #On récupère la valeur de la hauteur saisie par l'utilisateur
        Largeur = eval(Champ2.get())                        #on récupère la valeur de la largeur saisie par l'utilisateur
     
        im2 = image.resize((Hauteur,Largeur), Image.NEAREST)  # Fonction mathématiques qui permet de récuperer les valeurs données par l'utilisateur
        im2.save(fichierSortie)
        ActualisationDeImage ()                             # On actualise l'image qui se trouve dans le Canvas
     
     
    def Rotation90degresgauche () :   
        global nombrerotation
        nombrerotation = nombrerotation + 1
        im2 = image.rotate(nombrerotation*90)     # On utilise la fonction "rotate" qui permet la rotation d'une image
        im2.save(fichierSortie)                 # on stocke l’image résultante
        ActualisationDeImage ()                 # On actualise l'image qui se trouve dans le Canvas
     
     
    def Rotation90degresdroite () :  
        global nombrerotation
        nombrerotation = nombrerotation + 1
        im2 = image.rotate(nombrerotation*(-90))  # On utilise la fonction "rotate" qui permet la rotation d'une image
        im2.save(fichierSortie)                 # on stocke l’image résultante
        ActualisationDeImage ()                 # On actualise l'image qui se trouve dans le Canvas
     
     
    #####Création de la Fenêtre #####
     
    #Titre de la fenetre
    fenetre = tk.Tk()       # On met Tk.Tk(), car Tk() est deja utilisé plus bas
    fenetre.title ("Retouche photo")
     
    ## Les images qui vont être utilisées doivent-être définies
    #fichierEntree = Selector.askopenfilename(filetypes=[('all files','.*'), ('png files','.png')])   # Image d'entrée, qui est a selectionner.
    # 
    #fichierSortie = Selector.asksaveasfilename(title=" POUR SAUVEGARDER, IL FAUT METTRE L'EXTENSION DE L'IMAGE: .PNG, .JPEG, .GIF, ...")
    ## Image crée après la sauvegarde. On doit donner le nom et l'endroit où l'image sera sauvegardée.
    # 
    # 
     
    # Création d'un widget Canvas (zone graphique)
    Canvas = tk.Canvas(fenetre, width = 1200, height =600, bg ="gray")
    Canvas.pack()
     
    #image = Image.open(fichierEntree)   # Le paramètre image représente l'image que l'on veux insérer
     
    photo = ImageTk.PhotoImage(image)   # Avec la fonction ImageTk.PhotoImage (), on peut créer une image compatible Tkinter,
                                        # qu'on pourra afficher dans un Canvas par la méthode create_image(position, **options)
                                        # où position réprésente les 2 coordonnées du coin en haut à gauche de l'image,
                                        # sachant que l'image sera aussi positionnée par rapport au paramètre anchor qui par défaut vaut CENTER. 
     
    Fond = tk.Canvas(fenetre, width = image.size[0], height = image.size[1]) # Le Canvas ne s'adapte pas par défaut à la place que prennent 
                                                                             # les éléments que l'on à dessiner dedans. Donc si l'image que 
                                                                             # l'on veux insére est trop grande, on peut être assuré qu'elle sera
                                                                             # entièrement visible en renseignant les paramètres width et height
                                                                             # à la création du Canvas.
    Fond.create_image(0, 0, anchor = tk.NW, image=photo)    # Pour que l'image soit positionnée en haut à gauche du Canvas,
                                                            #on doit utiliser la position 0, 0 et rajouter le paramètre anchor = Tk.NW
    Fond.place (x=2, y=2)
     
     
     
    # On definit la Largeur et la Longueur de l'image ainsi que la creation de l'image d'entrée et de sortie
    # Ces valeurs seront utiles pour chaque fonction qui sera appliquée sur l'image par la suite
     
    L = image.size[0] # L = largeur de l’image, en pixels
    H = image.size[1] # H = hauteur de l'image, en pixels
    im2 = Image.new("RGB",(L,H)) # création de l’image destination
    # « vide » pour l’instant
     
     
    ###### Boutons ######
     
    def val(lum):
        lab.configure(text='Valeur actuelle = ' + str(lum))
        luminosite(lum)
     
     
    lab = tk.Label(fenetre)
    lab.place (x=880, y=80)
     
    #Création d'un widget Luminosité
    Lumin=tk.Label(fenetre, text=" Luminosité ", font="Comic 10")
    Lumin.place (x=595, y=35)
     
    Valeur = tk.StringVar() # On definit Valeur
    Valeur.set(0)        # On donne la valeur que prendra le curseur au départ
     
    # Création d'un widget Curseur
    echelle = tk.Scale(fenetre,length=400, orient=tk.HORIZONTAL, label = 'Réglage de la luminosité', troughcolor ='dark grey', \
    sliderlength =20, showvalue =0,from_=-200,to=200, resolution=40, tickinterval=50, variable=Valeur, command=val) # width=10
    echelle.place(x=750, y=15)
     
     
    # Création d'un widget Couleurs 
    Couleurs=tk.Label(fenetre, text=" Couleurs", font="Comic 10")
    Couleurs.place (x=600, y=133)
     
        # Création d'un widget Button Couleur Cyan 
    BoutonCouleurCyan = tk.Button(fenetre, text ='Cyan', command = couleurCyan, fg='black', bg='cyan', font="Comic 10")
    BoutonCouleurCyan.place(x=750, y=130)
     
        # Création d'un widget Button Couleur Rouge 
    BoutonCouleurRouge = tk.Button(fenetre, text ='Rouge', command = couleurRouge, fg='black', bg='red', font="Comic 10")
    BoutonCouleurRouge.place(x=850, y=130)
     
        # Création d'un widget Button Couleur Bleu 
    BoutonCouleurBleu = tk.Button(fenetre, text ='Bleu', command = couleurBleu, fg='white', bg='blue', font="Comic 10")
    BoutonCouleurBleu.place(x=950, y=130)
     
     
     
    # Création d'un widget Rotation     
    Rotation45degres=tk.Label(fenetre, text=" Rotation ", font="Comic 10")
    Rotation45degres.place (x=600, y=250)
     
        # Pour la fonction rotation de l'image, il faut definir la valeur que prend le Nombre de Rotation
    nombrerotation = 0 
     
        #Création d'un widget Button Rotation 90° vers la droite  
    photorotationdroite = tk.PhotoImage(file='rotationdroite.gif')
    BoutonRotation90degresdroite = tk.Button(fenetre, image=photorotationdroite, command = Rotation90degresdroite)
    BoutonRotation90degresdroite.place(x=910, y=250)
     
        #Création d'un widget Button Rotation 90° vers la gauche 
    photorotationgauche = tk.PhotoImage(file='rotationgauche.gif')
    BoutonRotation90degresgauche = tk.Button(fenetre, image=photorotationgauche , command = Rotation90degresgauche)
    BoutonRotation90degresgauche.place(x=830, y=250)
     
     
     
    #Création d'un widget Modification des Dimensions   
    ModifDimension=tk.Label(fenetre,text=" Dimensions ", font="Comic 10")
    ModifDimension.place(x=600, y=340)
     
        #Création d'un label Hauteur en pixels  
    hauteurpix = tk.Label(fenetre,text="Hauteur en pixels", font="Comic 9")
    hauteurpix.place(x=750, y=340)
     
        #Création d'un label Largeur en pixels   
    largeurpix=tk.Label(fenetre,text="Largeur en pixels", font="Comic 9")
    largeurpix.place(x=750, y=380)
     
        # Création d'un widget Entry (champ de saisie hauteur de l'image)
    Hauteur = tk.IntVar()
    Champ1 = tk.Entry(fenetre, textvariable= Hauteur)
    Champ1.focus_set()
    Champ1.place(x=875, y=340)
     
        # Création d'un widget Entry (champ de saisie largeur de l'image)
    Largeur = tk.IntVar()
    Champ2 = tk.Entry(fenetre, textvariable= Largeur)
    Champ2.focus_set()
    Champ2.place(x=875, y=380)
     
        # Création d'un widget Button (bouton Valider)
    BoutonValider = tk.Button(fenetre, text ='Valider', command = ModifDimensions, font="Comic 9")
    BoutonValider.place(x=925, y=420)
     
     
     
    # Création d'un widget Button pour afficher un message d'aide
    ButtonMessageAide = tk.Button(fenetre, text = "?", command = MessageAide, font="Comic 14", bg = "blue", fg = "white")
    ButtonMessageAide.place(x=1022, y=550)
     
     
    # Création d'un widget Button pour afficher l'image de depart
    ButtonImageDeDepart = tk.Button(fenetre, text = "Afficher l'image de depart", command = ImageDeDepart, font="Comic 10")
    ButtonImageDeDepart.place(x=600, y=500)
     
     
    # Création d'un widget Button pour afficher la nouvelle image
    BoutonNouvelleImage = tk.Button(fenetre, text ='Afficher la nouvelle image', command=NouvelleImage, font="Comic 10")
    BoutonNouvelleImage.place(x=857, y=500)
     
     
    # Création d'un widget Button (bouton Quitter)
    BoutonQuitter = tk.Button(fenetre, text =' Quitter ', command = fenetre.destroy, font="Comic 9")
    BoutonQuitter.place(x=600, y=550)
     
     
    fenetre.mainloop()  # Permet l'ouverture de la fenetre
    Avec une image en "jpg", pas de curseur, alors qu'avec une image "gif", le curseur est bien présent.
    De la même façon, si j'ôte la ligne luminosite à la ligne 205, le curseur revient, quelle que soit le format d'image.
    Je ne comprends pas ce comportement.
    Pas d'aide par mp.

  9. #29
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2016
    Messages : 15
    Points : 1
    Points
    1
    Par défaut
    Pour ce qui est du code qui suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    im1.putpixel((x,y),(r,v,b))
    Ce code est important puisqu'il permet d'additionner les modifications afin que l'on ai pas à lancer plusieurs fois le programme pour appliquer plusieurs modifications ^^'
    De plus, même en l'enlevant, aucune différence que ce soit pour les .gif ou pour les .jpg


    Concernant la conversion, cela ne permet pas de résoudre le problème avec les images en .gif ...
    J'imagine, et ce n'est qu'une supposition, que cela vient du 'RGB' (différent du rvb que j'utilise). J'ai quand même essayé en renommant la variable v en g, aucune différence. L'erreur persiste :/

  10. #30
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 608
    Points : 2 072
    Points
    2 072
    Par défaut
    Tout fonctionne chez moi (à part le curseur) lorsque je change à la ligne 11 "gif" par "jpg".
    Pas d'aide par mp.

  11. #31
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 608
    Points : 2 072
    Points
    2 072
    Par défaut
    Citation Envoyé par flolievre Voir le message
    Pour ce qui est du code qui suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    im1.putpixel((x,y),(r,v,b))
    Ce code est important puisqu'il permet d'additionner les modifications afin que l'on ai pas à lancer plusieurs fois le programme pour appliquer plusieurs modifications ^^'
    De plus, même en l'enlevant, aucune différence que ce soit pour les .gif ou pour les .jpg


    Concernant la conversion, cela ne permet pas de résoudre le problème avec les images en .gif ...
    J'imagine, et ce n'est qu'une supposition, que cela vient du 'RGB' (différent du rvb que j'utilise). J'ai quand même essayé en renommant la variable v en g, aucune différence. L'erreur persiste :/

    Si tu gardes im1, tu écrases ton image originelle. Cela devient noir, dès le deuxième traitement.
    Pas d'aide par mp.

  12. #32
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par marco056 Voir le message
    Avec une image en "jpg", pas de curseur, alors qu'avec une image "gif", le curseur est bien présent.
    De la même façon, si j'ôte la ligne luminosite à la ligne 205, le curseur revient, quelle que soit le format d'image.
    Je ne comprends pas ce comportement.
    Pour comprendre ce comportement, il suffit de mesurer le temps mis par le callback.
    Les réalités physiques sont têtues et ce n'est pas les "bonnes intentions" qui vont les changer.

    Citation Envoyé par flolievre Voir le message
    Concernant la conversion, cela ne permet pas de résoudre le problème avec les images en .gif ...
    J'imagine, et ce n'est qu'une supposition, que cela vient du 'RGB' (différent du rvb que j'utilise). J'ai quand même essayé en renommant la variable v en g, aucune différence. L'erreur persiste :/
    Quand je vous dit que changer le format des images ne vous servira à rien.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  13. #33
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2016
    Messages : 15
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par marco056 Voir le message
    Si tu gardes im1, tu écrases ton image originelle. Cela devient noir, dès le deuxième traitement.
    Dans mon cas, j'apporte les modifications sur im1 et im2. Cependant, vu que je ne sauvegarde que im2, l'image d'origine (im1) reste intacte.
    De plus, l'image devient noir uniquement dans certains cas. Si par exemple on applique le filtre bleu puis le rouge, l'image devient bleu.
    Mais si on applique le filtre cyan puis le jaune, cela devient vert.


    Pour revenir au curseur, étant donné que le problème persiste, rien ne m'empêche de revenir à un système plus simple comme celui de la modification des dimensions, et donc de demander à l'utilisateur de simplement de rentrer le nombre qu'il souhaite au clavier et non via un curseur.

  14. #34
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par flolievre Voir le message
    Pour revenir au curseur, étant donné que le problème persiste, rien ne m'empêche de revenir à un système plus simple comme celui de la modification des dimensions, et donc de demander à l'utilisateur de simplement de rentrer le nombre qu'il souhaite au clavier et non via un curseur.
    Si on veut seulement voir le widget Scale s'afficher correctement (le reste inchangé), le plus simple serait de "sauter" les calculs faits lorsque luminosite est appelé la première fois (ils ne servent à rien puisque la valeur passée est 0).
    Avec un flag comme init_done ci-dessous:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    init_done = False
     
    def luminosite(value):
        global init_done
     
        if not init_done:
            init_done = True
            return
     
        ... le code original....
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  15. #35
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2016
    Messages : 15
    Points : 1
    Points
    1
    Par défaut
    En effet, avec ce code le curseur se lance normalement.
    Cependant, le curseur ne se déplace pas, la luminosité augmente ou diminue si on appuie sur la ligne mais le curseur reste intacte.
    Ce qui est déjà une avancée en soi, merci

  16. #36
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par flolievre Voir le message
    En effet, avec ce code le curseur se lance normalement.
    Cependant, le curseur ne se déplace pas, la luminosité augmente ou diminue si on appuie sur la ligne mais le curseur reste intacte.
    Ce qui est déjà une avancée en soi, merci
    Chaque fois que vous bougez le curseur, çà bloque le GUI pendant plusieurs secondes: vous ne voyez son déplacement qu'après.
    init_done permet juste une affichage correct (la première fois).
    Normalement, on déporte les calculs dans un Thread et on affiche une progressbar.
    Sans passez par la votre seule option est de travailler sur des images plus petites.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  17. #37
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 608
    Points : 2 072
    Points
    2 072
    Par défaut
    Je préfère créer une autre image pour la retouche :
    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
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    # -*- coding: cp1252 -*-
     
    ##### Import #####
    import tkinter as tk
    import tkinter.filedialog as Selector # Module permettant de selectionner l'image que l'on veut
    import webbrowser               # webbrowser permet l'ouverture de l'image avec la visionneuse de photos Windows
    import PIL
    from PIL import Image, ImageTk
    from tkinter.messagebox import *      # Permet l'ouverture de boîtes de dialogue standard pour l’affichage de messages
     
    fichierEntree = 'lena.jpg'
    image = Image.open(fichierEntree)
    # ou bien :
    #fichierEntree = 'lena.gif'
    #image = Image.open(fichierEntree)
    #image=image.convert('RGB')
     
    fichierSortie = 'lena2.jpg'
     
    ##### Fonctions #####
     
    def ActualisationDeImage () :
    #    Fond.destroy()                              # On detruit l'ancienne image
     
        NouvelleImage = Image.open(fichierSortie)   # Le paramètre image représente l'image que l'on veux insérer
     
        NouvellePhoto = ImageTk.PhotoImage(NouvelleImage)   # Avec la fonction ImageTk.PhotoImage (), on peut créer une image compatible Tkinter,
                                                            # qu'on pourra afficher dans un Canvas par la méthode create_image(position, **options)
                                                            # où position réprésente les 2 coordonnées du coin en haut à gauche de l'image,
                                                            # sachant que l'image sera aussi positionnée par rapport au paramètre anchor
                                                            # qui par défaut vaut CENTER. 
     
        NouveauFond = tk.Canvas(fenetre, width = NouvelleImage.size[0], height = NouvelleImage.size[1])
     
                                                            # Le Canvas ne s'adapte pas par défaut à la place que prennent 
                                                            # les éléments que l'on à dessiner dedans. Donc si l'image que 
                                                            # l'on veux insére est trop grande, on peut être assuré qu'elle sera
                                                            # entièrement visible en renseignant les paramètres width et height à la création du Canvas.
     
        NouveauFond.create_image(0, 0, anchor = tk.NW, image=NouvellePhoto)  # Pour que l'image soit positionnée en haut à gauche du Canvas,
                                                                             # on doit utiliser la position 0, 0 et rajouter le paramètre anchor = Tk.NW
        NouveauFond.place (x=250, y=2) # On place le Nouveau Fond
        NouveauFond.mainloop()       # On ouvre la Nouvelle Image
     
     
     
     
    def NouvelleImage () :       
        webbrowser.open(fichierSortie)
     
     
    def ImageDeDepart () :       
        webbrowser.open(fichierEntree)
     
     
    def MessageAide () :
        showinfo(' AIDE ' , "Les boutons couleurs permettent de changer la couleur de l'image. Les boutons filtres appliquent des filtres sur la photo. \
    Par exemple, le bouton niveau de gis, change l'image en niveau de gris. Le bouton posterise permet de transformer l'image en une peinture. \
    Le seuillage permet de reduire les couleurs de l'image en seulement deux couleurs, le noir et le blanc. Le négatif, permet d'inverser \
    les couleurs de l'image. Ensuite, les boutons de redimenssionnement permettent de redimanssionner l'image. Les boutons de deplacement de l'image \
    font tourner l'image sur elle-même et dans différentes positions (90 - 180 - 270 degrés).")
     
     
     
    def couleurCyan () :                # Martin  
        for y in range(H): # on balaie toutes les lignes de l’image source, de 0 à H-1
            for x in range(L): # pour chaque ligne on balaie toutes les colonnes, de 0 à L-1
                pixel = image.getpixel((x,y)) # en stockant le pixel (x,y) dans une liste p à tois éléments
                                    # p[0] est la composante rouge, p[1] la composante verte, et p[2] la composante bleue
                r = 0
                v = pixel[1]  
                b = pixel[2]
                im2.putpixel((x,y),(r,v,b)) # on écrit le pixel modifié sur l’image destination
     
        im2.save(fichierSortie) # on stocke l’image résultante
        ActualisationDeImage () # On actualise l'image qui se trouve dans le Canvas
     
     
     
    def couleurRouge () :             # Martin  
        for y in range(H): # on balaie toutes les lignes de l’image source, de 0 à H-1
            for x in range(L): # pour chaque ligne on balaie toutes les colonnes, de 0 à L-1
                pixel = image.getpixel((x,y)) # en stockant le pixel (x,y) dans une liste p à tois éléments
                                    # p[0] est la composante rouge, p[1] la composante verte, et p[2] la composante bleue
                r = pixel[0]
                v = 0  
                b = 0
                im2.putpixel((x,y),(r,v,b)) # on écrit le pixel modifié sur l’image destination
     
        im2.save(fichierSortie) # on stocke l’image résultante    
        ActualisationDeImage () # On actualise l'image qui se trouve dans le Canvas
     
     
     
    def couleurBleu () :                  
        for y in range(H): # on balaie toutes les lignes de l’image source, de 0 à H-1
            for x in range(L): # pour chaque ligne on balaie toutes les colonnes, de 0 à L-1
                pixel = image.getpixel((x,y)) # en stockant le pixel (x,y) dans une liste p à tois éléments
                                    # p[0] est la composante rouge, p[1] la composante verte, et p[2] la composante bleue
                r = 0
                v = 0  
                b = pixel[2]
                im2.putpixel((x,y),(r,v,b)) # on écrit le pixel modifié sur l’image destination
     
        im2.save(fichierSortie) # on stocke l’image résultante
        ActualisationDeImage () # On actualise l'image qui se trouve dans le Canvas
     
     
    init_done = False
     
    def luminosite(nouvellevaleur):
        global init_done
     
        if not init_done:
            init_done = True
            return   
        for y in range (H):
            for x in range (L):
                pixel = image.getpixel((x, y))
     
                r = pixel[0]+ int(nouvellevaleur)   # On augmente de int(nouvellevaleur) la valeur des pixels Rouge (Valeur comprise entre [0,255])
                v = pixel[1]+ int(nouvellevaleur)   # On augmente de int(nouvellevaleur) la valeur des pixels Vert (Valeur comprise entre [0,255])
                b = pixel[2]+ int(nouvellevaleur)   # On augmente de int(nouvellevaleur) la valeur des pixels Bleu (Valeur comprise entre [0,255])
     
                if r < 0: r = 0         # Comme la valeur doit-être comprise entre [0,255], il faut donc suprimer les valeurs inférieurs à 0 et
                if r > 255: r = 255     # supérieurs à 255
     
                if v < 0: v = 0
                if v > 255: v = 255
     
                if b < 0: b = 0
                if b > 255: b = 255
     
                im2.putpixel ((x,y) ,(r,v,b))
     
        im2.save(fichierSortie) # on stocke l’image résultante
        ActualisationDeImage ()
     
     
    def ModifDimensions () :  
     
        Hauteur = eval(Champ1.get())                        #On récupère la valeur de la hauteur saisie par l'utilisateur
        Largeur = eval(Champ2.get())                        #on récupère la valeur de la largeur saisie par l'utilisateur
     
        im2 = image.resize((Hauteur,Largeur), Image.NEAREST)  # Fonction mathématiques qui permet de récuperer les valeurs données par l'utilisateur
        im2.save(fichierSortie)
        ActualisationDeImage ()                             # On actualise l'image qui se trouve dans le Canvas
     
     
    def Rotation90degresgauche () :   
        global nombrerotation
        nombrerotation = nombrerotation + 1
        im2 = image.rotate(nombrerotation*90)     # On utilise la fonction "rotate" qui permet la rotation d'une image
        im2.save(fichierSortie)                 # on stocke l’image résultante
        ActualisationDeImage ()                 # On actualise l'image qui se trouve dans le Canvas
     
     
    def Rotation90degresdroite () :  
        global nombrerotation
        nombrerotation = nombrerotation + 1
        im2 = image.rotate(nombrerotation*(-90))  # On utilise la fonction "rotate" qui permet la rotation d'une image
        im2.save(fichierSortie)                 # on stocke l’image résultante
        ActualisationDeImage ()                 # On actualise l'image qui se trouve dans le Canvas
     
     
    #####Création de la Fenêtre #####
     
    #Titre de la fenetre
    fenetre = tk.Tk()       # On met Tk.Tk(), car Tk() est deja utilisé plus bas
    fenetre.title ("Retouche photo")
     
    ## Les images qui vont être utilisées doivent-être définies
    #fichierEntree = Selector.askopenfilename(filetypes=[('all files','.*'), ('png files','.png')])   # Image d'entrée, qui est a selectionner.
    # 
    #fichierSortie = Selector.asksaveasfilename(title=" POUR SAUVEGARDER, IL FAUT METTRE L'EXTENSION DE L'IMAGE: .PNG, .JPEG, .GIF, ...")
    ## Image crée après la sauvegarde. On doit donner le nom et l'endroit où l'image sera sauvegardée.
    # 
    # 
     
    # Création d'un widget Canvas (zone graphique)
    Canvas = tk.Canvas(fenetre, width = 1200, height =600, bg ="gray")
    Canvas.pack()
     
    #image = Image.open(fichierEntree)   # Le paramètre image représente l'image que l'on veux insérer
     
    photo = ImageTk.PhotoImage(image)   # Avec la fonction ImageTk.PhotoImage (), on peut créer une image compatible Tkinter,
                                        # qu'on pourra afficher dans un Canvas par la méthode create_image(position, **options)
                                        # où position réprésente les 2 coordonnées du coin en haut à gauche de l'image,
                                        # sachant que l'image sera aussi positionnée par rapport au paramètre anchor qui par défaut vaut CENTER. 
     
    Fond = tk.Canvas(fenetre, width = image.size[0], height = image.size[1]) # Le Canvas ne s'adapte pas par défaut à la place que prennent 
                                                                             # les éléments que l'on à dessiner dedans. Donc si l'image que 
                                                                             # l'on veux insére est trop grande, on peut être assuré qu'elle sera
                                                                             # entièrement visible en renseignant les paramètres width et height
                                                                             # à la création du Canvas.
    Fond.create_image(0, 0, anchor = tk.NW, image=photo)    # Pour que l'image soit positionnée en haut à gauche du Canvas,
                                                            #on doit utiliser la position 0, 0 et rajouter le paramètre anchor = Tk.NW
    Fond.place (x=2, y=2)
     
     
     
    # On definit la Largeur et la Longueur de l'image ainsi que la creation de l'image d'entrée et de sortie
    # Ces valeurs seront utiles pour chaque fonction qui sera appliquée sur l'image par la suite
     
    L = image.size[0] # L = largeur de l’image, en pixels
    H = image.size[1] # H = hauteur de l'image, en pixels
    im2 = Image.new("RGB",(L,H)) # création de l’image destination
    # « vide » pour l’instant
     
     
    ###### Boutons ######
     
    def val(lum):
        lab.configure(text='Valeur actuelle = ' + str(lum))
        luminosite(lum)
     
     
    lab = tk.Label(fenetre)
    lab.place (x=880, y=80)
     
    #Création d'un widget Luminosité
    Lumin=tk.Label(fenetre, text=" Luminosité ", font="Comic 10")
    Lumin.place (x=595, y=35)
     
    Valeur = tk.StringVar() # On definit Valeur
    Valeur.set(0)        # On donne la valeur que prendra le curseur au départ
     
    # Création d'un widget Curseur
    echelle = tk.Scale(fenetre,length=400, orient=tk.HORIZONTAL, label = 'Réglage de la luminosité', troughcolor ='yellow', \
    sliderlength =20, showvalue =0,from_=-200,to=200, resolution=40, tickinterval=50, variable=Valeur, command=val) # width=10
    echelle.place(x=750, y=15)
     
     
    # Création d'un widget Couleurs 
    Couleurs=tk.Label(fenetre, text=" Couleurs", font="Comic 10")
    Couleurs.place (x=600, y=133)
     
        # Création d'un widget Button Couleur Cyan 
    BoutonCouleurCyan = tk.Button(fenetre, text ='Cyan', command = couleurCyan, fg='black', bg='cyan', font="Comic 10")
    BoutonCouleurCyan.place(x=750, y=130)
     
        # Création d'un widget Button Couleur Rouge 
    BoutonCouleurRouge = tk.Button(fenetre, text ='Rouge', command = couleurRouge, fg='black', bg='red', font="Comic 10")
    BoutonCouleurRouge.place(x=850, y=130)
     
        # Création d'un widget Button Couleur Bleu 
    BoutonCouleurBleu = tk.Button(fenetre, text ='Bleu', command = couleurBleu, fg='white', bg='blue', font="Comic 10")
    BoutonCouleurBleu.place(x=950, y=130)
     
     
     
    # Création d'un widget Rotation     
    Rotation45degres=tk.Label(fenetre, text=" Rotation ", font="Comic 10")
    Rotation45degres.place (x=600, y=250)
     
        # Pour la fonction rotation de l'image, il faut definir la valeur que prend le Nombre de Rotation
    nombrerotation = 0 
     
        #Création d'un widget Button Rotation 90° vers la droite  
    photorotationdroite = tk.PhotoImage(file='rotationdroite.gif')
    BoutonRotation90degresdroite = tk.Button(fenetre, image=photorotationdroite, command = Rotation90degresdroite)
    BoutonRotation90degresdroite.place(x=910, y=250)
     
        #Création d'un widget Button Rotation 90° vers la gauche 
    photorotationgauche = tk.PhotoImage(file='rotationgauche.gif')
    BoutonRotation90degresgauche = tk.Button(fenetre, image=photorotationgauche , command = Rotation90degresgauche)
    BoutonRotation90degresgauche.place(x=830, y=250)
     
     
     
    #Création d'un widget Modification des Dimensions   
    ModifDimension=tk.Label(fenetre,text=" Dimensions ", font="Comic 10")
    ModifDimension.place(x=600, y=340)
     
        #Création d'un label Hauteur en pixels  
    hauteurpix = tk.Label(fenetre,text="Hauteur en pixels", font="Comic 9")
    hauteurpix.place(x=750, y=340)
     
        #Création d'un label Largeur en pixels   
    largeurpix=tk.Label(fenetre,text="Largeur en pixels", font="Comic 9")
    largeurpix.place(x=750, y=380)
     
        # Création d'un widget Entry (champ de saisie hauteur de l'image)
    Hauteur = tk.IntVar()
    Champ1 = tk.Entry(fenetre, textvariable= Hauteur)
    Champ1.focus_set()
    Champ1.place(x=875, y=340)
     
        # Création d'un widget Entry (champ de saisie largeur de l'image)
    Largeur = tk.IntVar()
    Champ2 = tk.Entry(fenetre, textvariable= Largeur)
    Champ2.focus_set()
    Champ2.place(x=875, y=380)
     
        # Création d'un widget Button (bouton Valider)
    BoutonValider = tk.Button(fenetre, text ='Valider', command = ModifDimensions, font="Comic 9")
    BoutonValider.place(x=925, y=420)
     
     
     
    # Création d'un widget Button pour afficher un message d'aide
    ButtonMessageAide = tk.Button(fenetre, text = "?", command = MessageAide, font="Comic 14", bg = "blue", fg = "white")
    ButtonMessageAide.place(x=1022, y=550)
     
     
    # Création d'un widget Button pour afficher l'image de depart
    ButtonImageDeDepart = tk.Button(fenetre, text = "Afficher l'image de depart", command = ImageDeDepart, font="Comic 10")
    ButtonImageDeDepart.place(x=600, y=500)
     
     
    # Création d'un widget Button pour afficher la nouvelle image
    BoutonNouvelleImage = tk.Button(fenetre, text ='Afficher la nouvelle image', command=NouvelleImage, font="Comic 10")
    BoutonNouvelleImage.place(x=857, y=500)
     
     
    # Création d'un widget Button (bouton Quitter)
    BoutonQuitter = tk.Button(fenetre, text =' Quitter ', command = fenetre.destroy, font="Comic 9")
    BoutonQuitter.place(x=600, y=550)
     
     
    fenetre.mainloop()  # Permet l'ouverture de la fenetre
    Remarque : le curseur est toujours immobile, comme l'explique wiztricks...
    Pas d'aide par mp.

  18. #38
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    En guise d'illustration de ce qu'il faudrait faire.
    On part du code initial (corrigé):
    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
    from PIL import Image, ImageTk
    import Tkinter as tk
     
    def luminosite(value):
        global photo
     
        width, height = image.size
        for x in range(width):
            for y in range(height):
                rvb = list(image.getpixel((x, y)))
                for i, v in enumerate(rvb):
                    v += value
                    if v < 0: v = 0
                    elif v > 255: v = 255
                    rvb[i] = v
                image.putpixel((x,y), tuple(rvb))
        photo = ImageTk.PhotoImage(image)
        label['image'] = photo
     
    if __name__ == '__main__':
        root = tk.Tk()
        root['bg'] = 'grey'
        image = Image.open('clementine.jpg')
        photo = ImageTk.PhotoImage(image)
        label = tk.Label(root, image=photo)
        label.pack(side='left')
     
        scale = tk.Scale(root, from_=-150, to=250, resolution=25, orient='horizontal',
                 length=250, width=10, tickinterval=50,
                 command = lambda v: luminosite(int(v)))
        scale.pack(side='right')
     
        tk.mainloop()
    Puis on pousse les calculs dans un thread et on affiche une progressbar.

    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
    from PIL import Image, ImageTk
    import Tkinter as tk
    import ttk
    from threading import Thread
     
    import re
    def parse_geometry(geometry):
        m = re.match("(\d+)x(\d+)([-+]\d+)([-+]\d+)", geometry)
        if not m:
            raise ValueError("failed to parse geometry string")
        return map(int, m.groups())
     
    PB_NAME = 'progressbar'
     
    def pb_create():
        assert not pb_is_running(), 'fatal: not supposed to happen'
        # creation d'une fenetre sans bords
        window = tk.Toplevel(name=PB_NAME)
        window.overrideredirect(1)
        # on la rend +/- "modale"
        window.grab_set()
        # animation.
        w = ttk.Progressbar(window)
        w.pack()
        w.start()
        # centrage
        window.update()
        w, h, x, y = parse_geometry(root.geometry())
        u, v = window.winfo_width(), window.winfo_height()
        x += (w - u) // 2
        y += (h - v) // 2
        window.geometry('+%d+%d' % (x, y))
     
    def pb_delete():
        window = root.children.get(PB_NAME)
        if window:
            window.destroy()
     
    def pb_is_running():
        return root.children.get(PB_NAME) != None
     
    def luminosite(value):
     
        def done():
            # dans le contexte du thread principal, on fait
            # la mise a jour du widget.
            label['image'] = photo
            pb_delete()
     
        def compute():
            # effectue la transformation dans le Thread
            global photo
            width, height = image.size
            for x in range(width):
                for y in range(height):
                    rvb = list(image.getpixel((x, y)))
                    for i, v in enumerate(rvb):
                        v += value
                        if v < 0: v = 0
                        elif v > 255: v = 255
                        rvb[i] = v
                    image.putpixel((x,y), tuple(rvb))
            photo = ImageTk.PhotoImage(image)
            # on 'poste' la mise a jour
            root.after_idle(done)
     
        pb_create()
        p = Thread(target=compute)
        p.daemon = True
        p.start()
     
    if __name__ == '__main__':
        root = tk.Tk()
        root['bg'] = 'grey'
        image = Image.open('clementine.jpg')
        photo = ImageTk.PhotoImage(image)
        label = tk.Label(root, image=photo)
        label.pack(side='left')
     
        scale = tk.Scale(root, from_=-150, to=250, resolution=25, orient='horizontal',
                 length=250, width=10, tickinterval=50,
                command = lambda v: luminosite(int(v)) )
        scale.pack(side='right')
        tk.mainloop()
    In fine, j'ai ajouté 50 lignes de code supplémentaires à la 30aine de lignes du départ.


    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  19. #39
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    J'ai testé ton code, et comme tu l'avais supputé, assertion fail.
    Je sais où se situe le problème, mais je suis incapable de le résoudre

    Je me suis essayé en mettant tout dans une classe, bah ça fonctionne sans thread, le traitement est assez long (enfin c'est relatif), mais j'imagine que pour accélérer ça, faudrait découper les images et traiter chaque morceaux dans un thread, autant de morceaux d'images que de thread donc.

    Le code de gros amateur et pas dépoussiéré par rapport à celui de wiztricks, mais bon, il fonctionne pas trop mal.

    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
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    #!/usr/bin/python2.7
    # -*-loco-coding: utf-8 -*
     
    import Tkinter as tk
    from PIL import Image, ImageTk
    import tkFileDialog
    import tkMessageBox
    from shutil import copyfile
    import webbrowser
     
    AIDE = """Les boutons couleurs permettent de changer la couleur de l'image.
    Les boutons filtres appliquent des filtres sur la photo.
    Par exemple, le bouton niveau de gis, change l'image en niveau de gris.
    Le bouton posterise permet de transformer l'image en une peinture.
    Le seuillage permet de reduire les couleurs de l'image en seulement deux couleurs, le noir et le blanc.
    Le négatif, permet d'inverser les couleurs de l'image.
    Ensuite, les boutons de redimenssionnement permettent de redimanssionner l'image.
    Les boutons de deplacement de l'image font tourner l'image sur elle-même et dans différentes positions (90 - 180 - 270 degrés."""
     
     
    class RetouchesPhotos(tk.Frame) :
     
        def __init__(self, parent) :
            tk.Frame.__init__(self, parent)
            self.grid()
            self.master.title('Retouches Photos')
            self.selectionImage()
            self.imageTravail = self.imageBase
            # Canevas destiné à donner une dimension à la trame
            tk.Canvas(self, width=1050, height=600, bg='grey').grid(row=1, column=1, columnspan=5, rowspan=13)
     
            self.canevas = tk.Canvas(self, width=self.largeur, height=self.hauteur)
            self.canevas.grid(row=1, column=1, rowspan=13)
     
            imgN = ImageTk.PhotoImage(self.imageBase)
            self.imageId = self.canevas.create_image(0, 0, anchor=tk.NW, image=imgN)
            self.canevas.image = imgN
     
            self.elements()
            # Commandes à désactiver à chaque traitement sur l'image
            self.commandesBoutons = [(self.boutonCouleurCyan, self.couleurCyan),
                                     (self.boutonCouleurRouge, self.couleurRouge),
                                     (self.boutonCouleurBleu, self.couleurBleu),
                                     (self.boutonPivoterDroite, self.pivoterDroite),
                                     (self.boutonPivoterGauche, self.pivoterGauche),
                                     (self.boutonRedimensionner, self.redimensionner),
                                     (self.echelleLuminosite, self.luminosite),
                                     (self.boutonSauvegarde, self.sauvegarder),
                                    ]
     
        def selectionImage(self) :
            self.cheminImageSource = tkFileDialog.askopenfilename(filetypes=[('all files','.*'), ('png files','.png')])
            self.cheminImageDestination = tkFileDialog.asksaveasfilename(title='Choisissez l\'image de destination')
            copyfile(self.cheminImageSource, self.cheminImageDestination)
            self.imageBase = Image.open(self.cheminImageDestination)
            self.largeur, self.hauteur = self.imageBase.size
     
        def actualiser(self) :
            self.canevas.delete(self.imageId)
            imgN = ImageTk.PhotoImage(self.imageTravail)
            self.imageId = self.canevas.create_image(0, 0, anchor = tk.NW, image=imgN)
            self.canevas.image = imgN # tkinter a besoin de garder une référence de l'image
     
        def desactiverTravail(self) :
            self.canevas.itemconfigure(self.texteInfoTraitement1, state=tk.HIDDEN)
            self.canevas.itemconfigure(self.texteInfoTraitement1, state=tk.HIDDEN)
            self.canevas.update_idletasks()
            for n in self.commandesBoutons :
                n[0].state = tk.ACTIVE
                n[0].command = n[1]
     
        def activerTravail(self) :
            try : # lift et lower saoulent, du coup, on delete et create chaque fois
                self.canevas.delete(self.texteInfoTraitement1)
                self.canevas.delete(self.texteInfoTraitement2)
            except :
                pass
            self.texteInfoTraitement1 = self.canevas.create_text(round(self.largeur/2)-19, round(self.hauteur/2)-19, text='Opération en cours....', font='Comic 16', fill='#fff')
            self.texteInfoTraitement12 = self.canevas.create_text(round(self.largeur/2)-20, round(self.hauteur/2)-20, text='Opération en cours....', font='Comic 16', fill='dark green')
            self.canevas.update_idletasks()
            for n in self.commandesBoutons :
                n[0].state = tk.DISABLED
                n[0].command = None
     
     
        def couleur(self, r=0, g=0, b=0) :
            self.activerTravail()
            for y in range(self.hauteur) :
                for x in range(self.largeur) :
                    rgb = list(map(lambda n, n1: n - n1, self.imageTravail.getpixel((x,y)), (r,g,b)))
                    for k, v in enumerate(rgb) :
                        if v < 0 : rgb[k] = 0
                    self.imageTravail.putpixel((x,y),tuple(rgb))
            self.desactiverTravail()
            self.actualiser()
     
        def couleurCyan(self) :
            self.couleur(r=20)
     
        def couleurRouge(self) :
            self.couleur(g=20, b=20)
     
        def couleurBleu(self) :
            self.couleur(r=20, g=20)
     
        def luminosite(self, valeur) :      
            valeur = int(valeur)
            if self.valeurLuminosite < valeur :
                dif = abs(valeur-self.valeurLuminosite)
            elif self.valeurLuminosite > valeur :
                dif = -(self.valeurLuminosite-valeur)
            else :
                return # La commande est appelée sans qu'on ait agit sur le curseur...
            self.activerTravail()
     
            for y in range (self.hauteur) :
                for x in range (self.largeur) :
                    rgb = [n + dif for n in self.imageTravail.getpixel((x, y))]
                    for k, v in enumerate(rgb) :
                        if v > 255 : rgb[k] = 255
                        elif v < 0 : rgb[k] = 0
                    self.imageTravail.putpixel((x,y),tuple(rgb))
            self.valeurLuminosite = valeur
            self.actualiser()
            self.desactiverTravail()
     
        def redimensionner(self) :
            self.largeur, self.hauteur = int(self.varLargeur.get()), int(self.varHauteur.get())
            self.imageTravail = self.imageTravail.resize((self.largeur, self.hauteur), Image.NEAREST) # resize retourne une copie
            self.actualiser()
     
        def pivoter(self, angle) :
            self.imageTravail = self.imageTravail.rotate(angle) # Rotate retourne une copie
            self.actualiser()
     
        def pivoterGauche(self) :
            self.pivoter(-90)
     
        def pivoterDroite(self) :
            self.pivoter(90)
     
        def aide(self) :
            tkMessageBox.showinfo('Aide', AIDE, parent=self)
     
        def voirImage(self) :
            webbrowser.open(self.cheminImageDestination)
     
        def voirImageSource(self) :
            webbrowser.open(self.cheminImageSource)
     
        def sauvegarder(self) :
            self.imageTravail.save(self.cheminImageDestination)
     
        def elements(self) :     
            couleurs = tk.Label(self, text='Couleurs', font='Comic 10').grid(row=1, column=2, columnspan=4)
     
            self.boutonCouleurCyan = tk.Button(self, text ='Cyan', command=self.couleurCyan, fg='black', bg='cyan', font='Comic 10')
            self.boutonCouleurCyan.grid(row=2, column=2)
     
            self.boutonCouleurRouge = tk.Button(self, text ='Rouge', command=self.couleurRouge, fg='black', bg='red', font='Comic 10')
            self.boutonCouleurRouge.grid(row=2, column=3)
     
            self.boutonCouleurBleu = tk.Button(self, text ='Bleu', command=self.couleurBleu, fg='white', bg='blue', font='Comic 10')
            self.boutonCouleurBleu.grid(row=2, column=4)
     
            rotation = tk.Label(self, text=' Rotation ', font='Comic 10').grid(row=3, column=2, columnspan=4)
     
            imgRd, imgRg = tk.PhotoImage(file='rotationdroite.gif'), tk.PhotoImage(file='rotationgauche.gif')
            self.boutonPivoterDroite = tk.Button(self, image=imgRd, command=self.pivoterDroite)
            self.boutonPivoterDroite.grid(row=4, column=2, columnspan=2)
            self.boutonPivoterGauche = tk.Button(self, image=imgRg, command=self.pivoterGauche)
            self.boutonPivoterGauche.grid(row=4, column=4, columnspan=2)
            self.boutonPivoterDroite.image, self.boutonPivoterGauche.image = imgRd, imgRg
     
            tk.Label(self, text='Dimensions de l\'image', font='Comic 10').grid(row=5, column=2, columnspan=4)
     
            tk.Label(self, text='Hauteur en pixels', font='Comic 9').grid(row=6, column=2, columnspan=2, sticky=tk.NE)
            self.varHauteur = tk.IntVar()
            champHauteur = tk.Entry(self, textvariable=self.varHauteur, width=4).grid(row=6, column=4, columnspan=2, sticky=tk.NW)
     
            tk.Label(self, text='Largeur en pixels', font='Comic 9').grid(row=7, column=2, columnspan=2, sticky=tk.NE)
            self.varLargeur = tk.IntVar()
            champLargeur = tk.Entry(self, textvariable=self.varLargeur, width=4).grid(row=7, column=4, columnspan=2, sticky=tk.NW)
     
            self.boutonRedimensionner = tk.Button(self, text ='Valider', command=self.redimensionner, font='Comic 9')
            self.boutonRedimensionner.grid(row=8, column=2, columnspan=4)
     
            tk.Button(self, text = 'Afficher l\'image d\'origine', command=self.voirImageSource, font='Comic 10').grid(row=9, column=2, columnspan=2)
            tk.Button(self, text ='Afficher la nouvelle image', command=self.voirImage, font='Comic 10').grid(row=9, column=4, columnspan=2)
     
            tk.Label(self, text='Luminosité', font='Comic 9').grid(row=10, column=2, columnspan=4)
            self.valeurLuminosite = 0
            self.echelleLuminosite = tk.Scale(self, from_=-150, to=150, resolution=25, orient='horizontal', length=300, width=10, tickinterval=50, command=self.luminosite)
            self.echelleLuminosite.grid(row=11, column=2, columnspan=4)
     
            tk.Button(self, text = '?', command=self.aide, font='Comic 14', bg = 'blue', fg = 'white').grid(row=12, column=2, columnspan=2)
            tk.Button(self, text ='Quitter', command = self.master.destroy, font='Comic 9').grid(row=12, column=4, columnspan=2)
     
            self.boutonSauvegarde = tk.Button(self, text='Sauvegarder', command=self.sauvegarder, font='Comic 14')
            self.boutonSauvegarde.grid(row=13, column=2, columnspan=4)
     
    fen = tk.Tk()
    rp = RetouchesPhotos(fen)
    fen.mainloop()
    Le temps ronge l'amour comme l'acide.

  20. #40
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 608
    Points : 2 072
    Points
    2 072
    Par défaut
    Tout ceci est beaucoup trop compliqué pour moi.
    J'ai donc repris mon code, j'ai enlevé les fonctions sepia, sauvegarde, ...
    Voici ce que cela donne.
    C'est opérationnel avec python3.
    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
    102
    103
    104
    105
    106
    107
    108
    109
    110
    from PIL import Image as Im
    import sys
    import os
    from tkinter import Entry, Label, Tk, Scale, HORIZONTAL
    from tkinter import Canvas, PhotoImage, Button, StringVar
     
    def recup():
        """
        récupération du nom de fichier et de l'extension
        ouverture de l'image
        """
        nom_fich=entr1.get()
        nom_ext = entr2.get()
        # ext1 = '.jpg'
        ext2 = '.gif'
        global cible_gif, source_gif
        global cible_jpg, source_jpg
        source_jpg = nom_fich + '.' + nom_ext
        source_gif = nom_fich + ext2
        cible_jpg = nom_fich + 'conv' + '.' + nom_ext
        cible_gif = nom_fich + 'conv' + ext2
        global mon_image, largeur, hauteur
        mon_image = Im.open(source_jpg)
        mon_image.save(source_gif)
        largeur,hauteur = mon_image.size
     
    def jpg_gif(nom1,nom2):
        """ 
        conversion de format, par exemple jpg en gif
        """
        os.system('convert %s %s' % (nom1,nom2))
     
    def luminosite(valeur):
        image2 = Im.new('RGB',(largeur,hauteur))
        for colonne in range (largeur):
            for ligne in range (hauteur):
                pixel = mon_image.getpixel((colonne, ligne))
     
                rouge = pixel[0]+ int(valeur)   # On augmente de int(nouvellevaleur) la valeur des pixels Rouge (Valeur comprise entre [0,255])
                vert = pixel[1]+ int(valeur)   # On augmente de int(nouvellevaleur) la valeur des pixels Vert (Valeur comprise entre [0,255])
                bleu = pixel[2]+ int(valeur)   # On augmente de int(nouvellevaleur) la valeur des pixels Bleu (Valeur comprise entre [0,255])
     
                if rouge < 0: rouge = 0         # Comme la valeur doit-être comprise entre [0,255], il faut donc suprimer les valeurs inférieurs à 0 et
                if rouge > 255: rouge = 255     # supérieurs à 255
     
                if vert < 0: vert = 0
                if vert > 255: vert = 255
     
                if bleu < 0: bleu = 0
                if bleu > 255: bleu = 255
     
                image2.putpixel ((colonne,ligne) ,(rouge,vert,bleu))
        return image2
     
     
    def lum(valeur):
        """ conversion négatif couleur puis conversion de format
        pour avoir les aperçus dans tkinter"""
        recup()
        res = luminosite(valeur)
        res.save(cible_jpg)
        if sys.platform == "linux":
            jpg_gif(source_jpg,source_gif)
            jpg_gif(cible_jpg,cible_gif)
        rafraichissement()
     
    def rafraichissement():
        """
        rafarichissement des images source et cible dans les fenêtres de visualisation
        """
        global photo1, photo2
        can1 = Canvas(fen1, width =160, height =160, bg ='white')
        can1.grid(row =1, column =3, rowspan =3, padx =10, pady =5)
        can2 = Canvas(fen1, width =160, height =160, bg ='white')
        can2.grid(row =1, column =5, rowspan =3, padx =10, pady =5)
        if os.path.isfile(source_gif) == True:
            photo1 = PhotoImage(file = source_gif)
            can1.create_image(80, 80, image =photo1)
        if os.path.isfile(cible_gif) == True:
            photo2 = PhotoImage(file = cible_gif)
            can2.create_image(80, 80, image =photo2)
     
    fen1 = Tk()
     
    txt1 = Label(fen1, text ='Nom de fichier (sans extension)')
    entr1 = Entry(fen1)
    txt1.grid(row =1, column=1, sticky ='EW')
    entr1.grid(row =1, column =2)
     
    txt2 = Label(fen1, text ='Extension')
    entr2 = Entry(fen1)
    txt2.grid(row =2, column=1, sticky ='EW')
    entr2.grid(row =2, column =2)
     
     
    #Création d'un widget Luminosité
    Lumin=Label(fen1, text=" Luminosité ", font="Comic 10")
    Lumin.grid(row=11 , column=1, sticky='NESW')
    valeur = StringVar() # On definit Valeur
    valeur.set(0)        # On donne la valeur que prendra le curseur au départ
    # Création d'un widget Curseur
    echelle = Scale(fen1,length=400, orient=HORIZONTAL, label = 'Réglage de la luminosité', troughcolor ='yellow', \
    sliderlength =20, showvalue =0,from_=-220,to=220, resolution=40, tickinterval=50, variable=valeur, command=lum) # width=10
    echelle.grid(row=11 , column=3, sticky='NESW')
     
    # fermeture
    Button(fen1,text='Quitter',command=fen1.destroy).grid(row=7 , column=3,columnspan=1, sticky='NESW')
     
    # démarrage :
    fen1.mainloop()
    Pas de thread, de classe : j'en suis pour l'instant incapable.

    [Edit] J'avais oublié la fonction jpg_gif.
    Par contre, j'ai un message d'erreur qui n'altère pas le fonctionnement mais il va falloir que je creuse...
    Pas d'aide par mp.

Discussions similaires

  1. afficher une image dans un canvas
    Par alex.blais dans le forum Tkinter
    Réponses: 4
    Dernier message: 08/12/2007, 18h29
  2. afficher une image dans un canvas
    Par Arrakis dans le forum Tkinter
    Réponses: 1
    Dernier message: 05/03/2007, 13h22
  3. placer plusieurs images dans un canvas
    Par philac dans le forum Tkinter
    Réponses: 6
    Dernier message: 07/11/2006, 00h43
  4. actualisation d'une image dans ma page
    Par jack_1981 dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 01/08/2006, 14h45
  5. [Tkinter]Image dans un Canvas
    Par Slade991 dans le forum Tkinter
    Réponses: 2
    Dernier message: 10/06/2006, 14h42

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