Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Afficher une image dans un canevas (Tk)

2 réponses
Avatar
JH
Bonjour,

Je souhaite afficher une image chargée par l'intermédiaire d'un sélecteur de
fichier dans un canevas.

Le programme suivant ne donne aucun message d'erreur, et pourant rien ne
s'affiche dans le canevas.

J'ai pourtant pris la précaution de sauver l'image dans un objet tel qu'un
dictionnaire, pour éviter que le garbage collector ne détruise mon pointeur
d'image.... mais je dois pas avoir saisis, vu que ça ne fonctionne
pas... :?

Si quelqu'un parmi vous saurait me dire quelle est mon erreur... Je le
remercie d'avance,

Cordialement,

JH

======================================= CODE :
# -*- coding: iso-8859-15 -*-
class imageManipulator:
def __init__(self):
''' constructeur '''
self.root = Tk()
self.image = {}

# boutons et elements du GUI
self.openImageButton = Button(self.root, text="Ouvrir",
command=self.__openImage)
self.methodListbox = Listbox(self.root, height=4)
for item in ['inversion', 'flou', 'contour']:
self.methodListbox.insert(END, item)
self.methodListbox.select_set(0) # choix par defaut : le premier
self.computeMethodButton = Button(self.root, text="Calcul",
command=self.__computeImage)

self.scrollbar = Scrollbar(self.root)
self.c = Canvas(self.scrollbar, height=500, width=500, bg='#FFFFFF')

# placement des elements
self.openImageButton.grid(row=0, column=0)
self.methodListbox.grid(row=0, column=1)
self.computeMethodButton.grid(row=0, column=2)
self.scrollbar.grid(row=1, columnspan=3)
self.c.grid(row=0, column=0)

# main boucle
self.root.mainloop()

def __openImage(self):
global im
''' ouvre une image à partir du selecteur de fichier '''
self.imageFile = tkFileDialog.askopenfile(parent=self.root,
mode='rb', title='Choisissez une image')
if self.imageFile != None:
img = Image.open(self.imageFile)
self.image['image'] = img # logiquement : sauvegarde de l'objet
image dans un dic ??
#self.imageFile.close() # <======== doit on le fermer ?
self.__displayImage()

def __computeImage(self):
''' Calcule la transformation de l'image ouverte '''

def __displayImage(self):
''' affiche une image dans le canevas '''
self.c.create_image(0,0,
image=ImageTk.PhotoImage(self.image['image']), anchor=NW)


from Tkinter import *
import Image
import tkFileDialog
import ImageTk

imMan = imageManipulator()

2 réponses

Avatar
Eric Brunel
On Wed, 07 Jun 2006 19:44:37 +0200, JH wrote:

Bonjour,

Je souhaite afficher une image chargée par l'intermédiaire d'un
sélecteur de
fichier dans un canevas.

Le programme suivant ne donne aucun message d'erreur, et pourant rien ne
s'affiche dans le canevas.

J'ai pourtant pris la précaution de sauver l'image dans un objet tel
qu'un
dictionnaire, pour éviter que le garbage collector ne détruise mon
pointeur
d'image.... mais je dois pas avoir saisis, vu que ça ne fonctionne
pas... :?

Si quelqu'un parmi vous saurait me dire quelle est mon erreur... Je le
remercie d'avance,


Tu sauvegardes le mauvais objet: c'est l'instance de PhotoImage qu'il faut
sauvegarder, celle que tu crées dans la méthode __displayImage.

