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