diff options
author | salvadh0r <dhor@toxic.net.pl> | 2011-11-12 06:26:01 +0100 |
---|---|---|
committer | salvadh0r <dhor@toxic.net.pl> | 2011-11-12 06:26:01 +0100 |
commit | d83f8eb66841f08966cea2257f8b75ccb787935c (patch) | |
tree | 06206b9d7176255794c01b5797f2034712598efd /macrofusion.py | |
download | macrofusion-code-d83f8eb66841f08966cea2257f8b75ccb787935c.zip macrofusion-code-d83f8eb66841f08966cea2257f8b75ccb787935c.tar.gz macrofusion-code-d83f8eb66841f08966cea2257f8b75ccb787935c.tar.bz2 |
new file: CHANGELOG
new file: LICENSE
new file: README
new file: TODO
new file: debian/README.Debian
new file: debian/README.source
new file: debian/changelog
new file: debian/compat
new file: debian/control
new file: debian/copyright
new file: debian/docs
new file: debian/emacsen-install.ex
new file: debian/emacsen-remove.ex
new file: debian/emacsen-startup.ex
new file: debian/init.d.ex
new file: debian/macrofusion.cron.d.ex
new file: debian/macrofusion.default.ex
new file: debian/macrofusion.doc-base.EX
new file: debian/macrofusion.install
new file: debian/manpage.1.ex
new file: debian/manpage.sgml.ex
new file: debian/manpage.xml.ex
new file: debian/menu.ex
new file: debian/postinst.ex
new file: debian/postrm.ex
new file: debian/preinst.ex
new file: debian/prerm.ex
new file: debian/rules
new file: debian/source/format
new file: debian/watch.ex
new file: images/logoMF.png
new file: images/logoSplash.png
new file: locale/fr/LC_MESSAGES/MacroFusion.mo
new file: locale/fr/LC_MESSAGES/MacroFusion.po
new file: locale/pl/LC_MESSAGES/MacroFusion.mo
new file: locale/pl/LC_MESSAGES/MacroFusion.po
new file: macrofusion.desktop
new file: macrofusion.pot
new file: macrofusion.py
new file: ui/DOFuseInterface.glade
new file: ui/Progress.glade
Diffstat (limited to 'macrofusion.py')
-rwxr-xr-x | macrofusion.py | 725 |
1 files changed, 725 insertions, 0 deletions
diff --git a/macrofusion.py b/macrofusion.py new file mode 100755 index 0000000..32aa10d --- /dev/null +++ b/macrofusion.py @@ -0,0 +1,725 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + + +# Licence : GPLv3 voir : http://gplv3.fsf.org/ + +try: + import os, sys + import os.path + import subprocess + import shutil + import gobject + import time + import threading + import multiprocessing + import re + import ConfigParser +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) + +try: + import Image +except: + print('Python Imaging Library is missing.') + +try: + import gtk + import gtk.glade + import pygtk + pygtk.require("2.0") +except: + print('gtk2, pygtk or libglade is missing.') + sys.exit(1) + + +APP = 'MacroFusion' + +if os.path.exists('/usr/share/mfusion/ui/DOFuseInterface.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'): + # print ("System wide install!") + DIR = '/usr/share/locale/' + IMG = '/usr/share/pixmaps/macrofusion/' + UI = '/usr/share/mfusion/ui/' +elif os.path.exists(sys.path[0] + "/ui/DOFuseInterface.glade"): + # print ("Local run!") + DIR = sys.path[0] + '/locale/' + IMG = sys.path[0] + '/images/' + UI = sys.path[0] + '/ui/' +else: + print ("That's me, your MacroFusion. Make your mind - local or system wide install?") + sys.exit(1) + +import locale +import gettext +for module in (gettext, gtk.glade): + module.bindtextdomain(APP, DIR) + module.textdomain(APP) +locale.setlocale(locale.LC_ALL, '') +#gettext.bindtextdomain(APP, DIR) +#gettext.textdomain(APP) +#gettext.install(APP) +_ = gettext.gettext + + + +gobject.threads_init() #Pour que les threads soient lancés au moment opportun. + + + +def toggled_cb(cell, path, user_data): + model, column = user_data + model[path][column] = not model[path][column] + return + +def creer_miniature(chemin,taille): + outfile=donnees.previs_dossier + '/' + os.path.split(chemin)[1] + try: + im = Image.open(chemin) + im.thumbnail(taille) + im.save(outfile, "JPEG") + except IOError: + print _("Generating %s thumbnail failed.") % infile + return outfile + + + +#################################################### +########Classe des données########################## +#################################################### + +class Donnees: + """Données utiles""" + def __init__(self): + self.install_dossier=sys.path[0] #On recupere le dossier d'install + + self.home_dossier = (os.getenv('XDG_CONFIG_HOME') or os.path.expanduser('~/.config')) + '/mfusion' + # self.home_dossier = os.environ['HOME'] #On créé les dossiers pour mettre les preview + self.enfuse_dossier = self.home_dossier + self.previs_dossier = self.enfuse_dossier + "/preview" + if not os.path.isdir(self.enfuse_dossier): + os.makedirs(self.enfuse_dossier) + if not os.path.isdir(self.previs_dossier): + os.makedirs(self.previs_dossier) + + self.default_folder=os.path.expanduser('~/') + self.default_file="" + + def check_install(self, name): + a=False + for dir in os.environ['PATH'].split(":"): + prog = os.path.join(dir, name) + if os.path.exists(prog): + a=True + return a + +############################################################## +###########Classe de l'interface############################## +############################################################## + + +class Interface: + """Interface pour le logiciel d'exposition-fusion enfuse""" + + def __init__(self): + + # Set default icon + gtk.window_set_default_icon_from_file(IMG + 'logoMF.png') + + + self.cpus = multiprocessing.cpu_count() + if not donnees.check_install("enfuse"): + self.messageinthebottle(_("Can't find Enfuse.\nPlease check enblend/enfuse is installed.\nStopping...")) + sys.exit() + + # Check cpus + if self.cpus>1 and donnees.check_install("enfuse-mp"): + print _("Will use all the powers of your CPU!") + self.enfuser = "enfuse-mp" + else: + self.enfuser = "enfuse" + + + #Set the Glade file + self.gui=gtk.glade.XML(fname=UI + "DOFuseInterface.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 ^^ + self.win=self.gui.get_widget("mainwindow") + self.win.set_title('MacroFusion') + + #On chope le reste, et ca, ca va servir... + self.listeimages = self.gui.get_widget("listeimages") + self.buttonajoutfichiers = self.gui.get_widget("buttonajoutfichiers") + self.buttonenleverfichier = self.gui.get_widget("buttonenleverfichier") + self.statusbar = self.gui.get_widget("status1") + self.statusbar.push(1, _("CPU Cores: %s") % self.cpus) + + self.hscaleexp = self.gui.get_widget("hscaleexp") + self.ajus_exp = gtk.Adjustment(value=1, lower=0, upper=1, step_incr=0.1, page_incr=0.1, page_size=0) + self.hscaleexp.set_adjustment(self.ajus_exp) + self.spinbuttonexp = self.gui.get_widget("spinbuttonexp") + self.spinbuttonexp.set_digits(1) + self.spinbuttonexp.set_value(1) + self.spinbuttonexp.set_adjustment(self.ajus_exp) + + self.hscalecont = self.gui.get_widget("hscalecont") + self.ajus_cont = gtk.Adjustment(value=0, lower=0, upper=1, step_incr=0.1, page_incr=0.1, page_size=0) + self.hscalecont.set_adjustment(self.ajus_cont) + self.spinbuttoncont = self.gui.get_widget("spinbuttoncont") + self.spinbuttoncont.set_digits(1) + self.spinbuttoncont.set_value(0) + self.spinbuttoncont.set_adjustment(self.ajus_cont) + + self.hscalesat = self.gui.get_widget("hscalesat") + self.ajus_sat = gtk.Adjustment(value=0.2, lower=0, upper=1, step_incr=0.1, page_incr=0.1, page_size=0) + self.hscalesat.set_adjustment(self.ajus_sat) + self.spinbuttonsat = self.gui.get_widget("spinbuttonsat") + self.spinbuttonsat.set_digits(1) + self.spinbuttonsat.set_value(0.2) + self.spinbuttonsat.set_adjustment(self.ajus_sat) + + self.hscalemu = self.gui.get_widget("hscalemu") + self.ajus_mu = gtk.Adjustment(value=0.5, lower=0, upper=1, step_incr=0.01, page_incr=0.1, page_size=0) + self.hscalemu.set_adjustment(self.ajus_mu) + self.spinbuttonmu = self.gui.get_widget("spinbuttonmu") + self.spinbuttonmu.set_digits(2) + self.spinbuttonmu.set_value(0.5) + self.spinbuttonmu.set_adjustment(self.ajus_mu) + + self.hscalesigma = self.gui.get_widget("hscalesigma") + self.ajus_sigma = gtk.Adjustment(value=0.2, lower=0, upper=1, step_incr=0.01, page_incr=0.1, page_size=0) + self.hscalesigma.set_adjustment(self.ajus_sigma) + self.spinbuttonsigma = self.gui.get_widget("spinbuttonsigma") + self.spinbuttonsigma.set_digits(2) + self.spinbuttonsigma.set_value(0.2) + self.spinbuttonsigma.set_adjustment(self.ajus_sigma) + + self.buttonpreview = self.gui.get_widget("buttonpreview") + self.checkbuttontiff = self.gui.get_widget("checkbuttontiff") + self.checkbuttonjpeg = self.gui.get_widget("checkbuttonjpeg") + self.buttonfusion = self.gui.get_widget("buttonfusion") + self.buttonbeforeafter = self.gui.get_widget("buttonbeforeafter") + self.buttonedit = self.gui.get_widget("buttoneditw") + + self.imagepreview = self.gui.get_widget("imagepreview") + self.imagepreview.set_from_file(IMG + "logoSplash.png") + + self.progressbar = self.gui.get_widget("progressbar") + + self.checkbuttonexif = self.gui.get_widget("checkbuttonexif") + + if not donnees.check_install('exiftool'): + self.messageinthebottle(_("Exiftool missing!\n\n Cannot copy exif info.")) + + #valeurs des options et configurations : + self.check_pyramidelevel = self.gui.get_widget("check_pyramidelevel") + self.spinbuttonlevel = self.gui.get_widget("spinbuttonlevel") + self.check_hardmask = self.gui.get_widget("check_hardmask") + self.check_contwin = self.gui.get_widget("check_contwin") + self.spinbuttoncontwin = self.gui.get_widget("spinbuttoncontwin") + + self.check_courb = self.gui.get_widget("check_courb") + self.check_prctcourb = self.gui.get_widget("check_prctcourb") + self.spinbuttoncourb = self.gui.get_widget("spinbuttoncourb") + self.check_detecbord = self.gui.get_widget("check_detecbord") + self.spinbuttonEdge = self.gui.get_widget("spinbuttonEdge") + # self.spinbuttonEdge.set_value(self.conf.getint('prefs', 'w')) + + self.spinbuttonLceS = self.gui.get_widget("spinbuttonLceS") + self.spinbuttonLceF = self.gui.get_widget("spinbuttonLceF") + self.check_lces = self.gui.get_widget("check_lces") + self.check_lcef = self.gui.get_widget("check_lcef") + + self.check_ciecam = self.gui.get_widget("check_ciecam") + self.check_desatmeth = self.gui.get_widget("check_desatmeth") + self.combobox_desatmet = self.gui.get_widget("combobox_desatmet") + self.spinbuttonlargeurprev = self.gui.get_widget("spinbuttonlargeurprev") + self.spinbuttonhauteurprev = self.gui.get_widget("spinbuttonhauteurprev") + self.checkbuttoncache = self.gui.get_widget("checkbuttoncache") + self.spinbuttoncache = self.gui.get_widget("spinbuttoncache") + self.checkbuttonbloc = self.gui.get_widget("checkbuttonbloc") + self.spinbuttonbloc = self.gui.get_widget("spinbuttonbloc") + self.checkbuttontaillefinale = self.gui.get_widget("checkbuttontaillefinale") + self.spinbuttonlargeurfinale = self.gui.get_widget("spinbuttonlargeurfinale") + self.spinbuttonhauteurfinale = self.gui.get_widget("spinbuttonhauteurfinale") + self.spinbuttonxoff = self.gui.get_widget("spinbuttonxoff") + self.spinbuttonyoff = self.gui.get_widget("spinbuttonyoff") + self.checkbuttonjpegorig = self.gui.get_widget("checkbuttonjpegorig") + self.hscalecomprjpeg = self.gui.get_widget("hscalecomprjpeg") + self.combtiff = self.gui.get_widget("combtiff") + + self.combobox_desatmet.set_active(0) + self.combtiff.set_active(0) + +# Read values from config + self.conf = ConfigParser.ConfigParser() + if os.path.isfile(donnees.enfuse_dossier + '/mfusion.cfg'): + self.conf.read(donnees.enfuse_dossier + '/mfusion.cfg') + if self.conf.has_option('prefs', 'pwidth'): + self.spinbuttonlargeurprev.set_value(self.conf.getint('prefs', 'pwidth')) + if self.conf.has_option('prefs', 'pheight'): + self.spinbuttonhauteurprev.set_value(self.conf.getint('prefs', 'pheight')) + if self.conf.has_option('prefs', 'cachebutton'): + self.checkbuttoncache.set_active(self.conf.getboolean('prefs', 'cachebutton')) + if self.conf.has_option('prefs', 'cachesize'): + self.spinbuttoncache.set_value(self.conf.getint('prefs', 'cachesize')) + if self.conf.has_option('prefs', 'blocbutton'): + self.checkbuttonbloc.set_active(self.conf.getboolean('prefs', 'blocbutton')) + if self.conf.has_option('prefs', 'blocsize'): + self.spinbuttonbloc.set_value(self.conf.getint('prefs', 'blocsize')) + if self.conf.has_option('prefs', 'outsize'): + self.checkbuttontaillefinale.set_active(self.conf.getboolean('prefs', 'outsize')) + if self.conf.has_option('prefs', 'outwidth'): + self.spinbuttonlargeurfinale.set_value(self.conf.getint('prefs', 'outwidth')) + if self.conf.has_option('prefs', 'outheight'): + self.spinbuttonhauteurfinale.set_value(self.conf.getint('prefs', 'outheight')) + if self.conf.has_option('prefs', 'xoff'): + self.spinbuttonxoff.set_value(self.conf.getint('prefs', 'xoff')) + if self.conf.has_option('prefs', 'yoff'): + self.spinbuttonyoff.set_value(self.conf.getint('prefs', 'yoff')) + if self.conf.has_option('prefs', 'jpegdef'): + self.checkbuttonjpegorig.set_active(self.conf.getboolean('prefs', 'jpegdef')) + if self.conf.has_option('prefs', 'jpegcompr'): + self.hscalecomprjpeg.set_value(self.conf.getfloat('prefs', 'jpegcompr')) + if self.conf.has_option('prefs', 'tiffcomp'): + self.combtiff.set_active(self.conf.getint('prefs', 'tiffcomp')) + + #On relie les signaux (cliques sur boutons, cochage des cases, ...) aux fonctions appropriées + dic = { "on_mainwindow_destroy" : self.exit_app, + "on_buttonannuler_clicked" : self.exit_app, + "on_menufilequit_activate" : self.exit_app, + "on_menufileopen_activate" : self.ouverture, + "on_buttonajoutfichiers_clicked" : self.ajout, + "on_menufileadd_activate" : self.ajout, + "on_buttonenleverfichier_clicked" : self.ttenlever, + "on_menufileenlever_activate" : self.enlever, + "on_menufilettenlever_activate" : self.ttenlever, + "on_buttonpreview_clicked" : self.preview, + "on_menufilesave_activate" : self.fusion, + "on_buttonfusion_clicked" : self.fusion, + "on_buttoneditw_clicked" : self.sendto, + "on_buttonbeforeafter_pressed" : self.baswitch, + "on_buttonbeforeafter_released" : self.baswitch, + "on_imagemenuitem10_activate" : self.apropos + } + #Auto-connection des signaux + 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: + # return True + self.stop_now = True + self.closing_app = True + self.save_settings() + self.cleanup() + sys.exit(0) + + def cleanup(self): + for self.files in os.walk(donnees.previs_dossier): + for self.filename in self.files[2]: + os.remove(donnees.previs_dossier + "/" + self.filename) + + def inittreeview(self): + """initialisation de la liste d'images a importer""" + self.liststoreimport = gtk.ListStore(bool, str, str) #création de la listestore qui contiendra les noms d'images + self.listeimages.set_model(self.liststoreimport) #on donne la liststore au l'afficheur treeview + + self.colonneselect = gtk.TreeViewColumn('') #Premiere colonne : + self.listeimages.append_column(self.colonneselect) #on l'ajoute au TreeView + self.select=gtk.CellRendererToggle() #On creer le cellrender pour avoir des boutons toggle + self.colonneselect.pack_start(self.select, True) #on met le cellrender dans la colonne + self.colonneselect.add_attribute(self.select, 'active', 0) #on met les boutons actifs par défaut + + self.colonneimages = gtk.TreeViewColumn(_('Image')) #deuxieme colonne, titre 'Image' + self.listeimages.append_column(self.colonneimages) #on rajoute la colonne dans le treeview + self.cell = gtk.CellRendererText() #Ce sera des cellules de texte + self.colonneimages.pack_start(self.cell, True) #que l'on met dans la colonne + self.colonneimages.add_attribute(self.cell, 'text', 1) #et on specifie que c'est du texte simple + + self.select.connect("toggled", toggled_cb, (self.liststoreimport, 0)) #Pour que les boutons de selection marchent + + + def ouverture(self, widget): + FenOuv=Fenetre_Ouvrir(self.liststoreimport,0) + self.liststoreimport=FenOuv.get_model() + #self.raffraichissementlisteimages() + + def ajout(self, widget): + FenOuv=Fenetre_Ouvrir(self.liststoreimport,1) + self.liststoreimport=FenOuv.get_model() + #self.raffraichissementlisteimages() + + def raffraichissementlisteimages(self): + #self.listeimages.set_model(self.liststoreimport) + self.treeselectionsuppr=self.listeimages.get_selection() #pour récupérer quels fichiers sont selectionnés + self.treeselectionsuppr.set_mode(gtk.SELECTION_MULTIPLE) #Pour pouvoir en selectionner plusieurs + + def enlever(self, widget): + self.treeselectionsuppr=self.listeimages.get_selection() #pour récupérer quels fichiers sont selectionnés + self.treeselectionsuppr.set_mode(gtk.SELECTION_MULTIPLE) #Pour pouvoir en selectionner plusieurs + (model, pathlist) = self.treeselectionsuppr.get_selected_rows() + for i in pathlist: + treeiter = model.get_iter(i) + self.liststoreimport.remove(treeiter) + + def ttenlever(self, widget): + self.liststoreimport.clear() + + def preview(self, widget): + self.taille=(self.spinbuttonlargeurprev.get_value(), self.spinbuttonhauteurprev.get_value()) + self.name=donnees.previs_dossier + "/" + "preview.jpg" + 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.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.")) + + def get_options(self): + options=["--exposure-weight=" + str(self.spinbuttonexp.get_value()), + "--exposure-mu=" + str(self.spinbuttonmu.get_value()), + "--exposure-sigma=" + str(self.spinbuttonsigma.get_value()), + "--saturation-weight=" + str(self.spinbuttonsat.get_value()), + "--contrast-weight=" + str(self.spinbuttoncont.get_value())] + if self.check_pyramidelevel.get_active(): + options.append('-l ' + str(self.spinbuttonlevel.get_value_as_int())) + if self.check_hardmask.get_active(): + options.append('--hard-mask') + if self.check_contwin.get_active(): + options.append('--contrast-window-size=' + str(self.spinbuttoncontwin.get_value_as_int())) + if self.check_courb.get_active(): + if self.check_prctcourb.get_active(): + options.append('--contrast-min-curvature=' + str(self.spinbuttoncourb.get_value()) + "%") + else: + options.append('--contrast-min-curvature=' + str(self.spinbuttoncourb.get_value())) + if self.check_detecbord.get_active(): + opts='--contrast-edge-scale=' + str(self.spinbuttonEdge.get_value()) + ':' + if self.check_lces.get_active(): + opts+=str(self.spinbuttonLceS.get_value()) + '%:' + else: + opts+=str(self.spinbuttonLceS.get_value()) + ':' + + if self.check_lcef.get_active(): + opts+=str(self.spinbuttonLceF.get_value()) + '%' + else: + opts+=str(self.spinbuttonLceF.get_value()) + '' + + options.append(opts) + + + # + str(self.spinbuttonLceF.get_value()) + '%') + if self.check_ciecam.get_active(): + options.append('-c') + if self.check_desatmeth.get_active(): + opt={-1:None, 0:"average", 1:'l-star', 2:'lightness', 3:'value', 4:'luminance'} + options.append('--gray-projector=' + opt[self.combobox_desatmet.get_active()]) + if not self.checkbuttoncache.get_active(): + options.append('-m ' + str(self.spinbuttoncache.get_value_as_int())) + if not self.checkbuttonbloc.get_active(): + options.append('-b ' + str(self.spinbuttonbloc.get_value_as_int())) + if not self.checkbuttontaillefinale.get_active(): + options.append('-f ' + str(self.spinbuttonlargeurfinale.get_value_as_int()) + 'x' + str(self.spinbuttonhauteurfinale.get_value_as_int()) + 'x' + str(self.spinbuttonxoff.get_value_as_int()) + 'x' + str(self.spinbuttonyoff.get_value_as_int())) + if self.name.endswith(('.tif', '.tiff', '.TIF', '.TIFF')): + tiffopt={0:"NONE", 1:"PACKBITS", 2:"LZW", 3:"DEFLATE"} + options.append("--compression=" + tiffopt[self.combtiff.get_active()]) + if self.name.endswith(('.jpg', '.jpeg', '.JPG', '.JPEG')) and (not self.checkbuttonjpegorig.get_active()): + options.append("--compression=" + str(int(self.hscalecomprjpeg.get_value()))) + return options + + def pulsate(self): + if self.thread_preview.isAlive(): #Tant que le thread est en cours, + self.progressbar.set_text(_("Calculating preview...")) + self.progressbar.pulse() #on fait pulser la barre + return True #et on renvoie True pour que gobject.timeout recommence + else: + self.progressbar.set_fraction(1) + self.progressbar.set_text(_("Preview generated")) + self.imagepreview.set_from_file(donnees.previs_dossier + "/" + "preview.jpg") + return False + + def baswitch(self, widget): + if (not int(self.buttonbeforeafter.get_relief())) and (os.path.exists(donnees.previs_dossier + "/preview_.jpg")): + self.buttonbeforeafter.props.relief = gtk.RELIEF_NONE + self.imagepreview.set_from_file(donnees.previs_dossier + "/preview_.jpg") + 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): + self.name+=".jpg" + self.enroute('') + + def sendto(self, widget): + self.name=(donnees.previs_dossier + "/sendto.jpg") + + if self.enroute(self.name) == -1: + self.messageinthebottle(_("No preview, no output, no edit.\n\n Game Over.")) + return + + def messageinthebottle(self, message): + 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 enroute(self, issend): + self.issend=issend + self.liste_images=[] + for item in self.liststoreimport: + if item[0]: + self.liste_images.append(item[2]) + 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.")) + return -1 + command=[Gui.enfuser, "-o", self.name] + self.get_options() + self.liste_images + ProFus=Progress_Fusion(command, self.issend) + + + def apropos(self, widget): + self.fen=AproposFen() + + def save_settings(self): + conf = ConfigParser.ConfigParser() + conf.add_section('prefs') + # conf.set('prefs', 'w', self.spinbuttonEdge.get_value_as_int()) + conf.set('prefs', 'pwidth', self.spinbuttonlargeurprev.get_value_as_int()) + conf.set('prefs', 'pheight', self.spinbuttonhauteurprev.get_value_as_int()) + conf.set('prefs', 'cachebutton', self.checkbuttoncache.get_active()) + conf.set('prefs', 'cachesize', self.spinbuttoncache.get_value_as_int()) + conf.set('prefs', 'blocbutton', self.checkbuttonbloc.get_active()) + conf.set('prefs', 'blocsize', self.spinbuttonbloc.get_value_as_int()) + conf.set('prefs', 'outsize', self.checkbuttontaillefinale.get_active()) + conf.set('prefs', 'outwidth', self.spinbuttonlargeurfinale.get_value_as_int()) + conf.set('prefs', 'outheight', self.spinbuttonhauteurfinale.get_value_as_int()) + conf.set('prefs', 'xoff', self.spinbuttonxoff.get_value_as_int()) + conf.set('prefs', 'yoff', self.spinbuttonyoff.get_value_as_int()) + conf.set('prefs', 'jpegdef', self.checkbuttonjpegorig.get_active()) + conf.set('prefs', 'jpegcompr', int(self.hscalecomprjpeg.get_value())) + conf.set('prefs', 'tiffcomp', str(self.combtiff.get_active())) + + if not os.path.exists(donnees.enfuse_dossier): + os.makedirs(donnees.enfuse_dossier) + conf.write(file(donnees.enfuse_dossier + '/mfusion.cfg', 'w')) + + # Also, save accel_map: + # gtk.accel_map_save(self.config_dir + '/accel_map') + + return + +#################################################################### +###########Classe pour choisir les images a fusionner############### +#################################################################### + +class Fenetre_Ouvrir: + """La classe qui ouvre la fenetre de choix de fichiers, et qui retourne le ListStore par la methode get_model""" + def __init__(self,model,bitajout): + """Lance la fenetre de selection et créé la listsore a partir des fichiers selectionnés""" + self.filtre=gtk.FileFilter() + self.filtre.add_mime_type("image/jpeg") + self.filtre.add_mime_type("image/tiff") + self.liststoreimport=model #on repart de l'ancien modele + if bitajout: + self.fenetre_ouvrir = gtk.FileChooserDialog(_("Add images..."), + None, + gtk.FILE_CHOOSER_ACTION_OPEN, + (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) + self.fenetre_ouvrir.set_select_multiple(True) + self.fenetre_ouvrir.set_current_folder(donnees.default_folder) + self.fenetre_ouvrir.set_filter(self.filtre) + else: + self.fenetre_ouvrir = gtk.FileChooserDialog(_("Open images..."), + None, + gtk.FILE_CHOOSER_ACTION_OPEN, + (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) + self.fenetre_ouvrir.set_select_multiple(True) + self.fenetre_ouvrir.set_current_folder(donnees.default_folder) + self.fenetre_ouvrir.set_filter(self.filtre) + self.liststoreimport.clear() #On remet le model a 0 (oublie des anciennes images) + + if(self.fenetre_ouvrir.run() == gtk.RESPONSE_OK): + self.fichiers = self.fenetre_ouvrir.get_filenames() + donnees.default_file=self.fichiers[0] + for fichier in self.fichiers: + self.liststoreimport.append([1,os.path.basename(fichier),fichier]) + donnees.default_folder=self.fenetre_ouvrir.get_current_folder() + self.fenetre_ouvrir.destroy() + + def get_model(self): + """ Retourne la liststore """ + if self.liststoreimport: + return self.liststoreimport + else: + return None + + +##################################################################### +#########Classe pour la fenetre pour choisir le fichier final######## +##################################################################### + +class Fenetre_Parcourir: + """La classe qui ouvre la fenetre de choix pour enregistrer le fichier""" + def __init__(self): + + self.fenetre_ouvrir = gtk.FileChooserDialog(_("Save file..."), + None, + gtk.FILE_CHOOSER_ACTION_SAVE, + (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) + self.fenetre_ouvrir.set_current_folder(donnees.default_folder) + # self.fenetre_ouvrir.set_filename(donnees.default_file) + self.fenetre_ouvrir.set_current_name('output.jpg') + self.fenetre_ouvrir.set_do_overwrite_confirmation(True) + if (self.fenetre_ouvrir.run() == gtk.RESPONSE_OK): + self.resultat=self.fenetre_ouvrir.get_filename() + + self.fenetre_ouvrir.destroy() + + def get_name(self): + try: + return self.resultat + except AttributeError: + return "" + + + +##################################################################### +#########Thread pour la prévisualisation############################# +##################################################################### + +class Thread_Preview(threading.Thread): + def __init__(self, taille, options, liste): + threading.Thread.__init__ (self) + self.taille=taille + self.options=options + self.liste=liste + + def run(self): + images_a_fusionner=[] + + for item in self.liste: + if item[0]: + chemin_miniature=creer_miniature(item[2],(int(self.taille[0]), int(self.taille[1]))) + images_a_fusionner.append(chemin_miniature) + if os.path.exists(donnees.previs_dossier + "/preview.jpg"): + shutil.copy(donnees.previs_dossier + "/" + "preview.jpg", donnees.previs_dossier + "/" + "preview_.jpg") + command=[Gui.enfuser, "-o", donnees.previs_dossier + "/" + "preview.jpg"] + self.options + images_a_fusionner + # print (command) + preview_process=subprocess.Popen(command, stdout=subprocess.PIPE) + preview_process.wait() + + + +####################################################################### +#########Fenetre de progression lors de la fusion finale############### +####################################################################### + +class Progress_Fusion: + def __init__(self, command, issend): + self.issend=issend + self.progress = gtk.glade.XML(fname=UI + "Progress.glade", domain=APP) + self.progress_win = self.progress.get_widget("dialog1") + self.progress_label = self.progress.get_widget("progress_label") + self.info_label = self.progress.get_widget("info_label") + self.progress_bar = self.progress.get_widget("progressbar1") + self.progress_stop_button = self.progress.get_widget("stop_button") + self.dic1 = {"on_stop_button_clicked" : self.close_progress, + "on_dialog1_destroy" : self.close_progress} + self.progress.signal_autoconnect(self.dic1) + self.info_label.set_text(_('Fusion images...')) + + self.thread_fusion = Thread_Fusion(command, self.issend) #On prepare le thread qui va faire tout le boulot + self.thread_fusion.start() #On le lance + timer = gobject.timeout_add (100, self.pulsate) + + def pulsate(self): + if self.thread_fusion.isAlive(): #Tant que le thread est en cours, + self.progress_bar.set_text(_("Fusion, please wait...")) + self.progress_bar.pulse() #on fait pulser la barre + return True #et on renvoie True pour que gobject.timeout recommence + else: + self.progress_bar.set_fraction(1) + self.progress_bar.set_text(_("Fused !")) + self.close_progress(self) + return False + + def close_progress(self, widget): + self.progress_win.destroy() + + + +############################################################################## +###########Thread de fusion des vraies images################################# +############################################################################## + +class Thread_Fusion(threading.Thread): + def __init__(self, command, issend): + threading.Thread.__init__ (self) + self.command=command + self.issend=issend + + def run(self): + fusion_process=subprocess.Popen(self.command, stdout=subprocess.PIPE) + fusion_process.wait() + # fusion_process=subprocess.call(self.command) + if Gui.checkbuttonexif.get_active(): + exif_copy = subprocess.Popen(["exiftool", "-tagsFromFile", "-overwrite_original", Gui.liste_images[0], Gui.name]) + exif_copy.wait() + if len(self.issend) > 0: + subprocess.Popen(['gimp', self.issend], stdout=subprocess.PIPE) + +######################################## +#### Classe de la fenêtre a propos #### +######################################## + +class AproposFen: + def __init__(self): + # self.about = gtk.glade.XML(donnees.install_dossier + "/Apropos.glade", domain=APP) + # self.aboutdialog = self.about.get_widget("aboutdialog1") + self.aboutdialog = gtk.AboutDialog() + self.aboutdialog.set_name("MacroFusion") + self.aboutdialog.set_modal(True) + self.aboutdialog.set_position(gtk.WIN_POS_CENTER) + self.aboutdialog.set_version('0.5') + 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_logo(self.pixbuf) + self.aboutdialog.connect("response", self.close_about) + self.aboutdialog.show() + + + def close_about(self, widget, event): + self.aboutdialog.destroy() + + +########################################################### +#### Initialisation et appel de la classe principale #### +########################################################### + +if __name__ == "__main__": + + donnees=Donnees() #Initialisation des variables + Gui = Interface() #Initialise l'interface + gtk.main() #Lance la boucle principale |