# -*- coding: Latin-1 -*- #!/usr/bin/python import os, sys from PIL import Image import pygtk pygtk.require("2.0") import gtk import StringIO # passe d'une image pil à une image gtk (merci à manatlan) def image2pixbuf(im): file1 = StringIO.StringIO() im.save(file1, "ppm") contents = file1.getvalue() file1.close() loader = gtk.gdk.PixbufLoader("pnm") loader.write(contents, len(contents)) pixbuf = loader.get_pixbuf() loader.close() return pixbuf # création de l'interface avec les valeurs de base def fenetregtk(): # construction de l'interface mainWindow = gtk.Window() mainWindow.set_title("image") mainWindow.connect("destroy", on_mainWindow_destroy) #ouvre premiere image + quelques infos global im im = Image.open(CHEMIN+"/"+images[0]) global width global height width = im.size[0] height = im.size[1] info = str (images[0] + " " + im.format + " " + str(im.size) + " " + im.mode) label_info = gtk.Label(info) label_crop = gtk.Label(str(width) + " / " + str(height)) ratio = "ratio: " + str(float(width)/float(height)) label_ratio = gtk.Label(ratio) ratio_169 = gtk.Label("16/9: 1.7777...") ratio_43 = gtk.Label("4/3: 1.3333...") # choix de l'image sel_image = gtk.combo_box_new_text() for i in images: sel_image.append_text(i) sel_image.set_active(0) sel_image.connect('changed', change_image, label_info) # previsualisation global preview preview = False global prevWindowsDown prevWindowsDown = True check_prev = gtk.CheckButton("prévisualisation") check_prev.set_active(False) check_prev.connect("clicked", check_prev_clicked) #rotation global angle_rot angle_rot = 0 label_rotation = gtk.Label("rotation") rotation_ajustement = gtk.Adjustment(0, -360, 360, 1) rotation = gtk.SpinButton(rotation_ajustement) rotation.connect("value-changed", maj, label_crop, label_ratio, "rotation") #recadrage global rect rect = [0, 0, width, height] label_gauche = gtk.Label("gauche") label_haut = gtk.Label("haut") label_droite = gtk.Label("droite") label_bas = gtk.Label("bas") gauche_ajustement = gtk.Adjustment(0, 0, width, 1) haut_ajustement = gtk.Adjustment(0, 0, height, 1) droite_ajustement = gtk.Adjustment(width, 0, width, 1) bas_ajustement = gtk.Adjustment(height, 0, height, 1) gauche = gtk.SpinButton(gauche_ajustement) haut = gtk.SpinButton(haut_ajustement) droite = gtk.SpinButton(droite_ajustement) bas = gtk.SpinButton(bas_ajustement) gauche.connect("value-changed", maj, label_crop, label_ratio, "gauche") haut.connect("value-changed", maj, label_crop, label_ratio, "haut") droite.connect("value-changed", maj, label_crop, label_ratio, "droite") bas.connect("value-changed", maj, label_crop, label_ratio, "bas") #redimmentionnement global height_redim global width_redim height_redim = height width_redim = width global redim redim = False check_redim = gtk.CheckButton("redimmensionner?") check_redim.set_active(False) check_redim.connect("clicked", check_redim_clicked) label_width = gtk.Label("largeur") label_height = gtk.Label("hauteur") resize_width_ajustement = gtk.Adjustment(width, 0, width, 1) resize_height_ajustement = gtk.Adjustment(height, 0, height, 1) resize_width = gtk.SpinButton(resize_width_ajustement) resize_height = gtk.SpinButton(resize_height_ajustement) #resize_height.set_update_policy(gtk.UPDATE_DISCONTINUOUS) #resize_width.set_update_policy(gtk.UPDATE_DISCONTINUOUS) resize_height.connect("value_changed", redimensionner, "height", resize_width) resize_width.connect("value_changed", redimensionner, "width", resize_height) #enregistrement label_save = gtk.Label("") save_button = gtk.Button("save") save_button.connect("clicked", on_save_button_clicked, label_save) vBox = gtk.VBox() vBox.pack_start(sel_image) vBox.pack_start(label_info) vBox.pack_start(check_prev) vBox.pack_start(label_rotation) vBox.pack_start(rotation) vBox.pack_start(label_gauche) vBox.pack_start(gauche) vBox.pack_start(label_haut) vBox.pack_start(haut) vBox.pack_start(label_droite) vBox.pack_start(droite) vBox.pack_start(label_bas) vBox.pack_start(bas) vBox.pack_start(label_crop) vBox.pack_start(label_ratio) vBox.pack_start(ratio_169) vBox.pack_start(ratio_43) vBox.pack_start(check_redim) vBox.pack_start(label_width) vBox.pack_start(resize_width) vBox.pack_start(label_height) vBox.pack_start(resize_height) vBox.pack_start(save_button) vBox.pack_start(label_save) mainWindow.add(vBox) mainWindow.show_all() def prev_windows(): global zoom global prevWindowsDown prevWindowsDown = False # seconde fenetre prevWindow = gtk.Window() prevWindow.set_title("image") prevWindow.connect("destroy", on_prevWindow_destroy) zoom_image = gtk.combo_box_new_text() zoom_image.append_text("100%") zoom_image.append_text("75%") zoom_image.append_text("50%") zoom_image.append_text("25%") zoom_image.append_text("10%") if width > 2000 or height > 2000: zoom_image.set_active(4) zoom = "10%" elif width > 1000 or height > 1000: zoom_image.set_active(2) zoom = "50%" else: zoom_image.set_active(0) zoom = "100%" zoom_image.connect('changed', choix_zoom) global previmage previmage = gtk.Image() crop_im(im) vvBox = gtk.VBox() vvBox.pack_start(zoom_image, True, False, 0) vvBox.pack_start(previmage) prevWindow.add(vvBox) prevWindow.show_all() def on_mainWindow_destroy(widget): gtk.main_quit() def on_prevWindow_destroy(widget): global preview global prevWindowsDown preview = False prevWindowsDown = True def check_prev_clicked(widget): global preview global prevWindowsDown if widget.get_active(): preview = True if prevWindowsDown == True : prev_windows() prevWindowsDown = False else: crop_im(im) else: preview = False # découpe l'image et renvoie une image gtk def crop_im(im): if preview == True: im = im.rotate(angle_rot) #im = im.rotate(angle_rot, 3)#trop lourd tuple_rect = (rect[0],rect[1],rect[2],rect[3]) cropim = im.crop(tuple_rect) if zoom == "100%": w = cropim.size[0] h = cropim.size[1] elif zoom == "75%": w = int(cropim.size[0]*0.75) h = int(cropim.size[1]*0.75) elif zoom == "50%": w = int(cropim.size[0]*0.5) h = int(cropim.size[1]*0.5) elif zoom == "25%": w = int(cropim.size[0]*0.25) h = int(cropim.size[1]*0.25) elif zoom == "10%": w = int(cropim.size[0]*0.1) h = int(cropim.size[1]*0.1) cropzim = cropim.resize((w, h)) pixbuf = image2pixbuf(cropzim) previmage.set_from_pixbuf(pixbuf) def choix_zoom(zoom_image): global zoom zoom = zoom_image.get_active_text() crop_im(im) # change l'image utilisé pour la prévisualisation def change_image(sel_image, label_info): global im choix = sel_image.get_active_text() im = Image.open(CHEMIN+"/"+choix) info = str (choix + " " + im.format + " " + str(im.size) + " " + im.mode) label_info.set_text(info) crop_im(im) # met a jour le cadre et la prévisualisation def maj(entree, sortieCrop, sortieRatio, widget): global rect global angle_rot global ratio if widget == "gauche": rect[0] = int(entree.get_text()) elif widget == "haut": rect[1] = int(entree.get_text()) elif widget == "droite": rect[2] = int(entree.get_text()) elif widget == "bas": rect[3] = int(entree.get_text()) elif widget == "rotation": angle_rot = int(entree.get_text()) ratioheight = rect[3] - rect[1] ratiowidth = rect[2] - rect[0] ratio = float(ratiowidth)/float(ratioheight) sortieCrop.set_text(str(ratiowidth) + " / " + str(ratioheight)) sortieRatio.set_text(" ratio: "+str(ratio)) crop_im(im) # si l'image finale sera redimensionné ou non def check_redim_clicked(widget): global redim if widget.get_active(): redim = True else: redim = False def redimensionner(entree, widget, secwidget): global width_redim global height_redim if widget == "width": width_redim = entree.get_value() height_redim = width_redim / ratio secwidget.set_value(int(height_redim)) elif widget == "height": height_redim = entree.get_value() width_redim = height_redim * ratio secwidget.set_value(int(width_redim)) # aplique les modification a toutes les images def on_save_button_clicked(widget, label_save): tuple_rect = (rect[0],rect[1],rect[2],rect[3]) os.mkdir(repertoire_sortie) n = 0 nt = len (images) for i in images: n = n+1 im = Image.open(CHEMIN+"/"+i) im = im.rotate(angle_rot, 3) im = im.crop(tuple_rect) if redim == True: im = im.resize((width_redim, height_redim)) im.save(repertoire_sortie+"/"+i) label_save.set_text(str(n) + " / " + str(nt) + " images recadrées") if __name__ == "__main__": # verifie que c'est bien un dossier #CHEMIN = sys.argv[1] CHEMIN = "/media/doc/prog/python/image/thunar/13" if os.path.isdir(CHEMIN): fichiers = [] fichiers = os.listdir(CHEMIN) # prépare le répertoire ou seront enregistrées les images repertoire_sortie = CHEMIN + "_recadré" if os.path.isdir(repertoire_sortie): i=1 while os.path.isdir(repertoire_sortie): i = i+1 repertoire_sortie = repertoire_sortie+str(i) # ne prend que les fichiers images images = [] for i in fichiers: ext = os.path.splitext(i) [ 1 ] if ext == ".png" or ext == ".PNG" or ext == ".jpg" or ext == ".JPG" or ext == ".jpeg" or ext == ".JPEG": images.append(i) images.sort() # lance la fenetre pour choisir le cadre fenetregtk() gtk.main()