diff options
author | salvadh0r <dhor@toxic.net.pl> | 2011-11-24 19:04:35 +0100 |
---|---|---|
committer | salvadh0r <dhor@toxic.net.pl> | 2011-11-24 19:04:35 +0100 |
commit | aea400aff6da1875a905ad1549ac8f466d094df5 (patch) | |
tree | 2acd96e3d464f00b0dbb8cebfd6b12f107fc81ad /macrofusion.py | |
parent | d5b7ce288f6f37f00e0f2e9bd3d86479a0e5d5a0 (diff) | |
download | macrofusion-code-aea400aff6da1875a905ad1549ac8f466d094df5.zip macrofusion-code-aea400aff6da1875a905ad1549ac8f466d094df5.tar.gz macrofusion-code-aea400aff6da1875a905ad1549ac8f466d094df5.tar.bz2 |
0.7.2
Diffstat (limited to 'macrofusion.py')
-rwxr-xr-x | macrofusion.py | 199 |
1 files changed, 120 insertions, 79 deletions
diff --git a/macrofusion.py b/macrofusion.py index 21aa4d5..be59564 100755 --- a/macrofusion.py +++ b/macrofusion.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- -# Licence : GPLv3 voir : http://gplv3.fsf.org/ +# License : GPLv3 : http://gplv3.fsf.org/ try: import os, sys @@ -16,6 +16,8 @@ try: import re import ConfigParser import operator + import cairo + import random except: print('An error occured. Python or one of its sub modules is absent...\nIt would be wise to check your python installation.') sys.exit(1) @@ -42,19 +44,25 @@ global session_options_bak session_options_bak=[] APP = 'MacroFusion' +__VERSION__='0.7.2' +__LICENSE__='GPL' +__COPYRIGHT__='Dariusz Duma' +__WEBSITE__='http://sourceforge.net/p/macrofusion' if os.path.exists('/usr/share/mfusion/ui/DOFuseInterface2.glade') \ and os.path.exists('/usr/share/mfusion/ui/Progress.glade') \ - and os.path.exists('/usr/share/pixmaps/macrofusion/logoMF.png') \ - and os.path.exists('/usr/share/pixmaps/macrofusion/logoSplash.png'): + and os.path.exists('/usr/share/pixmaps/macrofusion.png') \ + and os.path.exists('/usr/share/mfusion/images/logoSplash.png'): # print ("System wide install!") DIR = '/usr/share/locale/' - IMG = '/usr/share/pixmaps/macrofusion/' + IMG = '/usr/share/pixmaps/' + IMG2 = '/usr/share/mfusion/images/' UI = '/usr/share/mfusion/ui/' elif os.path.exists(sys.path[0] + "/ui/DOFuseInterface2.glade"): # print ("Local run!") DIR = sys.path[0] + '/locale/' IMG = sys.path[0] + '/images/' + IMG2 = sys.path[0] + '/images/' UI = sys.path[0] + '/ui/' else: print ("That's me, your MacroFusion. Make your mind - local or system wide install?") @@ -130,8 +138,7 @@ class Interface: def __init__(self): # Set default icon - gtk.window_set_default_icon_from_file(IMG + 'logoMF.png') - + gtk.window_set_default_icon_from_file(IMG + 'macrofusion.png') self.cpus = multiprocessing.cpu_count() if not donnees.check_install("enfuse"): @@ -144,11 +151,9 @@ class Interface: self.enfuser = "enfuse-mp" else: self.enfuser = "enfuse" - #Set the Glade file self.gui=gtk.glade.XML(fname=UI + "DOFuseInterface2.glade", domain=APP) - #Dans la foulee on chope la fenetre principale, ca sert a rien c'est pour #montrer qu'on peut le faire c'est tout ^^ @@ -210,7 +215,7 @@ class Interface: self.buttonedit = self.gui.get_widget("buttoneditw") self.imagepreview = self.gui.get_widget("imagepreview") - self.imagepreview.set_from_file(IMG + "logoSplash.png") + self.imagepreview.set_from_file(IMG2 + "logoSplash.png") self.progressbar = self.gui.get_widget("progressbar") @@ -252,7 +257,7 @@ class Interface: self.checkbuttonjpegorig = self.gui.get_widget("checkbuttonjpegorig") self.hscalecomprjpeg = self.gui.get_widget("hscalecomprjpeg") self.combtiff = self.gui.get_widget("combtiff") - + self.checkbutton_a5_align = self.gui.get_widget("checkbutton_a5_align") self.checkbutton_a5_crop = self.gui.get_widget("checkbutton_a5_crop") self.checkbutton_a5_shift = self.gui.get_widget("checkbutton_a5_shift") @@ -262,7 +267,6 @@ class Interface: self.combobox_desatmet.set_active(0) self.combtiff.set_active(0) - if not donnees.check_install('exiftool'): self.checkbuttonexif.set_sensitive(False) @@ -331,17 +335,14 @@ class Interface: "on_buttonbeforeafter_pressed" : self.baswitch, "on_buttonbeforeafter_released" : self.baswitch, "on_entry_editor_activate" : self.check_editor, - # "on_entry_editor_focus_out_event" : self.check_editor, "on_imagemenuitem10_activate" : self.apropos } #Auto-connection des signaux - # self.entryedit_field.connect("activate", self.apropos) - #self.entryedit_field.connect("focus_out_event", self.apropos) self.gui.signal_autoconnect(dic) #initialisation de la liste d'images a fusionner self.inittreeview() - + def exit_app(self, action): # cancel = self.autosave_image() # if cancel: @@ -354,7 +355,7 @@ class Interface: def check_editor(self, action): if not donnees.check_install(self.entryedit_field.get_text()): - Gui.messageinthebottle(_("No such application!\n\n Cannot find " + self.entryedit_field.get_text() + _(".\n\n Revert to default value."))) + Gui.messageinthebottle(_("No such application!\n\n Cannot find ") + self.entryedit_field.get_text() + _(".\n\n Revert to default value.")) self.entryedit_field.set_text("gimp") return False return True @@ -428,15 +429,17 @@ class Interface: item=0 if len(self.liststoreimport)>0: self.ref=zip(*self.liststoreimport)[0] - for item in self.ref: - if item: - item=-1 - self.thread_preview = Thread_Preview(self.taille, self.get_options(), self.get_options_align(), self.liststoreimport) - self.thread_preview.start() - timer = gobject.timeout_add (100, self.pulsate) - break - if item==0: - self.messageinthebottle(_("Please add some images!\n\n Can't fuse anything.")) + for item2 in self.ref: + if item2: + item+=1 + if item>1: + self.thread_preview = Thread_Preview(self.taille, self.get_options(), self.get_options_align(), self.liststoreimport) + self.thread_preview.start() + timer = gobject.timeout_add (100, self.pulsate) + break + if item<=1: + self.messageinthebottle(_("Please add or activate at least two images.\n\n Cannot do anything smart with the one or no image.")) + def get_options_align(self): self.options_align=[] @@ -514,13 +517,12 @@ class Interface: elif os.path.exists(donnees.previs_dossier + "/preview_.jpg"): self.buttonbeforeafter.props.relief = gtk.RELIEF_NORMAL self.imagepreview.set_from_file(donnees.previs_dossier + "/preview.jpg") - # self.buttonbeforeafter.set_label("gfdgdf") def fusion(self,widget): FenPar=Fenetre_Parcourir() self.name = FenPar.get_name() if self.name: - if not re.search('.jpeg$|.jpg$|.tiff$', self.name, flags=re.IGNORECASE): + if not re.search('\\.jpeg$|\\.jpg$|\\.tiff$|\\.tif$', self.name, flags=re.IGNORECASE): self.name+=".jpg" self.enroute('') @@ -537,6 +539,27 @@ class Interface: self.messaga=gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_OK, message_format=(message)) if self.messaga.run() == gtk.RESPONSE_OK: self.messaga.destroy() + + def get_exif(self, fichier): + tags2='' + tags={} + exifinfo=None + try: + im = Image.open(fichier) + if hasattr( im, '_getexif' ): + exifinfo = im._getexif() + if exifinfo != None: + for tag, value in exifinfo.items(): + decoded = TAGS.get(tag, tag) + tags[decoded] = value + if tags.get('Model'): tags2=(_("<b>Model:</b> ") + str(tags['Model']) + "\n") + if tags.get('DateTimeOriginal'): tags2+=(_("<b>Date:</b> ") + str(tags['DateTimeOriginal']) + "\n") + if tags.get('FocalLength'): tags2+=(_("<b>Focal length:</b> ") + str(int(int(tags['FocalLength'][0])/int(tags['FocalLength'][1]))) + "mm \n") + if tags.get('FNumber'): tags2+=(_("<b>Aperture:</b> F/") + str(float(float(tags['FNumber'][0])/float(tags['FNumber'][1]))) + "\n") + if tags.get('ExposureTime'): tags2+=(_("<b>Exposure Time:</b> ") + str(str(tags['ExposureTime'][0]/10) + "/" + str(tags['ExposureTime'][1]/10) + " s. \n")) + except IOError: + print "failed to identify", file + return tags2 def enroute(self, issend): self.issend=issend @@ -553,8 +576,8 @@ class Interface: if self.liste_images.count(self.name): self.messageinthebottle(_("Can't overwrite input image!\n\n Please change the output filename.")) return -1 - if len(self.liste_images) == 0: - self.messageinthebottle(_("Please add some images!\n\n Can't fuse anything.")) + if len(self.liste_images) <= 1: + self.messageinthebottle(_("Please add or activate at least two images.\n\n Cannot do anything smart with the one or no image.")) return -1 command_a=['align_image_stack', '-a', donnees.previs_dossier + '/out'] + self.get_options_align() + self.liste_images command=[Gui.enfuser, "-o", self.name] + self.get_options() + self.liste_aligned @@ -594,8 +617,29 @@ class Interface: return - - + def put_files_to_the_list(self, fichiers): + + self.fichiers=fichiers + self.tags2='' + self.badfiles=[] + for fichier in self.fichiers: + if re.search('\\.jpg$|\\.jpeg$|\\.tiff$|\\.tif$', fichier, flags=re.IGNORECASE): + im = Image.open(fichier) + self.size=im.size + self.tags2 = Gui.get_exif(fichier) + if not self.tags2: + self.tags2='' + self.tooltip=("\n" + _("<b>Filename:</b> ") + os.path.basename(fichier) + "\n"+_("<b>Resolution:</b> ") + str(str(self.size[0]) + "x" + str(self.size[1])) + "\n" + self.tags2) + self.liststoreimport.append([1,os.path.basename(fichier), fichier, gtk.gdk.pixbuf_new_from_file_at_size(fichier, 128, 128), self.tooltip]) + else: + self.badfiles.append(fichier) + if len(self.badfiles)>0: + messaga=_("Only JPEG and TIFF files are allowed.\n\nCannot open:\n") + for itz in self.badfiles: + messaga+=itz + "\n" + Gui.messageinthebottle(messaga) + return + #################################################################### ###########Classe pour choisir les images a fusionner############### #################################################################### @@ -616,6 +660,10 @@ class Fenetre_Ouvrir: self.fenetre_ouvrir.set_select_multiple(True) self.fenetre_ouvrir.set_current_folder(donnees.default_folder) self.fenetre_ouvrir.set_filter(self.filtre) + self.fenetre_ouvrir.use_preview = True + self.previewidget = gtk.Image() + self.fenetre_ouvrir.set_preview_widget(self.previewidget) + self.fenetre_ouvrir.connect("update-preview", self.update_thumb_preview, self.previewidget) else: self.fenetre_ouvrir = gtk.FileChooserDialog(_("Open images..."), None, @@ -624,58 +672,41 @@ class Fenetre_Ouvrir: self.fenetre_ouvrir.set_select_multiple(True) self.fenetre_ouvrir.set_current_folder(donnees.default_folder) self.fenetre_ouvrir.set_filter(self.filtre) + self.fenetre_ouvrir.use_preview = True + self.previewidget = gtk.Image() + self.fenetre_ouvrir.set_preview_widget(self.previewidget) + self.fenetre_ouvrir.connect("update-preview", self.update_thumb_preview, self.previewidget) self.liststoreimport.clear() #On remet le model a 0 (oublie des anciennes images) - if(self.fenetre_ouvrir.run() == gtk.RESPONSE_OK): + if (self.fenetre_ouvrir.run() == gtk.RESPONSE_OK): self.fichiers = self.fenetre_ouvrir.get_filenames() self.tags2='' - donnees.default_file=self.fichiers[0] - for fichier in self.fichiers: - try: - im = Image.open(fichier) - self.tags={} - self.size=im.size - if hasattr( im, '_getexif' ): - exifinfo = im._getexif() - if exifinfo != None: - for tag, value in exifinfo.items(): - decoded = TAGS.get(tag, tag) - self.tags[decoded] = value - self.tags2=(_("<b>Model:</b> ") + str(self.tags['Model']) + "\n") - self.tags2+=(_("<b>Date:</b> ") + str(self.tags['DateTimeOriginal']) + "\n") - self.tags2+=(_("<b>Focal length:</b> ") + str(int(int(self.tags['FocalLength'][0])/int(self.tags['FocalLength'][1]))) + "mm \n") - self.tags2+=(_("<b>Aperture:</b> F/") + str(float(float(self.tags['FNumber'][0])/float(self.tags['FNumber'][1]))) + "\n") - self.tags2+=(_("<b>Exposure Time:</b> ") + str(str(self.tags['ExposureTime'][0]/10) + "/" + str(self.tags['ExposureTime'][1]/10) + " s. \n")) - except IOError: - print "failed to identify", file - - self.tooltip=("\n" + _("<b>Filename:</b> ") + os.path.basename(fichier) + "\n"+_("<b>Resolution:</b> ") + str(str(self.size[0]) + "x" + str(self.size[1])) + "\n" + self.tags2) - self.liststoreimport.append([1,os.path.basename(fichier), fichier, gtk.gdk.pixbuf_new_from_file_at_size(fichier, 128, 128), self.tooltip]) - + self.badfiles=[] + donnees.default_file = self.fichiers[0] + Gui.put_files_to_the_list(self.fichiers) + donnees.default_folder=self.fenetre_ouvrir.get_current_folder() self.fenetre_ouvrir.destroy() - + + def update_thumb_preview(self, file_chooser, preview): + if not self.fenetre_ouvrir.use_preview: + return + filename = file_chooser.get_preview_filename() + try: + pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(filename, 320, 320) + self.previewidget.set_from_pixbuf(pixbuf) + self.have_preview = True + except: + self.have_preview = False + self.fenetre_ouvrir.set_preview_widget_active(self.have_preview) + return + def get_model(self): """ Retourne la liststore """ if self.liststoreimport: return self.liststoreimport else: return None - - def get_exif_data(fname): - """Get embedded EXIF data from image file.""" - ret = {} - try: - img = Image.open(fname) - if hasattr( img, '_getexif' ): - exifinfo = img._getexif() - if exifinfo != None: - for tag, value in exifinfo.items(): - decoded = TAGS.get(tag, tag) - ret[decoded] = value - except IOError: - print 'IOERROR ' + fname - return ret ##################################################################### #########Classe pour la fenetre pour choisir le fichier final######## @@ -703,8 +734,6 @@ class Fenetre_Parcourir: return self.resultat except AttributeError: return "" - - ##################################################################### #########Thread pour la prévisualisation############################# @@ -731,6 +760,9 @@ class Thread_Preview(threading.Thread): images_a_align.append(chemin_miniature) images_a_fusionner.append(donnees.previs_dossier + "/test" + format(index, "04d") + ".tif") index += 1 + if (len(images_a_fusionner))<=1: + Gui.messageinthebottle(_("Please add two or more images.\n\n Cannot do anything smart with the one image.")) + return if not Gui.checkbutton_a5_align.get_active(): images_a_fusionner=images_a_align if os.path.exists(donnees.previs_dossier + "/preview.jpg"): @@ -829,9 +861,11 @@ class AproposFen: self.aboutdialog.set_name("MacroFusion") self.aboutdialog.set_modal(True) self.aboutdialog.set_position(gtk.WIN_POS_CENTER) - self.aboutdialog.set_version('0.7') - self.aboutdialog.set_comments('A GTK Gui for the excellent Enfuse.\n Based on EnfuseGui by Chez Gholyo.\n\n(c) 2011 Dariusz Duma <dhor@toxic.net.pl>') - self.pixbuf=gtk.gdk.pixbuf_new_from_file(IMG + "logoMF.png") + self.aboutdialog.set_version(__VERSION__) + self.aboutdialog.set_comments('A GTK Gui for the excellent Enfuse.\n Based on EnfuseGui by Chez Gholyo.\n\n2011 (c) Dariusz Duma\n<dhor@toxic.net.pl>') + # self.aboutdialog.set_copyright(__COPYRIGHT__) + self.aboutdialog.set_website(__WEBSITE__) + self.pixbuf=gtk.gdk.pixbuf_new_from_file(IMG + "macrofusion.png") self.aboutdialog.set_logo(self.pixbuf) self.aboutdialog.connect("response", self.close_about) self.aboutdialog.show() @@ -847,6 +881,13 @@ class AproposFen: if __name__ == "__main__": - donnees=Donnees() #Initialisation des variables - Gui = Interface() #Initialise l'interface - gtk.main() #Lance la boucle principale + donnees=Donnees() #Variables + Gui = Interface() #Interface + + if (len(sys.argv)>1): #Init with given files + fichiers=sys.argv[1:] + Gui.put_files_to_the_list(fichiers) +# if len(Gui.liststoreimport)==0: +# Gui.messageinthebottle(_("\nCan work only with JPEG or TIFF files.")) + + gtk.main() #The rest |