Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EnfusePanel.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
10 /* This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This software is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public
21  * License along with this software. If not, see
22  * <http://www.gnu.org/licenses/>.
23  *
24  */
25 
26 #include "EnfusePanel.h"
27 #include <wx/stdpaths.h>
28 #include <wx/propgrid/advprops.h>
29 #include "base_wx/platform.h"
30 #include "base_wx/wxPlatform.h"
32 #include "base_wx/Executor.h"
33 #include <wx/fileconf.h>
34 #include <wx/wfstream.h>
35 #include <wx/sstream.h>
36 #include "hugin_utils/utils.h"
38 #include "base_wx/LensTools.h"
39 #include "base_wx/wxutils.h"
40 #include "CreateBrightImgDlg.h"
41 
43 class EnfuseDropTarget : public wxFileDropTarget
44 {
45 public:
46  EnfuseDropTarget(EnfusePanel* parent) : wxFileDropTarget()
47  {
48  m_enfusePanel = parent;
49  }
50 
51  bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
52  {
53  // try to add as images
54  wxArrayString files;
55  for (unsigned int i = 0; i < filenames.GetCount(); i++)
56  {
57  wxFileName file(filenames[i]);
58  if (file.GetExt().CmpNoCase("jpg") == 0 ||
59  file.GetExt().CmpNoCase("jpeg") == 0 ||
60  file.GetExt().CmpNoCase("tif") == 0 ||
61  file.GetExt().CmpNoCase("tiff") == 0 ||
62  file.GetExt().CmpNoCase("png") == 0 ||
63  file.GetExt().CmpNoCase("bmp") == 0 ||
64  file.GetExt().CmpNoCase("gif") == 0 ||
65  file.GetExt().CmpNoCase("pnm") == 0 ||
66  file.GetExt().CmpNoCase("sun") == 0 ||
67  file.GetExt().CmpNoCase("hdr") == 0 ||
68  file.GetExt().CmpNoCase("viff") == 0)
69  {
70  files.push_back(file.GetFullPath());
71  };
72  };
73  // we got some images to add.
74  if (!files.empty())
75  {
76  for (auto& f : files)
77  {
79  };
80  };
81  return true;
82  }
83 private:
85 };
86 
87 // load wxPropertyGrid settings from string
88 void SetPropertyGridContent(wxPropertyGrid* grid, const wxString values)
89 {
90  wxArrayString properties = wxStringTokenize(values, "|");
91  for (size_t i = 0; i < properties.size(); ++i)
92  {
93  wxArrayString prop = wxStringTokenize(properties[i], ":");
94  if (prop.size() == 3)
95  {
96  if (prop[1] == "double")
97  {
98  double doubleVal;
99  if (prop[2].ToCDouble(&doubleVal))
100  {
101  grid->SetPropertyValue(prop[0], doubleVal);
102  };
103  }
104  else
105  {
106  if (prop[1] == "long")
107  {
108  long longVal;
109  if (prop[2].ToLong(&longVal))
110  {
111  grid->SetPropertyValue(prop[0], longVal);
112  }
113  }
114  else
115  {
116  if (prop[1] == "bool")
117  {
118  if (prop[2] == "true")
119  {
120  grid->SetPropertyValue(prop[0], true);
121  }
122  else
123  {
124  grid->SetPropertyValue(prop[0], false);
125  };
126  }
127  else
128  {
129  // unknown type, currently not implemented
130  };
131  };
132  };
133  };
134  };
135 }
136 
137 // save wxPropertyGrid settings into a string
138 wxString GetPropertyGridContent(const wxPropertyGrid* grid)
139 {
140  wxPropertyGridConstIterator it;
141  wxString output;
142  for (it = grid->GetIterator(); !it.AtEnd(); it++)
143  {
144  const wxPGProperty* p = *it;
145  if (p->IsCategory())
146  {
147  // skip categories
148  continue;
149  }
150  if (!output.IsEmpty())
151  {
152  output.Append("|");
153  };
154  const wxString type = p->GetValueType();
155  output.Append(p->GetName() + ":");
156  if (type == "double")
157  {
158  output.Append("double:" + wxString::FromCDouble(p->GetValue().GetDouble()));
159  }
160  else
161  {
162  if (type == "long")
163  {
164  output.Append("long:" + wxString::FromCDouble(p->GetValue().GetLong()));
165  }
166  else
167  {
168  if (type == "bool")
169  {
170  if (p->GetValue().GetBool())
171  {
172  output.Append("bool:true");
173  }
174  else
175  {
176  output.Append("bool:false");
177  };
178  }
179  else
180  {
181  // this should not happen
182  output.Append(type);
183  };
184  };
185  };
186  };
187  return output;
188 }
189 
190 // destructor, save settings
192 {
193  wxConfigBase* config = wxConfigBase::Get();
194  config->Write("/ToolboxFrame/Enfuse_Splitter", XRCCTRL(*this, "enfuse_splitter", wxSplitterWindow)->GetSashPosition());
195  config->Write("/ToolboxFrame/Enfuse_lastSettings", GetPropertyGridContent(m_enfuseOptions));
196  //save width of list ctrl column width
197  for (int j = 0; j < m_fileListCtrl->GetColumnCount(); j++)
198  {
199  config->Write(wxString::Format("/ToolboxFrame/FileListColumnWidth%d", j), m_fileListCtrl->GetColumnWidth(j));
200  };
201  config->Flush();
203 }
204 
205 bool EnfusePanel::Create(wxWindow* parent, MyExecPanel* logPanel)
206 {
207  if (!wxPanel::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, "panel"))
208  {
209  return false;
210  }
211  // populate wxPropertyGrid with all options
212  m_enfuseOptions = new wxPropertyGrid(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxPG_SPLITTER_AUTO_CENTER);
214  // create preview window
215  m_preview = new PreviewWindow();
216  m_preview->Create(this);
217 
218  m_logWindow = logPanel;
219  // load from xrc file and attach unknown controls
220  wxXmlResource::Get()->LoadPanel(this, "enfuse_panel");
221  wxXmlResource::Get()->AttachUnknownControl("enfuse_properties", m_enfuseOptions->GetGrid(), this);
222  wxXmlResource::Get()->AttachUnknownControl("enfuse_preview_window", m_preview, this);
223  // add to sizer
224  wxPanel* mainPanel = XRCCTRL(*this, "enfuse_panel", wxPanel);
225  wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL);
226  topsizer->Add(mainPanel, wxSizerFlags(1).Expand());
227  // create columns in wxListCtrl
228  m_fileListCtrl = XRCCTRL(*this, "enfuse_files", wxListCtrl);
229  m_fileListCtrl->InsertColumn(0, _("Filename"), wxLIST_FORMAT_LEFT, 200);
230  m_fileListCtrl->InsertColumn(1, _("Aperture"), wxLIST_FORMAT_LEFT, 50);
231  m_fileListCtrl->InsertColumn(2, _("Shutter Speed"), wxLIST_FORMAT_LEFT, 50);
232  m_fileListCtrl->InsertColumn(3, _("ISO"), wxLIST_FORMAT_LEFT, 50);
233  m_fileListCtrl->EnableCheckBoxes(true);
234  SetSizer(topsizer);
235  SetDropTarget(new EnfuseDropTarget(this));
236 
237  wxConfigBase* config = wxConfigBase::Get();
238  // restore splitter position
239  if (config->HasEntry("/ToolboxFrame/Enfuse_Splitter"))
240  {
241  XRCCTRL(*this, "enfuse_splitter", wxSplitterWindow)->SetSashPosition(config->ReadLong("/ToolboxFrame/Enfuse_Splitter", 300));
242  }
243  const wxString enfuseOptionsString=config->Read("/ToolboxFrame/Enfuse_lastSettings");
244  if (!enfuseOptionsString.IsEmpty())
245  {
246  SetPropertyGridContent(m_enfuseOptions, enfuseOptionsString);
247  };
248  //get saved width of list ctrl column width
249  for (int j = 0; j < m_fileListCtrl->GetColumnCount(); j++)
250  {
251  // -1 is auto
252  int width = config->Read(wxString::Format("/ToolboxFrame/FileListColumnWidth%d", j), -1);
253  if (width != -1)
254  {
255  m_fileListCtrl->SetColumnWidth(j, width);
256  };
257  };
258  // bind event handler
259  Bind(wxEVT_SIZE, &EnfusePanel::OnSize, this);
260  Bind(wxEVT_BUTTON, &EnfusePanel::OnAddFiles, this, XRCID("enfuse_add_file"));
261  Bind(wxEVT_BUTTON, &EnfusePanel::OnRemoveFile, this, XRCID("enfuse_remove_file"));
262  Bind(wxEVT_BUTTON, &EnfusePanel::OnCreateFile, this, XRCID("enfuse_create_file"));
263  m_fileListCtrl->Bind(wxEVT_CHAR, &EnfusePanel::OnSelectAllFiles, this);
264  m_fileListCtrl->Bind(wxEVT_LIST_ITEM_SELECTED, &EnfusePanel::OnFileSelectionChanged, this);
265  m_fileListCtrl->Bind(wxEVT_LIST_ITEM_DESELECTED, &EnfusePanel::OnFileSelectionChanged, this);
266  m_fileListCtrl->Bind(wxEVT_LIST_ITEM_CHECKED, &EnfusePanel::OnFileCheckStateChanged, this);
267  m_fileListCtrl->Bind(wxEVT_LIST_ITEM_UNCHECKED, &EnfusePanel::OnFileCheckStateChanged, this);
268  Bind(wxEVT_BUTTON, &EnfusePanel::OnLoadSetting, this, XRCID("enfuse_load_setting"));
269  Bind(wxEVT_BUTTON, &EnfusePanel::OnSaveSetting, this, XRCID("enfuse_save_setting"));
270  Bind(wxEVT_BUTTON, &EnfusePanel::OnResetSetting, this, XRCID("enfuse_reset_setting"));
271  Bind(wxEVT_BUTTON, &EnfusePanel::OnGeneratePreview, this, XRCID("enfuse_preview"));
272  Bind(wxEVT_BUTTON, &EnfusePanel::OnGenerateOutput, this, XRCID("enfuse_enfuse"));
273  Bind(wxEVT_CHOICE, &EnfusePanel::OnZoom, this, XRCID("enfuse_choice_zoom"));
274 
276  EnableOutputButtons(false);
277  return true;
278 }
279 
280 void EnfusePanel::AddFile(const wxString& filename)
281 {
282  // add filename
283  m_files.push_back(filename);
284  // add to wxListCtrl
285  wxFileName fullFilename(filename);
286  long index = m_fileListCtrl->InsertItem(m_fileListCtrl->GetItemCount(), fullFilename.GetFullName());
287  // set checkbox
288  m_fileListCtrl->CheckItem(index, true);
289  // read exif
290  {
292  srcImage.setFilename(std::string(fullFilename.GetFullPath().mb_str(HUGIN_CONV_FILENAME)));
293  if (srcImage.readEXIF())
294  {
295  m_fileListCtrl->SetItem(index, 1, FormatString::GetAperture(&srcImage));
296  m_fileListCtrl->SetItem(index, 2, FormatString::GetExposureTime(&srcImage));
297  m_fileListCtrl->SetItem(index, 3, FormatString::GetIso(&srcImage));
298  };
299  };
301 }
302 
303 void EnfusePanel::OnSize(wxSizeEvent& e)
304 {
305  Layout();
306  Update();
307  e.Skip();
308 }
309 
310 void EnfusePanel::OnAddFiles(wxCommandEvent& e)
311 {
312  wxConfigBase* config = wxConfigBase::Get();
313  wxString path = config->Read("/actualPath", "");
314  wxFileDialog dlg(this, _("Add images"), path, wxEmptyString,
315  GetFileDialogImageFilters(), wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST | wxFD_PREVIEW, wxDefaultPosition);
316  dlg.SetDirectory(path);
317 
318  // remember the image extension
319  wxString img_ext;
320  if (config->HasEntry("lastImageType"))
321  {
322  img_ext = config->Read("lastImageType").c_str();
323  }
324  if (img_ext == "all images")
325  dlg.SetFilterIndex(0);
326  else if (img_ext == "jpg")
327  dlg.SetFilterIndex(1);
328  else if (img_ext == "tiff")
329  dlg.SetFilterIndex(2);
330  else if (img_ext == "png")
331  dlg.SetFilterIndex(3);
332  else if (img_ext == "hdr")
333  dlg.SetFilterIndex(4);
334  else if (img_ext == "exr")
335  dlg.SetFilterIndex(5);
336  else if (img_ext == "all files")
337  dlg.SetFilterIndex(6);
338 
339  // call the file dialog
340  if (dlg.ShowModal() == wxID_OK)
341  {
342  // get the selections
343  wxArrayString Pathnames;
344  dlg.GetPaths(Pathnames);
345  // save the current path to config
346  config->Write("/actualPath", dlg.GetDirectory());
347  // save the image extension
348  switch (dlg.GetFilterIndex())
349  {
350  case 0: config->Write("lastImageType", "all images"); break;
351  case 1: config->Write("lastImageType", "jpg"); break;
352  case 2: config->Write("lastImageType", "tiff"); break;
353  case 3: config->Write("lastImageType", "png"); break;
354  case 4: config->Write("lastImageType", "hdr"); break;
355  case 5: config->Write("lastImageType", "exr"); break;
356  case 6: config->Write("lastImageType", "all files"); break;
357  }
358  for (auto& f : Pathnames)
359  {
360  AddFile(f);
361  }
362  }
363 }
364 
365 void EnfusePanel::OnRemoveFile(wxCommandEvent& e)
366 {
367  HuginBase::UIntSet selected;
368  if (m_fileListCtrl->GetSelectedItemCount() >= 1)
369  {
370  for (int i = 0; i < m_fileListCtrl->GetItemCount(); ++i)
371  {
372  if (m_fileListCtrl->GetItemState(i, wxLIST_STATE_SELECTED) & wxLIST_STATE_SELECTED)
373  {
374  selected.insert(i);
375  };
376  };
377  };
378  if (!selected.empty())
379  {
380  // remove selected file from wxListBox and internal file list
381  for (auto i = selected.rbegin(); i != selected.rend(); ++i)
382  {
383  if (*i >= 0 && *i < m_files.size())
384  {
385  m_fileListCtrl->DeleteItem(*i);
386  m_files.RemoveAt(*i, 1);
387  };
388  };
391  }
392  else
393  {
394  wxBell();
395  };
396 }
397 
398 void EnfusePanel::OnCreateFile(wxCommandEvent& e)
399 {
400  if (m_fileListCtrl->GetSelectedItemCount() == 1)
401  {
402  // single image selected
403  long index = m_fileListCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
404  if (index != -1)
405  {
406  CreateBrightImgDlg dlg(this);
407  wxString errorMsg;
408  if (dlg.SetImage(std::string(m_files[index].mb_str(HUGIN_CONV_FILENAME)), errorMsg))
409  {
410  if (dlg.ShowModal() == wxID_OK)
411  {
412  // get all new files
413  wxArrayString newFiles = dlg.GetTempFiles();
414  // wait a little bit before reading the files back
415  // wxMilliSleep(1000);
416  for (const auto& f : newFiles)
417  {
418  // add to list of temp files for cleanup at end
419  m_tempFiles.Add(f);
420  // add to list
421  AddFile(f);
422  };
423  };
424  }
425  else
426  {
427  hugin_utils::HuginMessageBox(errorMsg, _("Hugin toolbox"), wxOK | wxICON_QUESTION, this);
428  };
429  };
430  }
431  else
432  {
433  wxBell();
434  };
435 }
436 
437 // select all file swith ctrl+A
438 void EnfusePanel::OnSelectAllFiles(wxKeyEvent& e)
439 {
440  // ctrl + a
441  if (e.GetKeyCode() == 1 && e.CmdDown())
442  {
443  // select all
444  for (int i = 0; i < m_fileListCtrl->GetItemCount(); i++)
445  {
446  m_fileListCtrl->SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
447  };
448  };
449  e.Skip();
450 }
451 
452 void EnfusePanel::OnFileSelectionChanged(wxCommandEvent& e)
453 {
454  // enable/disable button according to selected files
456 }
457 
459 {
461 }
462 
464 static const wxString defaultIni
465 {
466  "[Enfuse_Settings]\n"
467  "Exposure fusion=exposureWeight:double:1|saturationWeight:double:0|contrastWeight:double:0|entropyWeight:double:0|hardMask:bool:false|levels:long:0|blendColorspace:long:0|wrapMode:long:0|exposureOptimum:double:0.5|exposureWidth:double:0.2|contrastEdgeScale:double:0|contrastMinCurvature:double:0|contrastWindowSize:long:5|entropyLowerCutoff:double:0|entropyUpperCutoff:double:100|entropyWindowSize:long:3|exposureLowerCutoff:double:0|exposureUpperCutoff:double:100|exposureWeightFunction:long:0|grayProjector:long:1\n"
468  "Focus stacking=exposureWeight:double:0|saturationWeight:double:0|contrastWeight:double:1|entropyWeight:double:0|hardMask:bool:true|levels:long:0|blendColorspace:long:0|wrapMode:long:0|exposureOptimum:double:0.5|exposureWidth:double:0.2|contrastEdgeScale:double:0|contrastMinCurvature:double:0|contrastWindowSize:long:5|entropyLowerCutoff:double:0|entropyUpperCutoff:double:100|entropyWindowSize:long:3|exposureLowerCutoff:double:0|exposureUpperCutoff:double:100|exposureWeightFunction:long:0|grayProjector:long:1\n"
469 };
470 
471 wxFileConfig* ReadIni(const wxString& filename)
472 {
473  wxInputStream* iniStream{ nullptr };
474  if (wxFileExists(filename))
475  {
476  iniStream = new wxFileInputStream(filename);
477  if (!iniStream->IsOk())
478  {
479  delete iniStream;
480  iniStream = nullptr;
481  }
482  };
483  if (iniStream == nullptr)
484  {
485  iniStream = new wxStringInputStream(defaultIni);
486  };
487  // now read from stream
488  wxFileConfig* iniFile=new wxFileConfig(*iniStream);
489  delete iniStream;
490  return iniFile;
491 }
492 
493 void EnfusePanel::OnLoadSetting(wxCommandEvent& e)
494 {
495  wxFileName iniFilename(hugin_utils::GetUserAppDataDir(), "toolbox.ini");
496  wxFileConfig* iniFile = ReadIni(iniFilename.GetFullPath());
497  // read known settings from file
498  iniFile->SetPath("Enfuse_Settings");
499  wxArrayString knownNames;
500  wxArrayString knownSettings;
501  wxString key;
502  long indexKey;
503  bool hasKeys = iniFile->GetFirstEntry(key, indexKey);
504  while (hasKeys)
505  {
506  knownNames.push_back(key);
507  knownSettings.push_back(iniFile->Read(key));
508  hasKeys = iniFile->GetNextEntry(key, indexKey);
509  };
510  int selection=wxGetSingleChoiceIndex(_("Select the Enfuse setting, which should be loaded."), _("Hugin toolbox"), knownNames, 0, this);
511  if (selection != -1)
512  {
513  SetPropertyGridContent(m_enfuseOptions, knownSettings[selection]);
514  };
515  delete iniFile;
516 }
517 
518 void EnfusePanel::OnSaveSetting(wxCommandEvent& e)
519 {
520  wxFileName iniFilename(hugin_utils::GetUserAppDataDir(), "toolbox.ini");
521  wxFileConfig* iniFile = ReadIni(iniFilename.GetFullPath());
522  // read known settings from file
523  iniFile->SetPath("Enfuse_Settings");
524  wxArrayString knownNames;
525  wxString key;
526  long indexKey;
527  bool hasKeys = iniFile->GetFirstEntry(key, indexKey);
528  while (hasKeys)
529  {
530  knownNames.push_back(key);
531  hasKeys = iniFile->GetNextEntry(key, indexKey);
532  };
533  wxString name;
534  while (true)
535  {
536  name = wxGetTextFromUser(_("Enter name of Enfuse setting"), "Enfuse settings", name, this);
537  if (name.IsEmpty())
538  {
539  // empty name or cancel
540  delete iniFile;
541  return;
542  };
543  // remove the '=' character from name, it is used as separator in ini file
544  name.Replace("=", "", true);
545  if (knownNames.Index(name) != wxNOT_FOUND)
546  {
547  if (hugin_utils::HuginMessageBox(wxString::Format(_("Enfuse setting with name \"%s\" is already existing.\nShould it be overwritten?"), name),
548  _("Hugin toolbox"), wxYES_NO | wxICON_QUESTION, this) == wxYES)
549  {
550  break;
551  };
552  }
553  else
554  {
555  break;
556  };
557  };
558  // finally write settings
559  iniFile->Write(name, GetPropertyGridContent(m_enfuseOptions));
560  // finally write to disc
561  wxFileOutputStream iniStream(iniFilename.GetFullPath());
562  bool success = true;
563  if (iniStream.IsOk())
564  {
565  success = iniFile->Save(iniStream);
566  };
567  if (!success)
568  {
569  hugin_utils::HuginMessageBox(wxString::Format(_("Could not save ini file \"%s\"."), iniFilename.GetFullPath()), _("Hugin toolbox"), wxOK | wxICON_ERROR, this);
570  };
571  delete iniFile;
572 }
573 
574 void EnfusePanel::OnResetSetting(wxCommandEvent& e)
575 {
576  // reset all settings to default values
577  m_enfuseOptions->SetPropertyValue("exposureWeight", 1.0);
578  m_enfuseOptions->SetPropertyValue("saturationWeight", 0.0);
579  m_enfuseOptions->SetPropertyValue("contrastWeight", 0.0);
580  m_enfuseOptions->SetPropertyValue("entropyWeight", 0.0);
581  m_enfuseOptions->SetPropertyValue("hardMask", false);
582  m_enfuseOptions->SetPropertyValue("levels", 0);
583  m_enfuseOptions->SetPropertyValue("blendColorspace", 0);
584  m_enfuseOptions->SetPropertyValue("wrapMode", 0);
585  m_enfuseOptions->SetPropertyValue("exposureOptimum", 0.5);
586  m_enfuseOptions->SetPropertyValue("exposureWidth", 0.2);
587  m_enfuseOptions->SetPropertyValue("contrastEdgeScale", 0.0);
588  m_enfuseOptions->SetPropertyValue("contrastMinCurvature", 0.0);
589  m_enfuseOptions->SetPropertyValue("contrastWindowSize", 5);
590  m_enfuseOptions->SetPropertyValue("entropyLowerCutoff", 0.0);
591  m_enfuseOptions->SetPropertyValue("entropyUpperCutoff", 100.0);
592  m_enfuseOptions->SetPropertyValue("entropyWindowSize", 3);
593  m_enfuseOptions->SetPropertyValue("exposureLowerCutoff", 0.0);
594  m_enfuseOptions->SetPropertyValue("exposureUpperCutoff", 100.0);
595  m_enfuseOptions->SetPropertyValue("exposureWeightFunction", 0);
596  m_enfuseOptions->SetPropertyValue("grayProjector", 1);
597 }
598 
599 void EnfusePanel::OnGeneratePreview(wxCommandEvent& e)
600 {
601  // create temp file name, set extension to tif
602  m_outputFilenames.resize(2);
603  wxFileName tempfile(wxFileName::CreateTempFileName(HuginQueue::GetConfigTempDir(wxConfig::Get()) + "he"));
604  m_outputFilenames[1] = tempfile.GetFullPath();
605  tempfile.SetExt("tif");
606  m_outputFilenames[0] = tempfile.GetFullPath();
607  m_cleanupOutput = true;
608  // get command line and execute
609  ExecuteEnfuse();
610 }
611 
613 {
614  wxString cmd = GetEnfuseCommandLine();
615  if (!cmd.IsEmpty())
616  {
617  EnableOutputButtons(false);
619  cmd = HuginQueue::wxEscapeFilename(HuginQueue::GetExternalProgram(wxConfigBase::Get(), wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR), "enfuse")) + cmd;
620  m_logWindow->AddString(cmd);
622  }
623 }
624 
626 {
627  wxString cmd = GetEnfuseCommandLine();
628  if (!cmd.IsEmpty())
629  {
630  EnableOutputButtons(false);
633  wxString exePath = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
634  queue->push_back(new HuginQueue::NormalCommand(HuginQueue::GetExternalProgram(wxConfig::Get(), exePath, "enfuse"), cmd, _("Merging images") + " (" + cmd + ")"));
635  // get first image
636  long index = -1;
637  for (long i = 0; i < m_fileListCtrl->GetItemCount(); ++i)
638  {
639  if (m_fileListCtrl->IsItemChecked(i))
640  {
641  index = i;
642  break;
643  };
644  };
645  wxString exiftoolArgs(" -overwrite_original -tagsfromfile " + HuginQueue::wxEscapeFilename(m_files[index]));
646  exiftoolArgs.Append(" -all:all --thumbnail --xposition --yposition --imagefullwidth --imagefullheight ");
647  exiftoolArgs.Append(HuginQueue::wxEscapeFilename(m_outputFilenames[0]));
648  queue->push_back(new HuginQueue::OptionalCommand(HuginQueue::GetExternalProgram(wxConfig::Get(), exePath, "exiftool"), exiftoolArgs, _("Updating EXIF")));
649  m_logWindow->ExecQueue(queue);
650  };
651 }
652 
653 void EnfusePanel::OnGenerateOutput(wxCommandEvent& e)
654 {
655  if (m_files.IsEmpty())
656  {
657  wxBell();
658  return;
659  };
660  wxConfigBase* config = wxConfigBase::Get();
661  wxString path = config->Read("/actualPath", "");
662  wxFileDialog dlg(this, _("Save output"), path, wxEmptyString, GetMainImageFilters(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
663  dlg.SetDirectory(path);
664 
665  // remember the image extension
666  wxString img_ext;
667  if (config->HasEntry("lastImageType"))
668  {
669  img_ext = config->Read("lastImageType").c_str();
670  }
671  if (img_ext == "jpg")
672  {
673  dlg.SetFilterIndex(0);
674  }
675  else
676  {
677  if (img_ext == "tiff")
678  {
679  dlg.SetFilterIndex(1);
680  }
681  else
682  {
683  if (img_ext == "png")
684  {
685  dlg.SetFilterIndex(2);
686  };
687  };
688  };
689  wxFileName outputfilename(m_files[0]);
690  outputfilename.SetName(outputfilename.GetName() + "_stacked");
691  dlg.SetFilename(outputfilename.GetFullPath());
692  // call the file dialog
693  if (dlg.ShowModal() == wxID_OK)
694  {
695  m_outputFilenames.resize(1);
696  m_outputFilenames[0] = dlg.GetPath();
697  // save the current path to config
698  config->Write("/actualPath", dlg.GetDirectory());
699  // save the image extension
700  switch (dlg.GetFilterIndex())
701  {
702  case 0:
703  config->Write("lastImageType", "jpg");
704  break;
705  case 1:
706  config->Write("lastImageType", "tiff");
707  break;
708  case 2:
709  config->Write("lastImageType", "png");
710  break;
711  };
712  m_cleanupOutput = false;
714  };
715 }
716 
717 void EnfusePanel::OnZoom(wxCommandEvent& e)
718 {
719  double factor;
720  switch (e.GetSelection())
721  {
722  case 0:
723  factor = 1;
724  break;
725  case 1:
726  // fit to window
727  factor = 0;
728  break;
729  case 2:
730  factor = 2;
731  break;
732  case 3:
733  factor = 1.5;
734  break;
735  case 4:
736  factor = 0.75;
737  break;
738  case 5:
739  factor = 0.5;
740  break;
741  case 6:
742  factor = 0.25;
743  break;
744  default:
745  DEBUG_ERROR("unknown scale factor");
746  factor = 1;
747  }
748  m_preview->setScale(factor);
749 }
750 
751 void EnfusePanel::OnProcessFinished(wxCommandEvent& e)
752 {
753  wxFileName output(m_outputFilenames[0]);
754  if (output.FileExists() && output.GetSize()>0)
755  {
756  m_preview->setImage(output.GetFullPath());
757  };
758  EnableOutputButtons(true);
759  if (m_cleanupOutput && output.FileExists())
760  {
761  // cleanup up preview files
762  for (const auto& f : m_outputFilenames)
763  {
764  wxRemoveFile(f);
765  };
766  };
767 }
768 
770 {
771  // all weight options, with spin control
772  wxPGProperty* prop = m_enfuseOptions->Append(new wxFloatProperty("Exposure weight", "exposureWeight", 1));
773  prop->SetEditor(wxPGEditor_SpinCtrl);
774  prop->SetAttribute(wxPG_ATTR_MIN, 0);
775  prop->SetAttribute(wxPG_ATTR_MAX, 1);
776  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.05);
777  prop = m_enfuseOptions->Append(new wxFloatProperty("Saturation weight", "saturationWeight", 0));
778  prop->SetEditor(wxPGEditor_SpinCtrl);
779  prop->SetAttribute(wxPG_ATTR_MIN, 0);
780  prop->SetAttribute(wxPG_ATTR_MAX, 1);
781  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.05);
782  prop = m_enfuseOptions->Append(new wxFloatProperty("Contrast weight", "contrastWeight", 0));
783  prop->SetEditor(wxPGEditor_SpinCtrl);
784  prop->SetAttribute(wxPG_ATTR_MIN, 0);
785  prop->SetAttribute(wxPG_ATTR_MAX, 1);
786  prop = m_enfuseOptions->Append(new wxFloatProperty("Entropy weight", "entropyWeight", 0));
787  prop->SetEditor(wxPGEditor_SpinCtrl);
788  prop->SetAttribute(wxPG_ATTR_MIN, 0);
789  prop->SetAttribute(wxPG_ATTR_MAX, 1);
790  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.05);
791  // hard / soft mask
792  m_enfuseOptions->Append(new wxBoolProperty("Hard mask", "hardMask", false));
793  // general options
794  prop = m_enfuseOptions->Append(new wxPropertyCategory(_("General"), "general"));
795  prop = m_enfuseOptions->Append(new wxIntProperty("Levels", "levels", 0));
796  prop->SetEditor(wxPGEditor_SpinCtrl);
797  prop->SetAttribute(wxPG_ATTR_MIN, -29);
798  prop->SetAttribute(wxPG_ATTR_MAX, 29);
799  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 1);
800  wxArrayString blendColorspaces;
801  blendColorspaces.Add("Auto");
802  blendColorspaces.Add("Identity (RGB)");
803  blendColorspaces.Add("CIELab");
804  blendColorspaces.Add("CIELuv");
805  blendColorspaces.Add("CIECAM02");
806  m_enfuseOptions->Append(new wxEnumProperty("Blend colorspace", "blendColorspace", blendColorspaces));
807  wxArrayString wrapMode;
808  wrapMode.Add("None");
809  wrapMode.Add("Horizontal");
810  wrapMode.Add("Vertical");
811  wrapMode.Add("Both");
812  m_enfuseOptions->Append(new wxEnumProperty("Wrap mode", "wrapMode", wrapMode));
813  m_enfuseOptions->Collapse("general");
814  m_enfuseOptions->Append(new wxPropertyCategory(_("Fusions options"), "fusionOptions"));
815  prop = m_enfuseOptions->Append(new wxFloatProperty("Exposure optimum", "exposureOptimum", 0.5));
816  prop->SetEditor(wxPGEditor_SpinCtrl);
817  prop->SetAttribute(wxPG_ATTR_MIN, 0);
818  prop->SetAttribute(wxPG_ATTR_MAX, 1);
819  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.05);
820  prop = m_enfuseOptions->Append(new wxFloatProperty("Exposure width", "exposureWidth", 0.2));
821  prop->SetEditor(wxPGEditor_SpinCtrl);
822  prop->SetAttribute(wxPG_ATTR_MIN, 0);
823  prop->SetAttribute(wxPG_ATTR_MAX, 1);
824  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.05);
825  prop = m_enfuseOptions->Append(new wxFloatProperty("Contrast edge scale", "contrastEdgeScale", 0));
826  prop->SetEditor(wxPGEditor_SpinCtrl);
827  prop->SetAttribute(wxPG_ATTR_MIN, 0);
828  prop->SetAttribute(wxPG_ATTR_MAX, 5);
829  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.1);
830  prop = m_enfuseOptions->Append(new wxFloatProperty("Contrast min curvature", "contrastMinCurvature", 0));
831  prop->SetEditor(wxPGEditor_SpinCtrl);
832  prop->SetAttribute(wxPG_ATTR_MIN, 0);
833  prop->SetAttribute(wxPG_ATTR_MAX, 50);
834  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.5);
835  prop = m_enfuseOptions->Append(new wxIntProperty("Contrast window size", "contrastWindowSize", 5));
836  prop->SetEditor(wxPGEditor_SpinCtrl);
837  prop->SetAttribute(wxPG_ATTR_MIN, 3);
838  prop->SetAttribute(wxPG_ATTR_MAX, 30);
839  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 1);
840  prop = m_enfuseOptions->Append(new wxFloatProperty("Entropy lower cutoff", "entropyLowerCutoff", 0));
841  prop->SetEditor(wxPGEditor_SpinCtrl);
842  prop->SetAttribute(wxPG_ATTR_MIN, 0);
843  prop->SetAttribute(wxPG_ATTR_MAX, 100);
844  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.5);
845  prop = m_enfuseOptions->Append(new wxFloatProperty("Entropy higher cutoff", "entropyUpperCutoff", 100));
846  prop->SetEditor(wxPGEditor_SpinCtrl);
847  prop->SetAttribute(wxPG_ATTR_MIN, 0);
848  prop->SetAttribute(wxPG_ATTR_MAX, 100);
849  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.5);
850  prop = m_enfuseOptions->Append(new wxIntProperty("Entropy window size", "entropyWindowSize", 3));
851  prop->SetEditor(wxPGEditor_SpinCtrl);
852  prop->SetAttribute(wxPG_ATTR_MIN, 3);
853  prop->SetAttribute(wxPG_ATTR_MAX, 7);
854  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 1);
855  prop = m_enfuseOptions->Append(new wxFloatProperty("Expoure lower cutoff", "exposureLowerCutoff", 0));
856  prop->SetEditor(wxPGEditor_SpinCtrl);
857  prop->SetAttribute(wxPG_ATTR_MIN, 0);
858  prop->SetAttribute(wxPG_ATTR_MAX, 100);
859  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.5);
860  prop = m_enfuseOptions->Append(new wxFloatProperty("Exposure higher cutoff", "exposureUpperCutoff", 100));
861  prop->SetEditor(wxPGEditor_SpinCtrl);
862  prop->SetAttribute(wxPG_ATTR_MIN, 0);
863  prop->SetAttribute(wxPG_ATTR_MAX, 100);
864  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.5);
865  wxArrayString exposureWeightFunction;
866  exposureWeightFunction.Add("Gaussian");
867  exposureWeightFunction.Add("Lorentzian");
868  exposureWeightFunction.Add("Half-sine");
869  exposureWeightFunction.Add("Full-sine");
870  exposureWeightFunction.Add("Bi-square");
871  m_enfuseOptions->Append(new wxEnumProperty("Exposure weight function", "exposureWeightFunction", exposureWeightFunction));
872  wxArrayString grayProjector;
873  grayProjector.Add("anti-value"); // index 0
874  grayProjector.Add("Average"); // index 1
875  grayProjector.Add("L-channel from Lab (gamma=1)"); // index 2
876  grayProjector.Add("L-channel from Lab (gamma corrected)"); // index 3
877  grayProjector.Add("Lightness"); // index 4
878  grayProjector.Add("Luminance"); // index 5
879  grayProjector.Add("Value from HSV"); // index 6
880  // missing: channelMixel
881  prop = m_enfuseOptions->Append(new wxEnumProperty("Gray projector", "grayProjector", grayProjector));
882  m_enfuseOptions->SetPropertyValue("grayProjector", 1);
883  // if you add new options also update GetEnfuseOptions() and OnResetSetting(..)
884 }
885 
887 {
888  wxString commandline("--verbose ");
889  double doubleValue=m_enfuseOptions->GetPropertyValueAsDouble("exposureWeight");
890  if (doubleValue != 1)
891  {
892  commandline.Append(" --exposure-weight=" + wxString::FromCDouble(doubleValue));
893  };
894  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("saturationWeight");
895  if (doubleValue != 0)
896  {
897  commandline.Append(" --saturation-weight=" + wxString::FromCDouble(doubleValue));
898  };
899  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("contrastWeight");
900  if (doubleValue != 0)
901  {
902  commandline.Append(" --contrast-weight=" + wxString::FromCDouble(doubleValue));
903  };
904  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("entropyWeight");
905  if (doubleValue != 0)
906  {
907  commandline.Append(" --entropy-weight=" + wxString::FromCDouble(doubleValue));
908  };
909  bool boolVal = m_enfuseOptions->GetPropertyValueAsBool("hardMask");
910  if (boolVal)
911  {
912  commandline.Append(" --hard-mask");
913  };
914  int intValue = m_enfuseOptions->GetPropertyValueAsInt("levels");
915  if (intValue != 0)
916  {
917  commandline.Append(wxString::Format(" --level=%d", intValue));
918  };
919  intValue = m_enfuseOptions->GetPropertyValueAsInt("blendColorspace");
920  switch (intValue)
921  {
922  case 1:
923  commandline.Append(" --blend-colorspace=identity");
924  break;
925  case 2:
926  commandline.Append(" --blend-colorspace=cielab");
927  break;
928  case 3:
929  commandline.Append(" --blend-colorspace=cieluv");
930  break;
931  case 4:
932  commandline.Append(" --blend-colorspace=ciecam");
933  break;
934  default:
935  case 0:
936  // do nothing
937  break;
938  };
939  intValue = m_enfuseOptions->GetPropertyValueAsInt("wrapMode");
940  switch (intValue)
941  {
942  case 1:
943  commandline.Append(" --wrap=horizontal");
944  break;
945  case 2:
946  commandline.Append(" --wrap=vertical");
947  break;
948  case 3:
949  commandline.Append(" --wrap=both ");
950  break;
951  case 0:
952  default:
953  break;
954  };
955  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("exposureOptimum");
956  if (doubleValue != 0.5)
957  {
958  commandline.Append(" --exposure-optimum=" + wxString::FromCDouble(doubleValue));
959  };
960  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("exposureWidth");
961  if (doubleValue != 0.2)
962  {
963  commandline.Append(" --exposure-width=" + wxString::FromCDouble(doubleValue));
964  };
965  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("contrastEdgeScale");
966  if (doubleValue != 0)
967  {
968  commandline.Append(" --contrast-edge-scale=" + wxString::FromCDouble(doubleValue));
969  };
970  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("contrastMinCurvature");
971  if (doubleValue != 0)
972  {
973  commandline.Append(" --contrast-min-curvature=" + wxString::FromCDouble(doubleValue) + "%");
974  };
975  intValue = m_enfuseOptions->GetPropertyValueAsInt("contrastWindowSize");
976  if (intValue != 5)
977  {
978  commandline.Append(wxString::Format(" --contrast-window-size=%d", intValue));
979  };
980  // entropy cutoff
981  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("entropyLowerCutoff");
982  double doubleValue2 = m_enfuseOptions->GetPropertyValueAsDouble("entropyUpperCutoff");
983  if (doubleValue > 0 || doubleValue2 < 100)
984  {
985  commandline.Append(" --entropy-cutoff=" + wxString::FromCDouble(doubleValue) + "%");
986  if (doubleValue2 < 100)
987  {
988  commandline.Append(":" + wxString::FromCDouble(doubleValue2) + "%");
989  };
990  };
991  intValue = m_enfuseOptions->GetPropertyValueAsInt("entropyWindowSize");
992  if (intValue != 3)
993  {
994  commandline.Append(wxString::Format(" --entropy-window-size=%d", intValue));
995  };
996  // exposure cutoff
997  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("exposureLowerCutoff");
998  doubleValue2 = m_enfuseOptions->GetPropertyValueAsDouble("exposureUpperCutoff");
999  if (doubleValue > 0 || doubleValue2 < 100)
1000  {
1001  commandline.Append(" --exposure-cutoff=" + wxString::FromCDouble(doubleValue) + "%");
1002  if (doubleValue2 < 100)
1003  {
1004  commandline.Append(":" + wxString::FromCDouble(doubleValue2) + "%");
1005  };
1006  };
1007  // exposure weight function
1008  intValue = m_enfuseOptions->GetPropertyValueAsInt("exposureWeightFunction");
1009  switch (intValue)
1010  {
1011  case 1:
1012  commandline.Append(" --exposure-weight-function=lorentz");
1013  break;
1014  case 2:
1015  commandline.Append(" --exposure-weight-function=halfsine");
1016  break;
1017  case 3:
1018  commandline.Append(" --exposure-weight-function=fullsine");
1019  break;
1020  case 4:
1021  commandline.Append(" --exposure-weight-function=bisquare");
1022  break;
1023  case 0:
1024  default:
1025  break;
1026  };
1027  // gray projector
1028  intValue = m_enfuseOptions->GetPropertyValueAsInt("grayProjector");
1029  switch (intValue)
1030  {
1031  case 0:
1032  commandline.Append(" --gray-projector=anti-value");
1033  break;
1034  case 2:
1035  commandline.Append(" --gray-projector=al-star");
1036  break;
1037  case 3:
1038  commandline.Append(" --gray-projector=pl-star");
1039  break;
1040  case 4:
1041  commandline.Append(" --gray-projector=lightness");
1042  break;
1043  case 5:
1044  commandline.Append(" --gray-projector=luminance");
1045  break;
1046  case 6:
1047  commandline.Append(" --gray-projector=value");
1048  break;
1049  case 1:
1050  default:
1051  break;
1052  };
1053  return commandline;
1054 }
1055 
1057 {
1058  wxString commandline(" --output=" + hugin_utils::wxQuoteFilename(m_outputFilenames[0]));
1059  // add options from control
1060  commandline.Append(" ");
1061  commandline.Append(GetEnfuseOptions());
1062  // now build image list
1063  wxArrayInt selectedFiles;
1064  for (int i = 0; i < m_fileListCtrl->GetItemCount(); ++i)
1065  {
1066  if (m_fileListCtrl->IsItemChecked(i))
1067  {
1068  selectedFiles.push_back(i);
1069  };
1070  };
1071  if (selectedFiles.IsEmpty())
1072  {
1073  hugin_utils::HuginMessageBox(_("Please activate at least one file."), _("Hugin_toolbox"), wxOK | wxOK_DEFAULT | wxICON_WARNING, this);
1074  return wxEmptyString;
1075  }
1076  for (int i = 0; i < selectedFiles.size(); ++i)
1077  {
1078  commandline.Append(" ");
1079  commandline.Append(hugin_utils::wxQuoteFilename(m_files[selectedFiles[i]]));
1080  }
1081  return commandline;
1082 }
1083 
1085 {
1086  // enable/disable button according to selected files
1087  XRCCTRL(*this, "enfuse_remove_file", wxButton)->Enable(m_fileListCtrl->GetSelectedItemCount() >= 1);
1088  XRCCTRL(*this, "enfuse_create_file", wxButton)->Enable(m_fileListCtrl->GetSelectedItemCount() == 1);
1089 }
1090 
1092 {
1093  // count checked items
1094  long count = 0;
1095  for (int i = 0; i < m_fileListCtrl->GetItemCount(); ++i)
1096  {
1097  if (m_fileListCtrl->IsItemChecked(i))
1098  {
1099  ++count;
1100  };
1101  };
1102  return count;
1103 }
1104 
1106 {
1107  XRCCTRL(*this, "enfuse_preview", wxButton)->Enable(enable);
1108  XRCCTRL(*this, "enfuse_enfuse", wxButton)->Enable(enable);
1109 
1110 }
1111 
1113 {
1114  for (const auto& f : m_tempFiles)
1115  {
1116  wxRemoveFile(f);
1117  };
1118 }
1119 
int ExecWithRedirect(wxString command)
EnfusePanel * m_enfusePanel
Definition: EnfusePanel.cpp:84
normal command for queue, processing is stopped if an error occurred in program
Definition: Executor.h:37
implementation of huginApp Class
void OnSize(wxSizeEvent &e)
event handler
void OnAddFiles(wxCommandEvent &e)
const wxString GetConfigTempDir(const wxConfigBase *config)
return the temp dir from the preferences, ensure that it ends with path separator ...
Definition: Executor.cpp:302
void OnRemoveFile(wxCommandEvent &e)
Dialog for create brighter and/or darker versions of an image.
MyExecPanel * m_logWindow
Definition: EnfusePanel.h:91
long GetCheckedItemCount() const
return the number of check images
optional command for queue, processing of queue is always continued, also if an error occurred ...
Definition: Executor.h:53
void OnSelectAllFiles(wxKeyEvent &e)
#define HUGIN_CONV_FILENAME
Definition: platform.h:40
void OnZoom(wxCommandEvent &e)
void ExecuteEnfuse()
build the command line and execute enfuse command
void OnGeneratePreview(wxCommandEvent &e)
void OnCreateFile(wxCommandEvent &e)
void EnableOutputButtons(bool enable)
enable/disable output buttons
int ExecQueue(HuginQueue::CommandQueue *queue)
some helper classes for graphes
wxArrayString m_files
Definition: EnfusePanel.h:89
void ClearOutput()
clear the output
void OnFileCheckStateChanged(wxCommandEvent &e)
file drag and drop handler method
Definition: EnfusePanel.cpp:43
vigra::pair< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImage(const ROIImage< Image, Mask > &img)
Definition: ROIImage.h:300
static const wxString defaultIni
default ini, if no one exists load this one
basic classes and function for queuing commands in wxWidgets
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
bool SetImage(const wxString &filename, wxString &errorMsg)
load the image, return true on success, otherwise false, error cause is in errorMsg ...
void EnableFileButtons()
enable/disable the file(s) remove and create buttons depending on selection of wxListCtrl ...
void AddFile(const wxString &filename)
adds the given file to the list
void setImage(const wxString &filename)
set the current image and mask list, this loads also the image from cache
bool m_cleanupOutput
Definition: EnfusePanel.h:94
PreviewWindow * m_preview
Definition: EnfusePanel.h:90
void OnLoadSetting(wxCommandEvent &e)
void ExecuteEnfuseExiftool()
build the command line and execute enfuse and exiftool afterwards
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name="panel")
create the control
wxListCtrl * m_fileListCtrl
Definition: EnfusePanel.h:87
IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow, wxWindow)
wxString GetMainImageFilters()
return a filter for the main image files (JPG/TIFF/PNG) only
Definition: platform.cpp:80
Definition of dialog class to create brighter/darker versions of the image.
void OnFileSelectionChanged(wxCommandEvent &e)
void AddString(const wxString &s)
display the string in the panel
void CleanUpTempFiles()
delete all temporary files, to be called mainly at end
declaration of panel for enfuse GUI
bool Create(wxWindow *parent, MyExecPanel *logPanel)
creates the control and populates all controls with their settings
void OnSaveSetting(wxCommandEvent &e)
void PopulateEnfuseOptions()
fill the PropertyGrid with all enfuse options
#define DEBUG_ERROR(msg)
Definition: utils.h:76
wxString GetPropertyGridContent(const wxPropertyGrid *grid)
wxString GetExposureTime(const HuginBase::SrcPanoImage *img)
returns formatted exposure time
Definition: LensTools.cpp:550
panel for enfuse GUI
Definition: EnfusePanel.h:37
wxArrayString m_tempFiles
Definition: EnfusePanel.h:93
void setScale(double factor)
set the scaling factor f.
void OnProcessFinished(wxCommandEvent &e)
call at the end of the enfuse command, to load result back and enable buttons again ...
str wxEscapeFilename(const str &arg)
special escaping routine for CommandQueues
Definition: Executor.h:79
~EnfusePanel()
destructor, save state and settings
std::string GetUserAppDataDir()
returns the directory for user specific Hugin settings, e.g.
Definition: utils.cpp:497
bool readEXIF()
try to fill out information about the image, by examining the exif data
wxString GetEnfuseCommandLine()
get the full commandline for enfuse without program, but with files and output options, the output filename is read from m_outputFilename
preview window
Definition: PreviewWindow.h:38
bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames)
Definition: EnfusePanel.cpp:51
platform/compiler specific stuff.
void SetPropertyGridContent(wxPropertyGrid *grid, const wxString values)
Definition: EnfusePanel.cpp:88
void OnResetSetting(wxCommandEvent &e)
EnfuseDropTarget(EnfusePanel *parent)
Definition: EnfusePanel.cpp:46
wxFileConfig * ReadIni(const wxString &filename)
wxPropertyGrid * m_enfuseOptions
Definition: EnfusePanel.h:88
str wxQuoteFilename(const str &arg)
Quote a filename, so that it is surrounded by &quot;&quot;.
Definition: wxPlatform.h:82
wxArrayString m_outputFilenames
Definition: EnfusePanel.h:92
All variables of a source image.
Definition: SrcPanoImage.h:194
wxString GetFileDialogImageFilters()
return filter for image files, needed by file open dialog it contains all image format vigra can read...
Definition: platform.cpp:69
wxString GetAperture(const HuginBase::SrcPanoImage *img)
returns formatted aperture value
Definition: LensTools.cpp:536
int HuginMessageBox(const wxString &message, const wxString &caption, int style, wxWindow *parent)
Definition: wxutils.cpp:176
wxString GetEnfuseOptions()
build string with all enfuse options from values in wxPropertyGrid this are the mainly the fusion opt...
wxString GetExternalProgram(wxConfigBase *config, const wxString &bindir, const wxString &name)
return path and name of external program, which can be overwritten by the user
Definition: Executor.cpp:148
std::vector< NormalCommand * > CommandQueue
Definition: Executor.h:61
wxString GetIso(const HuginBase::SrcPanoImage *img)
returns formatted iso value
Definition: LensTools.cpp:587
void OnGenerateOutput(wxCommandEvent &e)
wxArrayString GetTempFiles() const