Pour tes autres questions, je ne sais pas, vu que je ne connais pas le
package Image (PIL?). Je laisse les spécialistes répondre. Une petite
remarque/question: je ne comprends pas à quoi sert le "global im" dans la
méthode __openImage (ce qui signifie en fait que je suis à peu près
persuadé qu'il ne sert à rien, vu que tu n'utilises jamais la variable im
par la suite...). J'aurais compris un "global img", mais il n'aurait servi
à rien non plus: vu que tu sauvegardes dans un attribut de ton objet, il
est inutile de sauvegarder en plus dans une variable globale (et
rappelons-le: les variables globales, c'est Mal).

Une autre petite remarque: l'usage veut qu'on fasse les imports au début
du fichier plutôt qu'au milieu. Ce n'est pas très important, mais ça rend
le code plus facile à lire pour nous autres pauvres humains: comme ça,
quand on voit le nom d'un module importé, on sait déjà que c'est un module
importé.

======================================= CODE :
# -*- coding: iso-8859-15 -*-
class imageManipulator:
def __init__(self):
''' constructeur '''
self.root = Tk()
self.image = {}

# boutons et elements du GUI
self.openImageButton = Button(self.root, text="Ouvrir",
command=self.__openImage)
self.methodListbox = Listbox(self.root, height=4)
for item in ['inversion', 'flou', 'contour']:
self.methodListbox.insert(END, item)
self.methodListbox.select_set(0) # choix par defaut : le premier
self.computeMethodButton = Button(self.root, text="Calcul",
command=self.__computeImage)
self.scrollbar = Scrollbar(self.root)
self.c = Canvas(self.scrollbar, heightP0, widthP0,
bg='#FFFFFF')
# placement des elements
self.openImageButton.grid(row=0, column=0)
self.methodListbox.grid(row=0, column=1)
self.computeMethodButton.grid(row=0, column=2)
self.scrollbar.grid(row=1, columnspan=3)
self.c.grid(row=0, column=0)
# main boucle
self.root.mainloop()
def __openImage(self):
global im
''' ouvre une image à partir du selecteur de fichier '''
self.imageFile = tkFileDialog.askopenfile(parent=self.root,
mode='rb', title='Choisissez une image')
if self.imageFile != None:
img = Image.open(self.imageFile)
self.image['image'] = img # logiquement : sauvegarde de
l'objet
image dans un dic ??
#self.imageFile.close() # <======== doit on le fermer ?
self.__displayImage()

def __computeImage(self):
''' Calcule la transformation de l'image ouverte '''

def __displayImage(self):
''' affiche une image dans le canevas '''
self.c.create_image(0,0,
image=ImageTk.PhotoImage(self.image['image']), anchor=NW)

from Tkinter import *
import Image
import tkFileDialog
import ImageTk

imMan = imageManipulator()


HTH
--
python -c "print ''.join([chr(154 - ord(c)) for c in
'U(17zX(%,5.zmz5(17l8(%,5.Z*(93-965$l7+-'])"

Avatar
JH
On Wed, 07 Jun 2006 19:44:37 +0200, JH wrote:

Bonjour,

Je souhaite afficher une image chargée par l'intermédiaire d'un
sélecteur de
fichier dans un canevas.

Le programme suivant ne donne aucun message d'erreur, et pourant rien ne
s'affiche dans le canevas.

J'ai pourtant pris la précaution de sauver l'image dans un objet tel
qu'un
dictionnaire, pour éviter que le garbage collector ne détruise mon
pointeur
d'image.... mais je dois pas avoir saisis, vu que ça ne fonctionne
pas... :?

Si quelqu'un parmi vous saurait me dire quelle est mon erreur... Je le
remercie d'avance,



Tu sauvegardes le mauvais objet: c'est l'instance de PhotoImage qu'il
faut sauvegarder, celle que tu crées dans la méthode __displayImage.

ok. Voici donc ce que j'ai fait :


def __displayImage(self):
''' affiche une image dans le canevas '''
self.photoImage['image'] = ImageTk.PhotoImage(self.image['image'])
self.c.create_image(0,0, image=self.photoImage['image'], anchor=NW)

et ça fonctionne :)

Merci bcp.

Une petite
remarque/question: je ne comprends pas à quoi sert le "global im" dans
la méthode __openImage (ce qui signifie en fait que je suis à peu près
persuadé qu'il ne sert à rien, vu que tu n'utilises jamais la variable
im par la suite...). J'aurais compris un "global img", mais il n'aurait
servi à rien non plus: vu que tu sauvegardes dans un attribut de ton
objet, il est inutile de sauvegarder en plus dans une variable globale
(et rappelons-le: les variables globales, c'est Mal).


Heu, en fait, à rien ;) c'est un "reste" d'essais antérieurs, désolé...

Une autre petite remarque: l'usage veut qu'on fasse les imports au
début du fichier plutôt qu'au milieu. Ce n'est pas très important, mais
ça rend le code plus facile à lire pour nous autres pauvres humains:
comme ça, quand on voit le nom d'un module importé, on sait déjà que
c'est un module importé.


ok, c'est noté :)