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/Enfuse/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/Enfuse/FileListColumnWidth%d", j), -1);
253  if (width != -1)
254  {
255  m_fileListCtrl->SetColumnWidth(j, width);
256  };
257  };
258  // bind event handler
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::OnFileListChar, 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::OnAddFiles(wxCommandEvent& e)
303 {
304  wxConfigBase* config = wxConfigBase::Get();
305  wxString path = config->Read("/actualPath", "");
306  wxFileDialog dlg(this, _("Add images"), path, wxEmptyString,
307  GetFileDialogImageFilters(), wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST | wxFD_PREVIEW, wxDefaultPosition);
308  dlg.SetDirectory(path);
309 
310  // remember the image extension
311  wxString img_ext;
312  if (config->HasEntry("lastImageType"))
313  {
314  img_ext = config->Read("lastImageType").c_str();
315  }
316  if (img_ext == "all images")
317  dlg.SetFilterIndex(0);
318  else if (img_ext == "jpg")
319  dlg.SetFilterIndex(1);
320  else if (img_ext == "tiff")
321  dlg.SetFilterIndex(2);
322  else if (img_ext == "png")
323  dlg.SetFilterIndex(3);
324  else if (img_ext == "hdr")
325  dlg.SetFilterIndex(4);
326  else if (img_ext == "exr")
327  dlg.SetFilterIndex(5);
328  else if (img_ext == "all files")
329  dlg.SetFilterIndex(6);
330 
331  // call the file dialog
332  if (dlg.ShowModal() == wxID_OK)
333  {
334  // get the selections
335  wxArrayString Pathnames;
336  dlg.GetPaths(Pathnames);
337  // save the current path to config
338  config->Write("/actualPath", dlg.GetDirectory());
339  // save the image extension
340  switch (dlg.GetFilterIndex())
341  {
342  case 0: config->Write("lastImageType", "all images"); break;
343  case 1: config->Write("lastImageType", "jpg"); break;
344  case 2: config->Write("lastImageType", "tiff"); break;
345  case 3: config->Write("lastImageType", "png"); break;
346  case 4: config->Write("lastImageType", "hdr"); break;
347  case 5: config->Write("lastImageType", "exr"); break;
348  case 6: config->Write("lastImageType", "all files"); break;
349  }
350  for (auto& f : Pathnames)
351  {
352  AddFile(f);
353  }
354  }
355 }
356 
357 void EnfusePanel::OnRemoveFile(wxCommandEvent& e)
358 {
359  HuginBase::UIntSet selected;
360  if (m_fileListCtrl->GetSelectedItemCount() >= 1)
361  {
362  for (int i = 0; i < m_fileListCtrl->GetItemCount(); ++i)
363  {
364  if (m_fileListCtrl->GetItemState(i, wxLIST_STATE_SELECTED) & wxLIST_STATE_SELECTED)
365  {
366  selected.insert(i);
367  };
368  };
369  };
370  if (!selected.empty())
371  {
372  // remove selected file from wxListBox and internal file list
373  for (auto i = selected.rbegin(); i != selected.rend(); ++i)
374  {
375  if (*i >= 0 && *i < m_files.size())
376  {
377  m_fileListCtrl->DeleteItem(*i);
378  m_files.RemoveAt(*i, 1);
379  };
380  };
383  }
384  else
385  {
386  wxBell();
387  };
388 }
389 
390 void EnfusePanel::OnCreateFile(wxCommandEvent& e)
391 {
392  if (m_fileListCtrl->GetSelectedItemCount() == 1)
393  {
394  // single image selected
395  long index = m_fileListCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
396  if (index != -1)
397  {
398  CreateBrightImgDlg dlg(this);
399  wxString errorMsg;
400  if (dlg.SetImage(std::string(m_files[index].mb_str(HUGIN_CONV_FILENAME)), errorMsg))
401  {
402  if (dlg.ShowModal() == wxID_OK)
403  {
404  // get all new files
405  wxArrayString newFiles = dlg.GetTempFiles();
406  // wait a little bit before reading the files back
407  // wxMilliSleep(1000);
408  for (const auto& f : newFiles)
409  {
410  // add to list of temp files for cleanup at end
411  m_tempFiles.Add(f);
412  // add to list
413  AddFile(f);
414  };
415  };
416  }
417  else
418  {
419  hugin_utils::HuginMessageBox(errorMsg, _("Hugin toolbox"), wxOK | wxICON_QUESTION, this);
420  };
421  };
422  }
423  else
424  {
425  wxBell();
426  };
427 }
428 
429 void EnfusePanel::OnFileListChar(wxKeyEvent& e)
430 {
431  // ctrl + a, select all files
432  if (e.GetKeyCode() == 1 && e.CmdDown())
433  {
434  // select all
435  for (int i = 0; i < m_fileListCtrl->GetItemCount(); i++)
436  {
437  m_fileListCtrl->SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
438  };
439  };
440  // insert key, add file
441  if ((e.GetKeyCode() == WXK_INSERT || e.GetKeyCode() == WXK_NUMPAD_INSERT) && !e.HasAnyModifiers())
442  {
443  wxCommandEvent e(wxEVT_BUTTON);
444  e.SetId(XRCID("enfuse_add_file"));
445  this->GetEventHandler()->AddPendingEvent(e);
446  };
447  // delete key, delete selected file
448  if ((e.GetKeyCode() == WXK_DELETE || e.GetKeyCode() == WXK_NUMPAD_DELETE) && !e.HasAnyModifiers())
449  {
450  if (m_fileListCtrl->GetSelectedItemCount() > 0)
451  {
452  wxCommandEvent e(wxEVT_BUTTON);
453  e.SetId(XRCID("enfuse_remove_file"));
454  this->GetEventHandler()->AddPendingEvent(e);
455  }
456  else
457  {
458  wxBell();
459  };
460  };
461  e.Skip();
462 }
463 
464 void EnfusePanel::OnFileSelectionChanged(wxCommandEvent& e)
465 {
466  // enable/disable button according to selected files
468 }
469 
471 {
473 }
474 
476 static const wxString defaultIni
477 {
478  "[Enfuse_Settings]\n"
479  "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"
480  "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"
481 };
482 
483 wxFileConfig* ReadIni(const wxString& filename)
484 {
485  wxInputStream* iniStream{ nullptr };
486  if (wxFileExists(filename))
487  {
488  iniStream = new wxFileInputStream(filename);
489  if (!iniStream->IsOk())
490  {
491  delete iniStream;
492  iniStream = nullptr;
493  }
494  };
495  if (iniStream == nullptr)
496  {
497  iniStream = new wxStringInputStream(defaultIni);
498  };
499  // now read from stream
500  wxFileConfig* iniFile=new wxFileConfig(*iniStream);
501  delete iniStream;
502  return iniFile;
503 }
504 
505 void EnfusePanel::OnLoadSetting(wxCommandEvent& e)
506 {
507  wxFileName iniFilename(hugin_utils::GetUserAppDataDir(), "toolbox.ini");
508  wxFileConfig* iniFile = ReadIni(iniFilename.GetFullPath());
509  // read known settings from file
510  iniFile->SetPath("Enfuse_Settings");
511  wxArrayString knownNames;
512  wxArrayString knownSettings;
513  wxString key;
514  long indexKey;
515  bool hasKeys = iniFile->GetFirstEntry(key, indexKey);
516  while (hasKeys)
517  {
518  knownNames.push_back(key);
519  knownSettings.push_back(iniFile->Read(key));
520  hasKeys = iniFile->GetNextEntry(key, indexKey);
521  };
522  int selection=wxGetSingleChoiceIndex(_("Select the Enfuse setting, which should be loaded."), _("Hugin toolbox"), knownNames, 0, this);
523  if (selection != -1)
524  {
525  SetPropertyGridContent(m_enfuseOptions, knownSettings[selection]);
526  };
527  delete iniFile;
528 }
529 
530 void EnfusePanel::OnSaveSetting(wxCommandEvent& e)
531 {
532  wxFileName iniFilename(hugin_utils::GetUserAppDataDir(), "toolbox.ini");
533  wxFileConfig* iniFile = ReadIni(iniFilename.GetFullPath());
534  // read known settings from file
535  iniFile->SetPath("Enfuse_Settings");
536  wxArrayString knownNames;
537  wxString key;
538  long indexKey;
539  bool hasKeys = iniFile->GetFirstEntry(key, indexKey);
540  while (hasKeys)
541  {
542  knownNames.push_back(key);
543  hasKeys = iniFile->GetNextEntry(key, indexKey);
544  };
545  wxString name;
546  while (true)
547  {
548  name = wxGetTextFromUser(_("Enter name of Enfuse setting"), "Enfuse settings", name, this);
549  if (name.IsEmpty())
550  {
551  // empty name or cancel
552  delete iniFile;
553  return;
554  };
555  // remove the '=' character from name, it is used as separator in ini file
556  name.Replace("=", "", true);
557  if (knownNames.Index(name) != wxNOT_FOUND)
558  {
559  if (hugin_utils::HuginMessageBox(wxString::Format(_("Enfuse setting with name \"%s\" is already existing.\nShould it be overwritten?"), name),
560  _("Hugin toolbox"), wxYES_NO | wxICON_QUESTION, this) == wxYES)
561  {
562  break;
563  };
564  }
565  else
566  {
567  break;
568  };
569  };
570  // finally write settings
571  iniFile->Write(name, GetPropertyGridContent(m_enfuseOptions));
572  // finally write to disc
573  wxFileOutputStream iniStream(iniFilename.GetFullPath());
574  bool success = true;
575  if (iniStream.IsOk())
576  {
577  success = iniFile->Save(iniStream);
578  };
579  if (!success)
580  {
581  hugin_utils::HuginMessageBox(wxString::Format(_("Could not save ini file \"%s\"."), iniFilename.GetFullPath()), _("Hugin toolbox"), wxOK | wxICON_ERROR, this);
582  };
583  delete iniFile;
584 }
585 
586 void EnfusePanel::OnResetSetting(wxCommandEvent& e)
587 {
588  // reset all settings to default values
589  m_enfuseOptions->SetPropertyValue("exposureWeight", 1.0);
590  m_enfuseOptions->SetPropertyValue("saturationWeight", 0.0);
591  m_enfuseOptions->SetPropertyValue("contrastWeight", 0.0);
592  m_enfuseOptions->SetPropertyValue("entropyWeight", 0.0);
593  m_enfuseOptions->SetPropertyValue("hardMask", false);
594  m_enfuseOptions->SetPropertyValue("levels", 0);
595  m_enfuseOptions->SetPropertyValue("blendColorspace", 0);
596  m_enfuseOptions->SetPropertyValue("wrapMode", 0);
597  m_enfuseOptions->SetPropertyValue("exposureOptimum", 0.5);
598  m_enfuseOptions->SetPropertyValue("exposureWidth", 0.2);
599  m_enfuseOptions->SetPropertyValue("contrastEdgeScale", 0.0);
600  m_enfuseOptions->SetPropertyValue("contrastMinCurvature", 0.0);
601  m_enfuseOptions->SetPropertyValue("contrastWindowSize", 5);
602  m_enfuseOptions->SetPropertyValue("entropyLowerCutoff", 0.0);
603  m_enfuseOptions->SetPropertyValue("entropyUpperCutoff", 100.0);
604  m_enfuseOptions->SetPropertyValue("entropyWindowSize", 3);
605  m_enfuseOptions->SetPropertyValue("exposureLowerCutoff", 0.0);
606  m_enfuseOptions->SetPropertyValue("exposureUpperCutoff", 100.0);
607  m_enfuseOptions->SetPropertyValue("exposureWeightFunction", 0);
608  m_enfuseOptions->SetPropertyValue("grayProjector", 1);
609 }
610 
611 void EnfusePanel::OnGeneratePreview(wxCommandEvent& e)
612 {
613  // create temp file name, set extension to tif
614  m_outputFilenames.resize(2);
615  wxFileName tempfile(wxFileName::CreateTempFileName(HuginQueue::GetConfigTempDir(wxConfig::Get()) + "he"));
616  m_outputFilenames[1] = tempfile.GetFullPath();
617  tempfile.SetExt("tif");
618  m_outputFilenames[0] = tempfile.GetFullPath();
619  m_cleanupOutput = true;
620  // get command line and execute
621  ExecuteEnfuse();
622 }
623 
625 {
626  wxString cmd = GetEnfuseCommandLine();
627  if (!cmd.IsEmpty())
628  {
629  EnableOutputButtons(false);
631  cmd = HuginQueue::wxEscapeFilename(HuginQueue::GetExternalProgram(wxConfigBase::Get(), wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR), "enfuse")) + cmd;
632  m_logWindow->AddString(cmd);
634  }
635 }
636 
638 {
639  wxString cmd = GetEnfuseCommandLine();
640  if (!cmd.IsEmpty())
641  {
642  EnableOutputButtons(false);
645  wxString exePath = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
646  queue->push_back(new HuginQueue::NormalCommand(HuginQueue::GetExternalProgram(wxConfig::Get(), exePath, "enfuse"), cmd, _("Merging images") + " (" + cmd + ")"));
647  // get first image
648  long index = -1;
649  for (long i = 0; i < m_fileListCtrl->GetItemCount(); ++i)
650  {
651  if (m_fileListCtrl->IsItemChecked(i))
652  {
653  index = i;
654  break;
655  };
656  };
657  wxString exiftoolArgs(" -overwrite_original -tagsfromfile " + HuginQueue::wxEscapeFilename(m_files[index]));
658  exiftoolArgs.Append(" -all:all --thumbnail --thumbnailimage --xposition --yposition --imagefullwidth --imagefullheight ");
659  exiftoolArgs.Append(HuginQueue::wxEscapeFilename(m_outputFilenames[0]));
660  queue->push_back(new HuginQueue::OptionalCommand(HuginQueue::GetExternalProgram(wxConfig::Get(), exePath, "exiftool"), exiftoolArgs, _("Updating EXIF")));
661  m_logWindow->ExecQueue(queue);
662  };
663 }
664 
665 void EnfusePanel::OnGenerateOutput(wxCommandEvent& e)
666 {
667  if (m_files.IsEmpty())
668  {
669  wxBell();
670  return;
671  };
672  wxConfigBase* config = wxConfigBase::Get();
673  wxString path = config->Read("/actualPath", "");
674  wxFileDialog dlg(this, _("Save output"), path, wxEmptyString, GetMainImageFilters(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
675  dlg.SetDirectory(path);
676 
677  // remember the image extension
678  wxString img_ext;
679  if (config->HasEntry("lastImageType"))
680  {
681  img_ext = config->Read("lastImageType").c_str();
682  }
683  if (img_ext == "jpg")
684  {
685  dlg.SetFilterIndex(0);
686  }
687  else
688  {
689  if (img_ext == "tiff")
690  {
691  dlg.SetFilterIndex(1);
692  }
693  else
694  {
695  if (img_ext == "png")
696  {
697  dlg.SetFilterIndex(2);
698  };
699  };
700  };
701  wxFileName outputfilename(m_files[0]);
702  outputfilename.SetName(outputfilename.GetName() + "_stacked");
703  dlg.SetFilename(outputfilename.GetFullPath());
704  // call the file dialog
705  if (dlg.ShowModal() == wxID_OK)
706  {
707  m_outputFilenames.resize(1);
708  m_outputFilenames[0] = dlg.GetPath();
709  // save the current path to config
710  config->Write("/actualPath", dlg.GetDirectory());
711  // save the image extension
712  switch (dlg.GetFilterIndex())
713  {
714  case 0:
715  config->Write("lastImageType", "jpg");
716  break;
717  case 1:
718  config->Write("lastImageType", "tiff");
719  break;
720  case 2:
721  config->Write("lastImageType", "png");
722  break;
723  };
724  m_cleanupOutput = false;
726  };
727 }
728 
729 void EnfusePanel::OnZoom(wxCommandEvent& e)
730 {
731  double factor;
732  switch (e.GetSelection())
733  {
734  case 0:
735  factor = 1;
736  break;
737  case 1:
738  // fit to window
739  factor = 0;
740  break;
741  case 2:
742  factor = 2;
743  break;
744  case 3:
745  factor = 1.5;
746  break;
747  case 4:
748  factor = 0.75;
749  break;
750  case 5:
751  factor = 0.5;
752  break;
753  case 6:
754  factor = 0.25;
755  break;
756  default:
757  DEBUG_ERROR("unknown scale factor");
758  factor = 1;
759  }
760  m_preview->setScale(factor);
761 }
762 
763 void EnfusePanel::OnProcessFinished(wxCommandEvent& e)
764 {
765  wxFileName output(m_outputFilenames[0]);
766  if (output.FileExists() && output.GetSize()>0)
767  {
768  m_preview->setImage(output.GetFullPath());
769  };
770  EnableOutputButtons(true);
771  if (m_cleanupOutput && output.FileExists())
772  {
773  // cleanup up preview files
774  for (const auto& f : m_outputFilenames)
775  {
776  wxRemoveFile(f);
777  };
778  };
779 }
780 
782 {
783  // all weight options, with spin control
784  wxPGProperty* prop = m_enfuseOptions->Append(new wxFloatProperty("Exposure weight", "exposureWeight", 1));
785  prop->SetEditor(wxPGEditor_SpinCtrl);
786  prop->SetAttribute(wxPG_ATTR_MIN, 0);
787  prop->SetAttribute(wxPG_ATTR_MAX, 1);
788  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.05);
789  prop = m_enfuseOptions->Append(new wxFloatProperty("Saturation weight", "saturationWeight", 0));
790  prop->SetEditor(wxPGEditor_SpinCtrl);
791  prop->SetAttribute(wxPG_ATTR_MIN, 0);
792  prop->SetAttribute(wxPG_ATTR_MAX, 1);
793  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.05);
794  prop = m_enfuseOptions->Append(new wxFloatProperty("Contrast weight", "contrastWeight", 0));
795  prop->SetEditor(wxPGEditor_SpinCtrl);
796  prop->SetAttribute(wxPG_ATTR_MIN, 0);
797  prop->SetAttribute(wxPG_ATTR_MAX, 1);
798  prop = m_enfuseOptions->Append(new wxFloatProperty("Entropy weight", "entropyWeight", 0));
799  prop->SetEditor(wxPGEditor_SpinCtrl);
800  prop->SetAttribute(wxPG_ATTR_MIN, 0);
801  prop->SetAttribute(wxPG_ATTR_MAX, 1);
802  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.05);
803  // hard / soft mask
804  m_enfuseOptions->Append(new wxBoolProperty("Hard mask", "hardMask", false));
805  // general options
806  prop = m_enfuseOptions->Append(new wxPropertyCategory(_("General"), "general"));
807  prop = m_enfuseOptions->Append(new wxIntProperty("Levels", "levels", 0));
808  prop->SetEditor(wxPGEditor_SpinCtrl);
809  prop->SetAttribute(wxPG_ATTR_MIN, -29);
810  prop->SetAttribute(wxPG_ATTR_MAX, 29);
811  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 1);
812  wxArrayString blendColorspaces;
813  blendColorspaces.Add("Auto");
814  blendColorspaces.Add("Identity (RGB)");
815  blendColorspaces.Add("CIELab");
816  blendColorspaces.Add("CIELuv");
817  blendColorspaces.Add("CIECAM02");
818  m_enfuseOptions->Append(new wxEnumProperty("Blend colorspace", "blendColorspace", blendColorspaces));
819  wxArrayString wrapMode;
820  wrapMode.Add("None");
821  wrapMode.Add("Horizontal");
822  wrapMode.Add("Vertical");
823  wrapMode.Add("Both");
824  m_enfuseOptions->Append(new wxEnumProperty("Wrap mode", "wrapMode", wrapMode));
825  m_enfuseOptions->Collapse("general");
826  m_enfuseOptions->Append(new wxPropertyCategory(_("Fusions options"), "fusionOptions"));
827  prop = m_enfuseOptions->Append(new wxFloatProperty("Exposure optimum", "exposureOptimum", 0.5));
828  prop->SetEditor(wxPGEditor_SpinCtrl);
829  prop->SetAttribute(wxPG_ATTR_MIN, 0);
830  prop->SetAttribute(wxPG_ATTR_MAX, 1);
831  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.05);
832  prop = m_enfuseOptions->Append(new wxFloatProperty("Exposure width", "exposureWidth", 0.2));
833  prop->SetEditor(wxPGEditor_SpinCtrl);
834  prop->SetAttribute(wxPG_ATTR_MIN, 0);
835  prop->SetAttribute(wxPG_ATTR_MAX, 1);
836  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.05);
837  prop = m_enfuseOptions->Append(new wxFloatProperty("Contrast edge scale", "contrastEdgeScale", 0));
838  prop->SetEditor(wxPGEditor_SpinCtrl);
839  prop->SetAttribute(wxPG_ATTR_MIN, 0);
840  prop->SetAttribute(wxPG_ATTR_MAX, 5);
841  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.1);
842  prop = m_enfuseOptions->Append(new wxFloatProperty("Contrast min curvature", "contrastMinCurvature", 0));
843  prop->SetEditor(wxPGEditor_SpinCtrl);
844  prop->SetAttribute(wxPG_ATTR_MIN, 0);
845  prop->SetAttribute(wxPG_ATTR_MAX, 50);
846  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.5);
847  prop = m_enfuseOptions->Append(new wxIntProperty("Contrast window size", "contrastWindowSize", 5));
848  prop->SetEditor(wxPGEditor_SpinCtrl);
849  prop->SetAttribute(wxPG_ATTR_MIN, 3);
850  prop->SetAttribute(wxPG_ATTR_MAX, 30);
851  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 1);
852  prop = m_enfuseOptions->Append(new wxFloatProperty("Entropy lower cutoff", "entropyLowerCutoff", 0));
853  prop->SetEditor(wxPGEditor_SpinCtrl);
854  prop->SetAttribute(wxPG_ATTR_MIN, 0);
855  prop->SetAttribute(wxPG_ATTR_MAX, 100);
856  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.5);
857  prop = m_enfuseOptions->Append(new wxFloatProperty("Entropy higher cutoff", "entropyUpperCutoff", 100));
858  prop->SetEditor(wxPGEditor_SpinCtrl);
859  prop->SetAttribute(wxPG_ATTR_MIN, 0);
860  prop->SetAttribute(wxPG_ATTR_MAX, 100);
861  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.5);
862  prop = m_enfuseOptions->Append(new wxIntProperty("Entropy window size", "entropyWindowSize", 3));
863  prop->SetEditor(wxPGEditor_SpinCtrl);
864  prop->SetAttribute(wxPG_ATTR_MIN, 3);
865  prop->SetAttribute(wxPG_ATTR_MAX, 7);
866  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 1);
867  prop = m_enfuseOptions->Append(new wxFloatProperty("Expoure lower cutoff", "exposureLowerCutoff", 0));
868  prop->SetEditor(wxPGEditor_SpinCtrl);
869  prop->SetAttribute(wxPG_ATTR_MIN, 0);
870  prop->SetAttribute(wxPG_ATTR_MAX, 100);
871  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.5);
872  prop = m_enfuseOptions->Append(new wxFloatProperty("Exposure higher cutoff", "exposureUpperCutoff", 100));
873  prop->SetEditor(wxPGEditor_SpinCtrl);
874  prop->SetAttribute(wxPG_ATTR_MIN, 0);
875  prop->SetAttribute(wxPG_ATTR_MAX, 100);
876  prop->SetAttribute(wxPG_ATTR_SPINCTRL_STEP, 0.5);
877  wxArrayString exposureWeightFunction;
878  exposureWeightFunction.Add("Gaussian");
879  exposureWeightFunction.Add("Lorentzian");
880  exposureWeightFunction.Add("Half-sine");
881  exposureWeightFunction.Add("Full-sine");
882  exposureWeightFunction.Add("Bi-square");
883  m_enfuseOptions->Append(new wxEnumProperty("Exposure weight function", "exposureWeightFunction", exposureWeightFunction));
884  wxArrayString grayProjector;
885  grayProjector.Add("anti-value"); // index 0
886  grayProjector.Add("Average"); // index 1
887  grayProjector.Add("L-channel from Lab (gamma=1)"); // index 2
888  grayProjector.Add("L-channel from Lab (gamma corrected)"); // index 3
889  grayProjector.Add("Lightness"); // index 4
890  grayProjector.Add("Luminance"); // index 5
891  grayProjector.Add("Value from HSV"); // index 6
892  // missing: channelMixel
893  prop = m_enfuseOptions->Append(new wxEnumProperty("Gray projector", "grayProjector", grayProjector));
894  m_enfuseOptions->SetPropertyValue("grayProjector", 1);
895  // if you add new options also update GetEnfuseOptions() and OnResetSetting(..)
896 }
897 
899 {
900  wxString commandline("--verbose ");
901  double doubleValue=m_enfuseOptions->GetPropertyValueAsDouble("exposureWeight");
902  if (doubleValue != 1)
903  {
904  commandline.Append(" --exposure-weight=" + wxString::FromCDouble(doubleValue));
905  };
906  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("saturationWeight");
907  if (doubleValue != 0)
908  {
909  commandline.Append(" --saturation-weight=" + wxString::FromCDouble(doubleValue));
910  };
911  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("contrastWeight");
912  if (doubleValue != 0)
913  {
914  commandline.Append(" --contrast-weight=" + wxString::FromCDouble(doubleValue));
915  };
916  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("entropyWeight");
917  if (doubleValue != 0)
918  {
919  commandline.Append(" --entropy-weight=" + wxString::FromCDouble(doubleValue));
920  };
921  bool boolVal = m_enfuseOptions->GetPropertyValueAsBool("hardMask");
922  if (boolVal)
923  {
924  commandline.Append(" --hard-mask");
925  };
926  int intValue = m_enfuseOptions->GetPropertyValueAsInt("levels");
927  if (intValue != 0)
928  {
929  commandline.Append(wxString::Format(" --level=%d", intValue));
930  };
931  intValue = m_enfuseOptions->GetPropertyValueAsInt("blendColorspace");
932  switch (intValue)
933  {
934  case 1:
935  commandline.Append(" --blend-colorspace=identity");
936  break;
937  case 2:
938  commandline.Append(" --blend-colorspace=cielab");
939  break;
940  case 3:
941  commandline.Append(" --blend-colorspace=cieluv");
942  break;
943  case 4:
944  commandline.Append(" --blend-colorspace=ciecam");
945  break;
946  default:
947  case 0:
948  // do nothing
949  break;
950  };
951  intValue = m_enfuseOptions->GetPropertyValueAsInt("wrapMode");
952  switch (intValue)
953  {
954  case 1:
955  commandline.Append(" --wrap=horizontal");
956  break;
957  case 2:
958  commandline.Append(" --wrap=vertical");
959  break;
960  case 3:
961  commandline.Append(" --wrap=both ");
962  break;
963  case 0:
964  default:
965  break;
966  };
967  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("exposureOptimum");
968  if (doubleValue != 0.5)
969  {
970  commandline.Append(" --exposure-optimum=" + wxString::FromCDouble(doubleValue));
971  };
972  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("exposureWidth");
973  if (doubleValue != 0.2)
974  {
975  commandline.Append(" --exposure-width=" + wxString::FromCDouble(doubleValue));
976  };
977  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("contrastEdgeScale");
978  if (doubleValue != 0)
979  {
980  commandline.Append(" --contrast-edge-scale=" + wxString::FromCDouble(doubleValue));
981  };
982  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("contrastMinCurvature");
983  if (doubleValue != 0)
984  {
985  commandline.Append(" --contrast-min-curvature=" + wxString::FromCDouble(doubleValue) + "%");
986  };
987  intValue = m_enfuseOptions->GetPropertyValueAsInt("contrastWindowSize");
988  if (intValue != 5)
989  {
990  commandline.Append(wxString::Format(" --contrast-window-size=%d", intValue));
991  };
992  // entropy cutoff
993  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("entropyLowerCutoff");
994  double doubleValue2 = m_enfuseOptions->GetPropertyValueAsDouble("entropyUpperCutoff");
995  if (doubleValue > 0 || doubleValue2 < 100)
996  {
997  commandline.Append(" --entropy-cutoff=" + wxString::FromCDouble(doubleValue) + "%");
998  if (doubleValue2 < 100)
999  {
1000  commandline.Append(":" + wxString::FromCDouble(doubleValue2) + "%");
1001  };
1002  };
1003  intValue = m_enfuseOptions->GetPropertyValueAsInt("entropyWindowSize");
1004  if (intValue != 3)
1005  {
1006  commandline.Append(wxString::Format(" --entropy-window-size=%d", intValue));
1007  };
1008  // exposure cutoff
1009  doubleValue = m_enfuseOptions->GetPropertyValueAsDouble("exposureLowerCutoff");
1010  doubleValue2 = m_enfuseOptions->GetPropertyValueAsDouble("exposureUpperCutoff");
1011  if (doubleValue > 0 || doubleValue2 < 100)
1012  {
1013  commandline.Append(" --exposure-cutoff=" + wxString::FromCDouble(doubleValue) + "%");
1014  if (doubleValue2 < 100)
1015  {
1016  commandline.Append(":" + wxString::FromCDouble(doubleValue2) + "%");
1017  };
1018  };
1019  // exposure weight function
1020  intValue = m_enfuseOptions->GetPropertyValueAsInt("exposureWeightFunction");
1021  switch (intValue)
1022  {
1023  case 1:
1024  commandline.Append(" --exposure-weight-function=lorentz");
1025  break;
1026  case 2:
1027  commandline.Append(" --exposure-weight-function=halfsine");
1028  break;
1029  case 3:
1030  commandline.Append(" --exposure-weight-function=fullsine");
1031  break;
1032  case 4:
1033  commandline.Append(" --exposure-weight-function=bisquare");
1034  break;
1035  case 0:
1036  default:
1037  break;
1038  };
1039  // gray projector
1040  intValue = m_enfuseOptions->GetPropertyValueAsInt("grayProjector");
1041  switch (intValue)
1042  {
1043  case 0:
1044  commandline.Append(" --gray-projector=anti-value");
1045  break;
1046  case 2:
1047  commandline.Append(" --gray-projector=al-star");
1048  break;
1049  case 3:
1050  commandline.Append(" --gray-projector=pl-star");
1051  break;
1052  case 4:
1053  commandline.Append(" --gray-projector=lightness");
1054  break;
1055  case 5:
1056  commandline.Append(" --gray-projector=luminance");
1057  break;
1058  case 6:
1059  commandline.Append(" --gray-projector=value");
1060  break;
1061  case 1:
1062  default:
1063  break;
1064  };
1065  return commandline;
1066 }
1067 
1069 {
1070  wxString commandline(" --output=" + hugin_utils::wxQuoteFilename(m_outputFilenames[0]));
1071  // add options from control
1072  commandline.Append(" ");
1073  commandline.Append(GetEnfuseOptions());
1074  // now build image list
1075  wxArrayInt selectedFiles;
1076  for (int i = 0; i < m_fileListCtrl->GetItemCount(); ++i)
1077  {
1078  if (m_fileListCtrl->IsItemChecked(i))
1079  {
1080  selectedFiles.push_back(i);
1081  };
1082  };
1083  if (selectedFiles.IsEmpty())
1084  {
1085  hugin_utils::HuginMessageBox(_("Please activate at least one file."), _("Hugin_toolbox"), wxOK | wxOK_DEFAULT | wxICON_WARNING, this);
1086  return wxEmptyString;
1087  }
1088  for (int i = 0; i < selectedFiles.size(); ++i)
1089  {
1090  commandline.Append(" ");
1091  commandline.Append(hugin_utils::wxQuoteFilename(m_files[selectedFiles[i]]));
1092  }
1093  return commandline;
1094 }
1095 
1097 {
1098  // enable/disable button according to selected files
1099  XRCCTRL(*this, "enfuse_remove_file", wxButton)->Enable(m_fileListCtrl->GetSelectedItemCount() >= 1);
1100  XRCCTRL(*this, "enfuse_create_file", wxButton)->Enable(m_fileListCtrl->GetSelectedItemCount() == 1);
1101 }
1102 
1104 {
1105  // count checked items
1106  long count = 0;
1107  for (int i = 0; i < m_fileListCtrl->GetItemCount(); ++i)
1108  {
1109  if (m_fileListCtrl->IsItemChecked(i))
1110  {
1111  ++count;
1112  };
1113  };
1114  return count;
1115 }
1116 
1118 {
1119  XRCCTRL(*this, "enfuse_preview", wxButton)->Enable(enable);
1120  XRCCTRL(*this, "enfuse_enfuse", wxButton)->Enable(enable);
1121 
1122 }
1123 
1125 {
1126  for (const auto& f : m_tempFiles)
1127  {
1128  wxRemoveFile(f);
1129  };
1130 }
1131 
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 OnAddFiles(wxCommandEvent &e)
event handler
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:90
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
#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:88
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:93
PreviewWindow * m_preview
Definition: EnfusePanel.h:89
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:86
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:92
void OnFileListChar(wxKeyEvent &e)
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:87
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:91
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