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

GTK+ avec Python Discussion :

gtk image + dessin


Sujet :

GTK+ avec Python

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 9
    Points : 3
    Points
    3
    Par défaut gtk image + dessin
    Bonjour à tous,

    Voici ma question : je débute dans le développement d'une interface en gtk+(c).
    Je dois ouvrir une image, pouvoir zoomer, pouvoir récupérer les coordonnées x y et la valeur du pixel sur passage de la souris et pouvoir sélectionner une région(rectangle) (un peu à la Gimp).
    Pour l'image j'avais utilisé le widget Image mais cela ne convient pas puisqu'on ne peut dessiner ?.
    Pourriez-vous m'aiguiller sur quel widget utiliser et comment (j'ai essayé DrawingArea mais je ne parvient pas à faire grand chose, cela fait des jours que je lis des docs sur internet mais visiblement quelquechose m'échappe).

    Merci d'avance pour vos réponses.
    Syl

  2. #2
    Membre averti
    Avatar de Alain_72
    Inscrit en
    Août 2004
    Messages
    180
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 180
    Points : 342
    Points
    342
    Par défaut
    Le mieux est de manipuler les images avec la bibliothèque PIL (Python Imaging Library) et de les rapporter dans une ScrolledWindow un fois manipulées.

    Je t'ai fait un petit exemple, qui permet d'afficher une image, et d'en sélectionner une partie à la souris pour l'agrandir.

    Etudie bien tout ça...

    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
    #! /usr/bin/env python
    #-*- coding: utf-8 -*-
     
    import pygtk
    pygtk.require('2.0')
    import gtk
    import Image
    import ImageDraw
    import ImageOps
     
    class MaLoupe(gtk.Dialog):
    	def __init__(self,title ,principale, image):
    		gtk.Dialog.__init__(self, title= title, parent= principale, flags=gtk.DIALOG_MODAL)
    		self.image = image
    		self.zoneDeDessin = None
    		self.xTaille, self.yTaille = self.image.size
    		self.set_size_request(self.xTaille, self.yTaille)
    		self.surface = gtk.DrawingArea()
    		self.surface.set_size_request(self.xTaille, self.yTaille)
    		self.vbox.pack_start(self.surface, True, True, 0)
    		self.surface.set_events(gtk.gdk.BUTTON_PRESS_MASK)
    		self.surface.connect("button_press_event", self.Appuyer)
    		self.surface.connect("expose-event", self.Afficher)
     
    		self.surface.show()
     
    	def Appuyer(self, widget, event):
    		self.destroy()
    		return
     
    	def Afficher(self, widget=None, data=None):
    		buff = self.image.tostring()
    		self.zoneDeDessin = self.surface.window
    		self.gC = self.zoneDeDessin.new_gc()
    		if self.image.mode == "L":
    			self.zoneDeDessin.draw_gray_image(self.gC, 0, 0, self.xTaille, self.yTaille, gtk.gdk.RGB_DITHER_NONE, buff, self.xTaille)
    		elif self.image.mode == "RGB":
    			self.zoneDeDessin.draw_rgb_image(self.gC, 0, 0, self.xTaille, self.yTaille, gtk.gdk.RGB_DITHER_NONE, buff, self.xTaille*3)
    		elif self.image.mode == "RGBA":
    			self.zoneDeDessin.draw_rgb_32_image(self.gC, 0, 0, self.xTaille, self.yTaille, gtk.gdk.RGB_DITHER_NONE, buff, self.xTaille*4)
    		return
     
    class MonAffichage(gtk.ScrolledWindow):
    	def __init__(self, principale, image=None):
    		gtk.ScrolledWindow.__init__(self)
    		self.xPosOr = self.yPosOr = 0
    		self.flagSelect = False
    		self.principale = principale
    		if image:
    			self.image = image
    			self.imOr = image.copy()
    		else:
    			self.image = Image.new("RGB", (800, 600))
    			self.imOr = None
    		self.zoneDeDessin = None
    		self.xTaille, self.yTaille = self.image.size
    		self.surface = gtk.DrawingArea()
    		self.surface.set_size_request(self.xTaille, self.yTaille)
    		self.add_with_viewport(self.surface)
     
    		self.surface.set_events(gtk.gdk.BUTTON_PRESS_MASK|gtk.gdk.BUTTON_RELEASE_MASK|gtk.gdk.POINTER_MOTION_MASK)
    		self.surface.connect("button_press_event", self.Appuyer)
    		self.surface.connect("button_release_event", self.Relacher)
    		self.surface.connect("motion_notify_event", self.Bouger)
     
    		self.surface.connect("expose-event", self.Afficher)
     
    		self.surface.show()
     
    	def Appuyer(self, widget, event):
    		if self.imOr:
    			xPos, yPos = event.get_coords()
    			if (xPos <= self.xTaille) and (yPos <= self.yTaille):
    				self.xPosOr = xPos
    				self.yPosOr = yPos
    				self.flagSelect = True
     
    	def Relacher(self, widget, event):
    		if self.flagSelect:
    			xPos, yPos = event.get_coords()
    			if (xPos > self.xTaille):
    				xPos = self.xTaille
    			if (yPos > self.yTaille):
    				yPos = self.yTaille
    			self.flagSelect = False
    			self.image = self.imOr
    			self.Afficher()
    			if (abs(xPos - self.xPosOr) > 20) and (abs(yPos - self.yPosOr) > 20):
    				if xPos > self.xPosOr:
    					xDeb = self.xPosOr
    					xFin = xPos
    				else:
    					xDeb = xPos
    					xFin = self.xPosOr
    				if yPos > self.yPosOr:
    					yDeb = self.yPosOr
    					yFin = yPos
    				else:
    					yDeb = yPos
    					yFin = self.yPosOr
    				rect = (int(xDeb), int(yDeb), int(xFin), int(yFin))
    				region = self.imOr.crop(rect)
    				largeur, hauteur = region.size
    				largeur = int(largeur * 2)
    				hauteur = int(hauteur * 2)
    				taille = (largeur, hauteur)
    				im = region.resize(taille)
    				loupe = MaLoupe(title = "Loupe", principale = self.principale, image = im)
    				loupe.run()
    		return
     
    	def Bouger(self, widget, event):
    		if self.flagSelect:
    			xPos, yPos = event.get_coords() 
    			if (xPos > self.xTaille):
    				xPos = self.xTaille
    			elif xPos < 0:
    				xPos = 0
    			if (yPos > self.yTaille):
    				yPos = self.yTaille
    			elif xPos < 0:
    				xPos = 0
    			if xPos > self.xPosOr:
    				xDeb = self.xPosOr
    				xFin = xPos
    			else:
    				xDeb = xPos
    				xFin = self.xPosOr
    			if yPos > self.yPosOr:
    				yDeb = self.yPosOr
    				yFin = yPos
    			else:
    				yDeb = yPos
    				yFin = self.yPosOr
    			rect = [(xDeb, yDeb), (xFin, yFin)]
    			tampon = self.imOr.copy()
    			draw = ImageDraw.Draw(tampon)
    			draw.rectangle(rect)
    			self.xTaille, self.yTaille = tampon.size
    			self.image = tampon
    			self.Afficher()
     
    	def Afficher(self, widget=None, data=None):
    		if self.image.mode == "1":
    			try:
    				self.image = ImageOps.grayscale(self.image)
    			except:
    				self.destroy()
    				return
    		buff = self.image.tostring()
    		self.zoneDeDessin = self.surface.window
    		self.gC = self.zoneDeDessin.new_gc()
    		if self.image.mode == "L":
    			self.zoneDeDessin.draw_gray_image(self.gC, 0, 0, self.xTaille, self.yTaille, gtk.gdk.RGB_DITHER_NONE, buff, self.xTaille)
    		elif self.image.mode == "RGB":
    			self.zoneDeDessin.draw_rgb_image(self.gC, 0, 0, self.xTaille, self.yTaille, gtk.gdk.RGB_DITHER_NONE, buff, self.xTaille*3)
    		elif self.image.mode == "RGBA":
    			self.zoneDeDessin.draw_rgb_32_image(self.gC, 0, 0, self.xTaille, self.yTaille, gtk.gdk.RGB_DITHER_NONE, buff, self.xTaille*4)
    		else:
    			self.destroy()
    			return
     
    	def SetImage(self, image=None):
    		if image:
    			self.image = image
    			self.imOr = image.copy()
    		else:
    			self.image = Image.new("RGB", (800, 600))
    			self.imOr = None
    		self.xTaille, self.yTaille = self.image.size
                    self.surface.set_size_request(self.xTaille, self.yTaille)
    		self.Afficher()
     
    class MonPanneau(gtk.Frame):
    	def __init__(self, principale):
    		gtk.Frame.__init__(self)
    		self.principale = principale
    		self.set_shadow_type(gtk.SHADOW_NONE)
    		self.image = None
    		self.affichage = MonAffichage(self.parent)
    		self.add(self.affichage)
    		self.affichage.show()
     
    	def SetImage(self, image=None):
    		self.image = image
    		self.affichage.SetImage(self.image)
     
    class MaFenetre(gtk.Window):
    	def __init__(self, titre = "Test"):
    		gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
    		self.set_title(titre)
    		self.set_size_request(800, 700)
    		self.set_border_width(3)
    		self.image = None
    		box = gtk.VBox(False, 0)
    		icon_open = gtk.Image()
    		icon_open.set_from_stock(gtk.STOCK_OPEN, gtk.ICON_SIZE_SMALL_TOOLBAR)
    		icon_quit = gtk.Image()
    		icon_quit.set_from_stock(gtk.STOCK_QUIT, gtk.ICON_SIZE_SMALL_TOOLBAR)
    		icon_close = gtk.Image()
    		icon_close.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_SMALL_TOOLBAR)
    		toolbar = gtk.Toolbar()
    		toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL)
    		toolbar.set_style(gtk.TOOLBAR_BOTH)
    		toolbar.set_border_width(5)
    		open_bouton = toolbar.append_item("Ouvrir", "Ouvrir un fichier image", "private", icon_open, self.Ouvrir)
    		open_bouton = toolbar.append_item("Fermer", "Fermer le fichier", "private", icon_close, self.Fermer)
    		open_bouton = toolbar.append_item("Quitter", "Sortir de l'application", "private", icon_quit, self.Quitter)
    		box.pack_start(toolbar, False, False, 3)
    		toolbar.show()
    		self.panneau = MonPanneau(self)
    		box.pack_start(self.panneau, True, True, 3)
    		self.panneau.show()
    		self.add(box)
    		box.show()
    		self.connect("delete_event", lambda a1, a2 : gtk.main_quit())
     
    	def Ouvrir(self, event):
    		fichier = None
    		chooser = gtk.FileChooserDialog(title="choisir une image",action=gtk.FILE_CHOOSER_ACTION_OPEN,
    								buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
    		filter = gtk.FileFilter()
    		filter.set_name("Images")
    		filter.add_mime_type("image/png")
    		filter.add_mime_type("image/jpeg")
    		filter.add_pattern("*.png")
    		filter.add_pattern("*.jpg")
    		chooser.add_filter(filter)
    		reponse = chooser.run()
    		if reponse == gtk.RESPONSE_OK:
    			fichier = chooser.get_filename()
    		chooser.destroy()
    		if fichier:
    			self.image = Image.open(fichier)
    			self.panneau.SetImage(self.image)
     
    	def Fermer(self, event):
    		if self.image:
    			self.image = None
    			self.panneau.SetImage()
     
    	def Quitter(self, event):
    		gtk.main_quit()
     
    class MonApp:
    	def __init__(self):
    		f = MaFenetre()
    		f.show()
     
    	def MainLoop(self):
    		gtk.main()
     
    if __name__ == "__main__" :
    	app = MonApp()
    	app.MainLoop()

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    je te remercie Alain pour ce code ))) c'est exactement ce que je voulais faire mais en mieux.

    1) Je voudrais savoir sous quelle licence tu mets ce code stp. (si c'est GPL, ca me convient complètement, vu que le soft que je suis en train defaire le sera (en fonction de la licence de ton code))

    2) ne trouves-tu pas une certaine lenteur au dessin du rectangle ? quand on sélectionne la zone à zoomer ?
    Peut-on améliorer cela, par exemple en ne dessinant le rectangle qu'une fois que le mouvement a dépasser plus de 3 pixels ?

    A bientot.

Discussions similaires

  1. gtk image dessin
    Par syl_syl dans le forum GTK+ avec C & C++
    Réponses: 3
    Dernier message: 30/06/2006, 11h49
  2. [Image]Dessiner des rectangles sur une image
    Par navona dans le forum Bibliothèques et frameworks
    Réponses: 9
    Dernier message: 09/03/2006, 22h51
  3. [Image][Dessin]calques
    Par roche.jul dans le forum 2D
    Réponses: 9
    Dernier message: 06/03/2006, 12h56
  4. [Servlet] [Image] Dessiner sur une image
    Par gaia_dev dans le forum 2D
    Réponses: 5
    Dernier message: 01/09/2004, 17h11
  5. [Image]Dessiner une ligne en dynamique
    Par Bugmaster dans le forum AWT/Swing
    Réponses: 8
    Dernier message: 02/08/2004, 11h56

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