summaryrefslogtreecommitdiffstats
path: root/macrofusion.py
diff options
context:
space:
mode:
authorsalvadh0r <dhor@toxic.net.pl>2011-11-24 19:04:35 +0100
committersalvadh0r <dhor@toxic.net.pl>2011-11-24 19:04:35 +0100
commitaea400aff6da1875a905ad1549ac8f466d094df5 (patch)
tree2acd96e3d464f00b0dbb8cebfd6b12f107fc81ad /macrofusion.py
parentd5b7ce288f6f37f00e0f2e9bd3d86479a0e5d5a0 (diff)
downloadmacrofusion-code-aea400aff6da1875a905ad1549ac8f466d094df5.zip
macrofusion-code-aea400aff6da1875a905ad1549ac8f466d094df5.tar.gz
macrofusion-code-aea400aff6da1875a905ad1549ac8f466d094df5.tar.bz2
0.7.2
Diffstat (limited to 'macrofusion.py')
-rwxr-xr-xmacrofusion.py199
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