|
Publicité | ||||||||||||||||||||||
|
|
#1 (permalink) |
|
Invité de passage
![]() Date d'inscription: juin 2006
Messages: 9
|
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 (permalink) |
![]() Date d'inscription: août 2004
Messages: 180
|
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 :
#! /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()
__________________
Je ne traite pas les problèmes techniques par MP... Les forums sont là pour ça... Le blog d'un bipede ordinaire Les contributions du bipede Dernière modification par Alain_72 ; 01/01/2007 à 16h47. |
|
|
|
|
|
#3 (permalink) |
|
Invité de passage
![]() Date d'inscription: avril 2004
Messages: 6
|
je te remercie Alain pour ce code
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. |
|
|
|
|
|
![]() |
||
gtk image + dessin
|
||
| Outils de la discussion | |
|
|