Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
BVWXMainFrame.cpp
1 /*
2  This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4  Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10  BIAS is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation; either version 2.1 of the License, or
13  (at your option) any later version.
14 
15  BIAS 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
18  GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with BIAS; if not, write to the Free Software
22  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #include "BVWXMainFrame.hh"
26 #include <Gui/FilterDialogMean.hh>
27 #include <Gui/FilterDialogGradientSobel3x3.hh>
28 #include <Gui/FilterDialogRescale.hh>
29 #include <Gui/FilterDialogGauss.hh>
30 #include <Gui/FilterDialogMedian.hh>
31 #include <Gui/FilterDialogCannyEdge.hh>
32 #include <Gui/wxVideoSettingsDialog.h>
33 #include <Utils/StringUtils.hh>
34 #include <Utils/ImageValueBar.hh>
35 #ifdef BIAS_HAVE_FFMPEG
36 #include <VideoSink/VideoSink_FFmpeg.hh>
37 #endif
38 #include <wx/printdlg.h>
39 #include <wx/string.h>
40 #include <wx/event.h>
41 #include <wx/artprov.h>
42 #include <wx/aboutdlg.h>
43 #include <wx/progdlg.h>
44 #include <string>
45 #include <sstream>
46 #include <limits>
47 
48 typedef unsigned char UCHAR;
49 
50 using namespace std;
51 using namespace BIAS;
52 
53 // icon
54 #if !defined(__WXPM__)
55 # include <img/biasviewwx.xpm>
56 # include <img/play.xpm>
57 # include <img/stopplaying.xpm>
58 #endif
59 
60 BEGIN_EVENT_TABLE(BVWXMainFrame, wxFrame)
61 EVT_MENU (BVWXMainFrame::ID_Exit, BVWXMainFrame::OnExit)
62 EVT_MENU (BVWXMainFrame::ID_Load, BVWXMainFrame::OnLoad)
63 EVT_MENU (BVWXMainFrame::ID_RemoveCurrent, BVWXMainFrame::OnRemoveCurrent)
64 EVT_MENU (BVWXMainFrame::ID_RemoveAllButCurrent, BVWXMainFrame::OnRemoveAllButCurrent)
65 EVT_MENU (BVWXMainFrame::ID_Info, BVWXMainFrame::OnInfo)
66 EVT_MENU (BVWXMainFrame::ID_MetaData, BVWXMainFrame::OnMetaData)
67 EVT_MENU (BVWXMainFrame::ID_SaveAs, BVWXMainFrame::OnSaveAs)
68 EVT_MENU (BVWXMainFrame::ID_SaveCurrent, BVWXMainFrame::OnSaveCurrent)
69 EVT_MENU (BVWXMainFrame::ID_SaveMovie, BVWXMainFrame::OnSaveAsMovie)
70 
71 EVT_MENU (BVWXMainFrame::ID_PrintCurrent, BVWXMainFrame::OnPrintCurrent)
72 EVT_MENU (BVWXMainFrame::ID_Print, BVWXMainFrame::OnPrint)
73 EVT_MENU (BVWXMainFrame::ID_SaveList, BVWXMainFrame::OnSaveList)
74 EVT_MENU (BVWXMainFrame::ID_ImageValues, BVWXMainFrame::OnImageValues)
75 EVT_MENU (BVWXMainFrame::ID_DrawROI, BVWXMainFrame::OnDrawROI)
76 EVT_MENU (BVWXMainFrame::ID_Histogramm, BVWXMainFrame::OnHistogramm)
77 EVT_MENU (BVWXMainFrame::ID_ImageValueBar, BVWXMainFrame::OnImageValueBar)
78 
79 EVT_MENU (BVWXMainFrame::ID_KeyInfo, BVWXMainFrame::OnKeyInfo)
80 EVT_MENU (wxID_ABOUT, BVWXMainFrame::OnAbout)
81 
82 EVT_BUTTON (BVWXMainFrame::ID_Next, BVWXMainFrame::OnNext)
83 EVT_BUTTON (BVWXMainFrame::ID_Prev, BVWXMainFrame::OnPrev)
84 EVT_BUTTON (BVWXMainFrame::ID_RunStop, BVWXMainFrame::OnRunStop)
85 EVT_BUTTON (BVWXMainFrame::ID_Run, BVWXMainFrame::OnRun)
86 EVT_BUTTON (BVWXMainFrame::ID_Stop, BVWXMainFrame::OnStop)
87 EVT_BUTTON (BVWXMainFrame::ID_Histogramm, BVWXMainFrame::OnHistogramm)
88 EVT_BUTTON (BVWXMainFrame::ID_ImageValueBar, BVWXMainFrame::OnImageValueBar)
89 EVT_SPINCTRL(BVWXMainFrame::ID_Delay, BVWXMainFrame::OnDelay)
90 EVT_CHECKBOX(BVWXMainFrame::ID_Fit, BVWXMainFrame::OnFit)
91 EVT_CHECKBOX(BVWXMainFrame::ID_KeepScrollPosition, BVWXMainFrame::OnKeepScrollPosition)
92 
93 EVT_MENU (BVWXMainFrame::ID_Next, BVWXMainFrame::OnNext)
94 EVT_MENU (BVWXMainFrame::ID_Prev, BVWXMainFrame::OnPrev)
95 EVT_MENU (BVWXMainFrame::ID_RunStop, BVWXMainFrame::OnRunStop)
96 EVT_MENU (BVWXMainFrame::ID_Run, BVWXMainFrame::OnRun)
97 EVT_MENU (BVWXMainFrame::ID_Stop, BVWXMainFrame::OnStop)
98 EVT_TOOL_ENTER(BVWXMainFrame::ID_ToolBar, BVWXMainFrame::OnToolEnter)
99 
100 EVT_MENU (BVWXMainFrame::ID_ChangeChannel_1, BVWXMainFrame::OnChangeChannel_1)
101 EVT_MENU (BVWXMainFrame::ID_ChangeChannel_2, BVWXMainFrame::OnChangeChannel_2)
102 EVT_MENU (BVWXMainFrame::ID_ChangeChannel_3, BVWXMainFrame::OnChangeChannel_3)
103 EVT_MENU (BVWXMainFrame::ID_ChangeChannel_4, BVWXMainFrame::OnChangeChannel_4)
104 EVT_MENU (BVWXMainFrame::ID_ChangeChannel_5, BVWXMainFrame::OnChangeChannel_5)
105 EVT_MENU (BVWXMainFrame::ID_ChangeChannel_6, BVWXMainFrame::OnChangeChannel_6)
106 EVT_MENU (BVWXMainFrame::ID_ChangeChannel_7, BVWXMainFrame::OnChangeChannel_7)
107 EVT_MENU (BVWXMainFrame::ID_ChangeChannel_8, BVWXMainFrame::OnChangeChannel_8)
108 EVT_MENU (BVWXMainFrame::ID_ChangeChannel_ALL, BVWXMainFrame::OnChangeChannel_ALL)
109 
110 EVT_MENU (BVWXMainFrame::ID_FilterCannyEdge, BVWXMainFrame::OnFilterCannyEdge)
111 EVT_MENU (BVWXMainFrame::ID_FilterGauss, BVWXMainFrame::OnFilterGauss)
112 EVT_MENU (BVWXMainFrame::ID_FilterGradientSobel3x3, BVWXMainFrame::OnFilterGradientSobel3x3)
113 EVT_MENU (BVWXMainFrame::ID_FilterMean, BVWXMainFrame::OnFilterMean)
114 EVT_MENU (BVWXMainFrame::ID_FilterMedian, BVWXMainFrame::OnFilterMedian)
115 EVT_MENU (BVWXMainFrame::ID_FilterRescale, BVWXMainFrame::OnFilterRescale)
116 
117 EVT_TIMER (BVWXMainFrame::ID_Timer, BVWXMainFrame::OnTimer)
118 EVT_IDLE (BVWXMainFrame::OnIdle)
119 EVT_SIZE (BVWXMainFrame::OnSize)
120 EVT_COMMAND (BVWXMainFrame::ID_FilterWindow, wxEVT_FILTER_SAVE, BVWXMainFrame::OnFilterSave)
121 
122 END_EVENT_TABLE()
123 
124 
125 // ctor
126 BVWXMainFrame::BVWXMainFrame(const wxString& title,
127  const wxPoint& pos,
128  const wxSize& size)
129 : wxFrame((wxFrame*)NULL, BIAS::ID_WIN_BVWX_MAINFRAME, title, pos, size),
130  _ImageCanvasUC(NULL),
131  _ImageCanvasFloat(NULL),
132  _FitCheckBox(NULL),
133  _KeepScrollPositionCheckBox(NULL)
134 {
135  SetIcon(wxIcon(biasviewwx_xpm));
136  _CurrentImage = 0;
137  _DefaultFile = wxT("ucim.pgm");
138  _DefaultDir = wxT("");
139  _BlockAnimation = true;
140  _SelectedChannel = 0;
141  _ShowImageValueBar = false;
142  _ShowHistogramm = false;
143  _HistoPosition = wxPoint(10,10);
144  _ValueBarPosition = wxPoint(150,10);
145  _HistoSize = wxSize(100,100);
146  _ValueBarSize = wxSize(200,300);
147 
148  // init timer
149  _Timer.SetOwner(this, ID_Timer);
150 
151  // create file menu
152  wxMenu* fileMenu = new wxMenu;
153  fileMenu->Append(ID_Load,
154  wxT("&Open/Load...\tCtrl-O"),
155  wxT("Open a file from disk for loading"));
156  fileMenu->Append(ID_RemoveCurrent,
157  wxT("&Remove current image...\tCtrl-R"),
158  wxT("Remove current file from viewer list"));
159  fileMenu->Append(ID_RemoveAllButCurrent,
160  wxT("Remove &all but current image"),
161  wxT("Remove all files from viewer list "));
162 
163  fileMenu->AppendSeparator();
164 
165  fileMenu->Append(ID_Info, wxT("Image Info...\tCtrl-I"));
166  fileMenu->Append(ID_MetaData, wxT("Meta Data...\tCtrl-M"));
167  fileMenu->Append(ID_ImageValues, wxT("Image Values..."));
168 
169  fileMenu->AppendSeparator();
170 
171  fileMenu->Append(ID_SaveAs,
172  wxT("&Save image as\tAlt-S"),
173  wxT("Save image to disk"));
174  fileMenu->Append(ID_SaveCurrent,
175  wxT("&Save current image\tAlt-Ctrl-S"),
176  wxT("Save image as currently displayed with storage type unsigned char to disk."));
177  fileMenu->Append(ID_SaveList,
178  wxT("&Save images list to .lst file ...\tCtrl-S"),
179  wxT("save all list of all image filenames to .lst disk file."));
180 
181  fileMenu->AppendSeparator();
182  fileMenu->Append(ID_SaveMovie,
183  wxT("Save images as movie"),
184  wxT("Save current images in list as movie to disk using ffmpeg."));
185  fileMenu->AppendSeparator();
186 
187  // fileMenu->Append(ID_PrintCurrent,
188  // wxT("&Print current image \tAlt-P"),
189  // wxT("Print only current image."));
190  // fileMenu->Append(ID_Print,
191  // wxT("Print &multiple image \tAlt-m"),
192  // wxT("Open Choise dialog and print multiple images."));
193 
194  // fileMenu->AppendSeparator();
195 
196  fileMenu->Append(ID_Exit, wxT("E&xit"), wxT("Exit this application"));
197 
198 
199  // create help menu
200  wxMenu* helpMenu = new wxMenu;
201  helpMenu->Append(ID_KeyInfo, wxT("&Keys...\tF1"));
202  helpMenu->Append(ID_About, wxT("&About...\tCtrl-F1"));
203 
204  // create channel selection menu
205  wxMenu* channelMenu = new wxMenu;
206  channelMenu->Append(ID_ChangeChannel_ALL, wxT("&0 All Channels\tShift-F9"));
207 
208  channelMenu->AppendSeparator();
209 
210  channelMenu->Append(ID_ChangeChannel_1, wxT("&1 channel (red?)\tShift-F1"));
211  channelMenu->Append(ID_ChangeChannel_2, wxT("&2 channel (green?)\tShift-F2"));
212  channelMenu->Append(ID_ChangeChannel_3, wxT("&3 channel (blue?)\tShift-F3"));
213  channelMenu->Append(ID_ChangeChannel_4, wxT("&4 channel (alpha?)\tShift-F4"));
214  channelMenu->Append(ID_ChangeChannel_5, wxT("&5 channel (H for RGB)\tShift-F5"));
215  channelMenu->Append(ID_ChangeChannel_6, wxT("&6 channel (S for RGB)\tShift-F6"));
216  channelMenu->Append(ID_ChangeChannel_7, wxT("&7 channel (L for RGB)\tShift-F7"));
217  channelMenu->Append(ID_ChangeChannel_8, wxT("&8 channel\tShift-F8"));
218 
219  wxMenu* viewMenu = new wxMenu;
220  _DrawROICheckItem = new wxMenuItem(viewMenu, ID_DrawROI, wxString(
221  wxT("Draw &ROI")), wxEmptyString, wxITEM_CHECK);
222  viewMenu->Append(_DrawROICheckItem);
223  _DrawROICheckItem->Check(false);
224 
225  _HistogramCheckItem = new wxMenuItem(viewMenu, ID_Histogramm, wxString(
226  wxT("Show &Histogramm")), wxEmptyString, wxITEM_CHECK);
227  viewMenu->Append(_HistogramCheckItem);
228  _HistogramCheckItem->Check(false);
229 
230  _ValueBarCheckItem = new wxMenuItem(viewMenu, ID_ImageValueBar, wxString(
231  wxT("Show &Legend")), wxEmptyString, wxITEM_CHECK);
232  viewMenu->Append(_ValueBarCheckItem);
233  _ValueBarCheckItem->Check(false);
234  viewMenu->AppendSeparator();
235  viewMenu->Append( ID_Prev, wxT("&Previous \tCTRL-LEFT"));
236  viewMenu->Append( ID_Next, wxT("&Next \tCTRL-RIGHT"));
237  viewMenu->Append( ID_RunStop, wxT("&Run/Stop \tCTRL-SPACE"));
238 
239  // create filter menu
240  wxMenu* filterMenu = new wxMenu;
241  filterMenu->Append(ID_FilterCannyEdge,
242  wxT("&Canny Edge\tAlt-Ctrl-C"),
243  wxT("Canny edge filter"));
244  filterMenu->Append(ID_FilterGauss,
245  wxT("&Gauss\tAlt-Ctrl-G"),
246  wxT("Gauss filter"));
247  filterMenu->Append(ID_FilterGradientSobel3x3,
248  wxT("G&radient Sobel 3x3\tAlt-Ctrl-R"),
249  wxT("Gradient sobel filter"));
250  filterMenu->Append(ID_FilterMean,
251  wxT("&Mean\tAlt-Ctrl-M"),
252  wxT("Mean filter"));
253  filterMenu->Append(ID_FilterMedian,
254  wxT("Me&dian\tAlt-Ctrl-D"),
255  wxT("Median filter"));
256  filterMenu->Append(ID_FilterRescale,
257  wxT("Resc&ale\tAlt-Ctrl-A"),
258  wxT("Rescale"));
259 
260  // create menu bar
261  wxMenuBar* menuBar = new wxMenuBar;
262  menuBar->Append(fileMenu, wxT("&File"));
263  menuBar->Append(channelMenu, wxT("&Channel"));
264  menuBar->Append(viewMenu, wxT("&View"));
265  menuBar->Append(filterMenu, wxT("Fil&ter"));
266  menuBar->Append(helpMenu, wxT("&Help"));
267  SetMenuBar(menuBar);
268 
269  // create status bar
270  const int numFields = 3;
271  CreateStatusBar(numFields);
272  int widths[] = {30 * GetCharWidth(),-1, 60 * GetCharWidth()};// sizes of fields in array, negative means relative *variable* size
273  // positive means absolute *fixed* size FRISO
274  SetStatusWidths(numFields, widths);
275  SetStatusText(wxT("Welcome to BiasViewWX"), 0);
276 
277  // create tool bar
278  wxToolBar* toolBar = CreateToolBar(wxTB_HORIZONTAL | wxNO_BORDER |wxTB_TEXT,ID_ToolBar);
279  //toolBar->CaptureMouse();
280 
281  //this tells especially windows that 24x24 px icons are used
282  toolBar->SetToolBitmapSize(wxSize(24,24));
283 
284  toolBar->AddTool( ID_Load, wxT("Open"),
285  wxArtProvider::GetIcon(wxART_FILE_OPEN,wxART_TOOLBAR), wxT("Open image(s)"));
286  toolBar->AddTool( ID_SaveCurrent, wxT("Save Current"),
287  wxArtProvider::GetIcon(wxART_FILE_SAVE,wxART_TOOLBAR),wxT("Save image as currently displayed with storage type unsigned char to disk.") );
288  toolBar->AddTool( ID_SaveAs, wxT("Save As"),
289  wxArtProvider::GetIcon(wxART_FILE_SAVE_AS,wxART_TOOLBAR),wxT("Save image with new filename.") );
290 
291  toolBar->AddSeparator();
292  toolBar->AddTool( ID_Prev, wxT("Previous"),
293  wxArtProvider::GetIcon(wxART_GO_BACK,wxART_TOOLBAR),wxT("[Ctrl-LEFT] Previous") );
294  toolBar->AddTool( ID_Next, wxT("Next"),
295  wxArtProvider::GetIcon(wxART_GO_FORWARD,wxART_TOOLBAR), wxT("Next [Ctrl-RIGHT]") );
296 
297  _RunTool = toolBar->AddTool( ID_RunStop, wxT("Run/Stop"), wxIcon(play_xpm), wxT("Run/Stop [Ctrl-SPACE]"));
298 
299  //_HistogrammButton = new wxButton(toolBar, ID_Histogramm, wxT(" Histogramm "));
300  //_ValueBarButton = new wxButton(toolBar, ID_ImageValueBar, wxT(" Legend "));
301  //toolBar->AddControl(_HistogrammButton);
302  //toolBar->AddControl(_ValueBarButton);
303 
304  toolBar->AddSeparator();
305  _ReverseCheckBox = new wxCheckBox(toolBar, ID_ReverseLoop, wxT("Reverse"));
306  toolBar->AddControl(_ReverseCheckBox);
307 
308  toolBar->AddSeparator();
309  wxSize sizeSize(60,25);
310  _DelaySpin = new wxSpinCtrl(toolBar, ID_Delay, wxT("100"),
311  wxDefaultPosition, sizeSize,
312  wxSP_ARROW_KEYS, 1, 50000,100, wxT("Delay"));
313  toolBar->AddControl(_DelaySpin);
314 
315  toolBar->AddSeparator();
316 
317  _FitCheckBox = new wxCheckBox(toolBar, ID_Fit, wxT("Fit Window"));
318  toolBar->AddControl(_FitCheckBox);
319 
320  toolBar->AddSeparator();
321 
322  _KeepScrollPositionCheckBox = new wxCheckBox(toolBar,
323  ID_KeepScrollPosition,
324  wxT("Keep Position"));
325  toolBar->AddControl(_KeepScrollPositionCheckBox);
326 
327  toolBar->Realize();
328  SetToolBar(toolBar);
329 
330  /************************************************
331  * the format of wxwindow layout is as follows:
332  *
333  * /------------------------------------\
334  * | TOOLBAR |
335  * |------------------------------------|
336  * | SIZER |
337  * |------------------------------------|
338  * | STATUSBAR |
339  * \------------------------------------/
340  *
341  * so what we do - we add a _SizerWindow to our frame
342  * (the frame handles resizing and refitting of a single
343  * window AUTOMATICALLY) and then we add wxBoxSizer
344  * _MainSizer which contains both canvases canvases as
345  * children (so that the sizer decides what size should
346  * the canvases be of)
347  ***********************************************/
348  _MainSizer = new wxBoxSizer(wxVERTICAL);
349  _SizerWindow = new wxWindow(this,-1);
350 
351  _SizerWindow->SetSizer(_MainSizer);
352 
353  // set the shortcuts, but they only seldomly work
354  std::vector<wxAcceleratorEntry> entries;
355  entries.push_back(wxAcceleratorEntry(wxACCEL_NORMAL, 'r', ID_RunStop));
356  entries.push_back(wxAcceleratorEntry(wxACCEL_NORMAL, 'h', ID_Histogramm));
357 
358  wxAcceleratorTable accel(entries.size(), (wxAcceleratorEntry*)& entries[0] );
359  this->SetAcceleratorTable(accel);
360 
361  //_NewButton->SetFocus();
362 }
363 
364 
365 BVWXMainFrame::~BVWXMainFrame() { }
366 
367 
368 void BVWXMainFrame::SetFileList(const vector<string>& fileNames)
369 {
370  _FileNames = fileNames;
371  if (_FileNames.size() > 0)
372  {
373  LoadImageFromList(0);
374  }
375 }
376 
377 void BVWXMainFrame::UncompressImage(BIAS::ImageBase & image)
378 {
380  // store info about raw image which will be lost by conversion
381  stringstream ss;
382  AddInfo(image, ss);
383  infoRaw_ = ss.str();
384 
385  // uncompress raw to different size display image
386  // the uncompression scheme can be selecetd via menu mode
387  // ... or hard coded for now
388  BIAS::ImageBase tmp = image;
389  ImageConvert::DeinterleaveHorizontal(tmp, image);
390  }
391 }
392 
393 
394 void BVWXMainFrame::LoadImageFromList(int index)
395 {
396  if (_FileNames.size() == 0)
397  {
398  //The CANVASES should be emptied and refreshed (somehow they don't
399  //do it automatically, so we have to make it M-A-N-U-A-L-L-Y
400 
401  //P.S. Somehow even with the following code written:
402  if(_ImageCanvasUC!=NULL){
403  _ImageCanvasUC->SetSize(5, 5);
404  _ImageCanvasUC->Destroy();
405  _ImageCanvasUC = NULL;
406  }
407  if(_ImageCanvasFloat!=NULL){
408  _ImageCanvasFloat->SetSize(5, 5);
409  _ImageCanvasFloat->Destroy();
410  _ImageCanvasFloat = NULL;
411  }
412 
413  _SizerWindow->SetSize(5, 5);
414  _SizerWindow->Refresh();
415  _SizerWindow->Update();
416 
417  //it doesn't work - the CANVAS remains to be shown.
418  //So what we do is a little trick:
419 
420  /**
421  ImageBase image = new ImageBase();
422  Camera<unsigned char> camera(image);
423  camera.ParseMetaData();
424  camera.PrintAppData(info);
425  **/
426 
427  return;
428  }
429 
430  _CurrentImage = index;
431  const string& fileName = _FileNames[index];
432  //cout<<"Loading image with index:"<<_CurrentImage<<" and filename:"<<fileName<<endl;
433 
434  // load image
435  ImageBase image;
436 
437  // true disk access
438  if (ImageIO::Load(fileName.c_str(), image)!=0)
439  {
440  stringstream msg;
441  msg << "Error loading " << fileName;
442  BIASERR(msg.str());
443  SetStatusText(AsciiToWx(msg.str()));
444  wxMessageBox(AsciiToWx(msg.str()),
445  wxT("Loading Error"), wxOK | wxICON_EXCLAMATION);
446  return;
447  }
448 
449  // handle compressed image sizes
450  // where display image dimension
451  // differs form orig image dimension.
452  // e..g. X3B multicam images (with three images in one file
453  // or Pyramid images, depth/color PMD,...
454  UncompressImage(image);
455 
456  // save meta data for image info dialog
457  stringstream info;
458  switch (image.GetStorageType())
459  {
460  case ImageBase::ST_unsignedchar:
461  {
462  Camera<unsigned char> camera(image);
463  camera.ParseMetaData();
464  camera.PrintAppData(info);
465  } break;
466 
467  case ImageBase::ST_float:
468  {
469  Camera<float> camera(image);
470  camera.ParseMetaData();
471  camera.PrintAppData(info);
472  } break;
473 #ifdef BUILD_IMAGE_USHORT
474  case ImageBase::ST_unsignedshortint:
475  {
476  Camera<unsigned short> camera(image);
477  camera.ParseMetaData();
478  camera.PrintAppData(info);
479  } break;
480 #endif
481  default:
482  // BIASERR("unfinished");
483  break;
484  }
485  _MetaData = info.str();
486 
487  // create appropriate image canvas based on storage type
488  if (image.GetStorageType() == ImageBase::ST_unsignedchar)
489  {
490  //check if the previous image was with floats
491  bool histo_was_shown_for_float = false;
492  bool valuebar_was_shown_for_float = false;
493 
494  // delete float image canvas
495  if (_ImageCanvasFloat != NULL)
496  {
497  //when recreating Histogramm-window, give it the same position as it had
498  //before
499  _HistoPosition = _ImageCanvasFloat->GetImageCanvas()->GetHistoPos();
500  _HistoSize = _ImageCanvasFloat->GetImageCanvas()->GetHistoSize();
501 
502  _ValueBarSize = _ImageCanvasFloat->GetImageCanvas()->GetValueBarSize();
503  _ValueBarPosition = _ImageCanvasFloat->GetImageCanvas()->GetValueBarPos();
504 
505 // cout<<"Got Pos/Size of ValueBar:"<<_ValueBarPosition.x<<","<<_ValueBarPosition.y
506 // <<_ValueBarSize.x<<_ValueBarSize.y<<endl;
507 
508  if(_ImageCanvasFloat->GetImageCanvas() != NULL){
509  if(_ImageCanvasFloat->GetImageCanvas()->HistogrammIsShown())
510  histo_was_shown_for_float = true;
511  if(_ImageCanvasFloat->GetImageCanvas()->ImageValueBarIsShown())
512  valuebar_was_shown_for_float = true;
513 
514  }
515 
516  _MainSizer->Detach(_ImageCanvasFloat);
517  _ImageCanvasFloat->Destroy();
518  _ImageCanvasFloat = NULL;
519  }
520 
521  // create uc image canvas
522  if (_ImageCanvasUC == NULL)
523  {
524  _ImageCanvasUC = new ImageCanvas(_SizerWindow, GetStatusBar(), 2, -1, wxPoint(1,1));
525  // can safely turn this on, since ImageCanvas now uses double buffering
526  _ImageCanvasUC->SetClearDrawingContext(true);
527 
528  _MainSizer->Add(_ImageCanvasUC,wxEXPAND);
529  }
530  else{
531  _HistoPosition = _ImageCanvasUC->GetHistoPos();
532  _HistoSize = _ImageCanvasUC->GetHistoSize();
533  _ValueBarSize = _ImageCanvasUC->GetValueBarSize();
534  _ValueBarPosition = _ImageCanvasUC->GetValueBarPos();
535 
536 // cout<<"Got Pos/Size of ValueBar:"<<_ValueBarPosition.x<<","<<_ValueBarPosition.y
537 // <<_ValueBarSize.x<<_ValueBarSize.y<<endl;
538  }
539  //check if the histogramm should be shown and if YES, then update it
540  if(_ShowHistogramm){
541  if(!histo_was_shown_for_float){
542  //cout << "showing histo" << endl;
543  if(_ImageCanvasUC->HistogrammIsShown())
544  ShowHistogramm(image);
545  else
546  _ShowHistogramm = false;
547  }
548  else{
549  ShowHistogramm(image);
550  }
551  }
552  //check if legend is requested and draw it (or not)
553  if(_ShowImageValueBar){
554  if(!valuebar_was_shown_for_float){
555  //cout << "showing histo" << endl;
556  if(_ImageCanvasUC->ImageValueBarIsShown())
557  ShowImageValueBar(image);
558  else
559  _ShowImageValueBar = false;
560  }
561  else{
562  ShowImageValueBar(image);
563  }
564  }
565 
566  // convert image
567  Image<unsigned char> ucImage;
568  ucImage.StealImage(image);
569  ucImage.SetUID(image.GetUID());
570 
571  if (ucImage.GetChannelCount() < _SelectedChannel) {
572  if ( _SelectedChannel>4 && _SelectedChannel<8) {
573  // show hsl for rgb-like images
575  if (ImageConvert::ToHSV(ucImage, hsl)!=0) {
576  BIASERR("Picture conversion to HSL failed.");
577  } else {
578  ucImage = hsl;
579  ImageConvert::GetChannel(ucImage, _SelectedChannel-5);
580  ucImage.SetColorModel(ImageBase::CM_RGB);
581  }
582  } else {
583  BIASERR("Can't show selected Channel, because picture has less channels.");
584  }
585  }
586  else
587  {
588  // Shows only the selected channel of image
589  if (_SelectedChannel > 0)
590  {
591  ImageConvert::GetChannel(ucImage, _SelectedChannel-1);
592  }
593  }
594 
595  if (_FitCheckBox->IsChecked()) {
596  // get size available for image canvas
597  int width, height;
598  GetClientSize(&width, &height);
599 
600  // compute scale that keeps the aspect ratio and the image is fully visible
601  float xscale = (float)width / image.GetWidth();
602  float yscale = (float)height / image.GetHeight();
603  float scale = xscale < yscale ? xscale : yscale;
604 
605  _ImageCanvasUC->SetScaledImageSize((int)(image.GetWidth() * scale), (int)(image.GetHeight() * scale));
606  _ImageCanvasUC->SetShowScaled(true);
607  }//fitcheckbox
608  else{
609  _ImageCanvasUC->SetShowScaled(false);
610  }
611 
612  // show image in canvas
613  //cout<<"Showing image with filename:"<<fileName<<endl;
614  _ImageCanvasUC->Show(ucImage, fileName);
615 
616  // don't show scrollbars if image is maximized
617  if (_FitCheckBox->IsChecked()){
618  _ImageCanvasUC->SetScrollbars(0, 0, 0, 0);
619  }
620  }
621  else // image.GetStorageType() != ImageBase::ST_unsignedchar
622  {
623  //check if the previous image was with unsigned char
624  bool histo_was_shown_for_uc = false;
625  bool valuebar_was_shown_for_uc = false;
626 
627  // delete uc image canvas
628  if (_ImageCanvasUC != NULL)
629  {
630  //when recreating Histogramm-window, give it the same position as it had
631  //before
632  _HistoPosition = _ImageCanvasUC->GetHistoPos();
633  _HistoSize = _ImageCanvasUC->GetHistoSize();
634 
635  _ValueBarSize = _ImageCanvasUC->GetValueBarSize();
636  _ValueBarPosition = _ImageCanvasUC->GetValueBarPos();
637 
638 // cout<<"Got Pos/Size of ValueBar:"<<_ValueBarPosition.x<<","<<_ValueBarPosition.y
639 // <<_ValueBarSize.x<<_ValueBarSize.y<<endl;
640 
641  if(_ImageCanvasUC->HistogrammIsShown())
642  histo_was_shown_for_uc = true;
643  if(_ImageCanvasUC->ImageValueBarIsShown())
644  valuebar_was_shown_for_uc = true;
645 
646  _MainSizer->Detach(_ImageCanvasUC);
647  _ImageCanvasUC->Destroy();
648  _ImageCanvasUC = NULL;
649  }
650 
651  // create float image canvas
652  if (_ImageCanvasFloat == NULL)
653  {
654  _ImageCanvasFloat = new ScaledImageCanvas(_SizerWindow, GetStatusBar(), 2, -1, wxPoint(1,1));
655  _MainSizer->Add(_ImageCanvasFloat,wxEXPAND);
656  }
657  else{
658  _HistoPosition = _ImageCanvasFloat->GetImageCanvas()->GetHistoPos();
659  _HistoSize = _ImageCanvasFloat->GetImageCanvas()->GetHistoSize();
660  _ValueBarSize = _ImageCanvasFloat->GetImageCanvas()->GetValueBarSize();
661  _ValueBarPosition = _ImageCanvasFloat->GetImageCanvas()->GetValueBarPos();
662 
663 // cout<<"Got Pos/Size of ValueBar:"<<_ValueBarPosition.x<<","<<_ValueBarPosition.y
664 // <<_ValueBarSize.x<<","<<_ValueBarSize.y<<endl;
665  }
666  //check if the histogramm should be shown and if YES, then update it
667  if(_ShowHistogramm){
668  if(!histo_was_shown_for_uc){
669  //cout << "showing histo" << endl;
670  if(_ImageCanvasFloat->GetImageCanvas() != NULL){
671  //cout << "canvas exists" << endl;
672  if(_ImageCanvasFloat->GetImageCanvas()->HistogrammIsShown())
673  ShowHistogramm(image);
674  else
675  _ShowHistogramm = false;
676  }
677  }
678  else{
679  if(_ImageCanvasFloat->GetImageCanvas() != NULL){
680  ShowHistogramm(image);
681  }
682  }
683  }
684  //check if legend is requested and draw it (or not)
685  if(_ShowImageValueBar){
686  if(!valuebar_was_shown_for_uc){
687  //cout << "showing histo" << endl;
688  if(_ImageCanvasFloat->GetImageCanvas() != NULL){
689  //cout << "canvas exists" << endl;
690  if(_ImageCanvasFloat->GetImageCanvas()->ImageValueBarIsShown())
691  ShowImageValueBar(image);
692  else
693  _ShowImageValueBar = false;
694  }
695  }
696  else{
697  if(_ImageCanvasFloat->GetImageCanvas() != NULL){
698  ShowImageValueBar(image);
699  }
700  }
701  }
702 
703  /**
704  // set appropriate scale and offset range
705  switch (image.GetStorageType())
706  {
707  case ImageBase::ST_unsignedshortint:
708  _ImageCanvasFloat->SetScaleRange(1.0/16.0, 1.0);
709  _ImageCanvasFloat->SetOffsetRange(-4095.0, 0.0);
710  break;
711 
712  case ImageBase::ST_char:
713  _ImageCanvasFloat->SetScaleRange(0.5, 5.0);
714  _ImageCanvasFloat->SetOffsetRange(-128.0, 128.0);
715  break;
716 
717  case ImageBase::ST_float:
718  _ImageCanvasFloat->SetScaleRange(0.5, 50.0);
719  _ImageCanvasFloat->SetOffsetRange(-100.0, 100.0);
720  break;
721 
722  default:
723  cout << "Warning: Unknown storage type" << endl;
724  break;
725  }
726  **/
727 
728  if (image.GetChannelCount() < _SelectedChannel) {
729  BIASERR("Can't show selected Channel, because picture has less channels.")
730  }
731  else
732  {
733  // Shows only the selected channel of image
734  if (_SelectedChannel > 0)
735  {
736  ImageConvert::GetChannel(image, _SelectedChannel-1);
737  }
738  }
739 
740  if (_FitCheckBox->IsChecked())
741  {
742  // get size available for image canvas
743  int width, height;
744  GetClientSize(&width, &height);
745  width = max(1, width - 10); // little fix so the image is really fully visible
746  height = max(1, height - 40); // larger fix because of sliders in float canvas
747 
748  // compute scale that keeps the aspect ratio and the image is fully visible
749  float xscale = (float)width / image.GetWidth();
750  float yscale = (float)height / image.GetHeight();
751  float scale = xscale < yscale ? xscale : yscale;
752 
753  _ImageCanvasFloat->GetImageCanvas()->SetScaledImageSize((int)(image.GetWidth() * scale), (int)(image.GetHeight() * scale));
754  _ImageCanvasFloat->GetImageCanvas()->SetShowScaled(true);
755  }
756  else
757  {
758  _ImageCanvasFloat->GetImageCanvas()->SetShowScaled(false);
759  }
760 
761  //cout<<"Showing image with filename:"<<fileName<<endl;
762  // show image in canvas
763  _ImageCanvasFloat->Show(image, fileName);
764 
765  // don't show scrollbars if image is maximized
766  if (_FitCheckBox->IsChecked())
767  {
768  _ImageCanvasFloat->GetImageCanvas()->SetScrollbars(0, 0, 0, 0);
769  }
770  }
771 
772  stringstream msg;
773  msg << "File '" << fileName << "' (" << image.GetWidth() << "x" << image.GetHeight() << ") loaded";
774  SetStatusText(AsciiToWx(msg.str()),1);
775 
776  this->RefitClients();
777 
778  // breaks WIN32
779  //#ifndef WIN32
780  // make the shortcuts work without the need to click the canvas manually (on linux)
781  //if (_ImageCanvasUC)
782  // _ImageCanvasUC->SetFocus();
783  //if (_ImageCanvasFloat)
784  // _ImageCanvasFloat->SetFocus();
785  //#endif
786 }
787 
788 void BVWXMainFrame::LoadImages(const wxArrayString &paths)
789 {
790  // add file names to internal std::string list
791  bool ok=true;
792  unsigned old_size = _FileNames.size();
793  for (int i = 0; i < (int)paths.GetCount(); i++) {
794  wxString extUP=wxFileName(paths[i]).GetExt().Upper();
795  if (wxFileName(paths[i]).IsDir()) {
796  ok=false;
797  } else if ((extUP==AsciiToWx("LST")) || (extUP==AsciiToWx("TXT"))) {
798  // special handling for .lst and .txt files.
799  // they are no images but contain a list of line separated image
800  //filenames
801  vector<string> lstFilenames;
802  int result=BIAS::Param::ParseListFile(WxToAscii(paths[i]),
803  lstFilenames);
804  if (result!=0){
805  BIASERR("could not load image list file "<<WxToAscii(paths[i])
806  <<" result="<<result<<endl);
807  } else {
808  // append filenames
809  _FileNames.insert(_FileNames.end(), lstFilenames.begin(),
810  lstFilenames.end() );
811  }
812  } else {
813  _FileNames.push_back( string(WxToAscii(paths[i])) );
814  }
815  }
816 
817  // convert filenames to right format
818  if (!_FileNames.empty()) {
819  std::string str;
820  for (std::vector<std::string>::iterator it = _FileNames.begin();
821  it != _FileNames.end(); it++) {
822  // remove whitespaces at beginning and end of filenames
823  StringUtils::Trim(*it, str);
824  // replace slash by backslash (Windows) or vice versa (Unix)
825  *it = FileHandling::CorrectSlashes(str);
826  }
827  }
828 
829  // load last added file and remember file name and directory
830  // do NOT jump to file 0 if adding files subsequently.
831  // we may discuss to jump to first of currently "added" file,
832  // but never jump to first file in list of all files!
833  if (!_FileNames.empty()) {
834  LoadImageFromList(old_size);
835  _DefaultFile = AsciiToWx(_FileNames[old_size]);
836  }
837 
838  if (!ok) {
839  wxMessageBox(wxT("Dropping directories is unsupported. Please drop only filenames!"),
840  wxT("Drag&Drop Error"), wxOK | wxICON_EXCLAMATION);
841  }
842 }
843 
844 void BVWXMainFrame::FitSizetIfTooSmall()
845 {
846 
847  int w=0, h=0;
848  int imgW=0, imgH=0;
849  if (_ImageCanvasUC!=NULL){
850  if (_ImageCanvasUC->GetOrigImage()==NULL)
851  return;
852  imgW = _ImageCanvasUC->GetOrigImage()->GetWidth();
853  imgH = _ImageCanvasUC->GetOrigImage()->GetHeight();
854  } else if (_ImageCanvasFloat!=NULL){
855  imgW = _ImageCanvasFloat->GetOrigimg().GetWidth();
856  imgH = _ImageCanvasFloat->GetOrigimg().GetHeight();
857  } else {
858  // no valid canvas, nothing to do.
859  return;
860  }
861  // get current frame size, TODO: query client area of canvas instead.
862  this->GetClientSize(&w, &h);
863 
864  // query display screen dim
865  int screenW=0, screenH=0;
866  ::wxDisplaySize(&screenW, &screenH);
867  if ( (w<imgW) || (h<imgH)) {
868  // expand limited by screen size
869  // TODO: adpat Client size, to avoid the FitInside...
870  // problem: ImageCanves do not handle sizers correctly...
871  // this is an approximation working for now:
872  this->SetSize(
873  //0,0, /* move win to top-left of screen */
874  //-1, -1, /* keep window pos. */
875  min(imgW+40, screenW), min(imgH+100, screenH) );
876  }
877  this->RefitClients();
878 }
879 
880 
881 void BVWXMainFrame::RefitClients()
882 {
883  int w, h;
884 
885  GetClientSize(&w, &h);
886 
887  if(_ImageCanvasUC != NULL || _ImageCanvasFloat != NULL){
888  _SizerWindow->SetSize(w,h);
889  }
890  if (_ImageCanvasUC!=NULL){
891  _ImageCanvasUC->SetSize(
892  //0,0,
893  //-1, -1,
894  w, h);//< keep window pos., do not move the window!
895  }
896  if (_ImageCanvasFloat!=NULL){
897  _ImageCanvasFloat->SetSize(
898  //0,0,
899  //-1, -1,
900  w, h); //< keep window pos., do not move the window!
901  }
902 }
903 
904 void BVWXMainFrame::OnLoad(wxCommandEvent& WXUNUSED(event))
905 {
906  wxFileDialog fileDialog(
907  this, // parent
908  wxT("Choose file(s) to load"), // message
909  _DefaultDir, // default directory
910  _DefaultFile, // default file
911  wxT("Image files (mip;pgm;ppm;jpg;jpeg;png)|*.mip;*.pgm;*.ppm;*.jpg;*.jpeg;*.png|All files (*.*)|*.*"), // wildcard
912  wxFD_OPEN | wxFD_MULTIPLE); // style
913 
914  if (fileDialog.ShowModal() == wxID_OK)
915  {
916  // get file names
917  wxArrayString paths;
918  fileDialog.GetPaths(paths);
919  // load them
920  LoadImages(paths);
921  } else {
922  SetStatusText(wxT("Loading canceled"),0);
923  }
924 
925  _DefaultDir = fileDialog.GetDirectory();
926 }
927 
928 
929 void BVWXMainFrame::AddInfo(const BIAS::ImageBase & image, std::stringstream &info){
930  info << "Width: " << image.GetWidth() << endl;
931  info << "Height: " << image.GetHeight() << endl;
932  info << "Depth: " << image.GetDepth() << endl;
933  info << "BitDepth: " << image.GetBitDepth() << endl;
934  info << "SizeByte: " << image.GetSizeByte() << " bytes" << endl;
935  info << "Pixel Count: " << image.GetPixelCount() << endl;
936  info << "Channels: " << image.GetChannelCount() << endl;
937  info << "ColorModel: " << image.GetColorModel() << endl;
938  info << "StorageType: " << image.GetStorageType() << endl;
939  info << "IsPlanar: " << image.IsPlanar() << endl;
940  info << "IsInterleaved: " << image.IsInterleaved() << endl;
941  info << "UUID: " << image.GetUID() << endl;
942  info << "Version: " << image.GetVersionNumber() << endl;
943 }
944 
945 void BVWXMainFrame::OnInfo(wxCommandEvent& WXUNUSED(event))
946 {
947  // get currently displayed image
948  ImageBase* image = NULL;
949  if (_ImageCanvasUC != NULL)
950  {
951  image = _ImageCanvasUC->GetOrigImage();
952  }
953  else if (_ImageCanvasFloat != NULL)
954  {
955  image = &_ImageCanvasFloat->GetOrigimg();
956  }
957  if (image == NULL)
958  {
959  wxMessageBox(wxT("No image loaded"), wxT("Image Info"), wxOK | wxICON_ERROR, this);
960  return;
961  }
962 
963  // collect information
964  stringstream info;
965  BIASASSERT(image!=NULL);
966  AddInfo(*image, info);
967 
968  // some info may already be lost through by Uncompress pre-conversion
969  if (infoRaw_.size()>0)
970  info << endl<<endl<<"RAW info before uncompression: "<<endl<<infoRaw_<<endl;
971 
972  // show information in message box
973  wxMessageBox(AsciiToWx(info.str()), wxT("Image Info"), wxOK, this);
974 }
975 
976 void BVWXMainFrame::OnDrawROI(wxCommandEvent& WXUNUSED(event))
977 {
978  if (_ImageCanvasUC != NULL) {
979  _ImageCanvasUC->DrawRoi(_DrawROICheckItem->IsChecked());
980  }
981  else if(_ImageCanvasFloat != NULL){
982  _ImageCanvasFloat->GetImageCanvas()->DrawRoi(_DrawROICheckItem->IsChecked());
983  }
984 }
985 
986 void BVWXMainFrame::OnImageValues(wxCommandEvent& WXUNUSED(event))
987 {
988  float dmin=0.0, dmax=0.0;
989  // get currently displayed image
990  ImageBase* image = NULL;
991  if (_ImageCanvasUC != NULL) {
992  image = _ImageCanvasUC->GetOrigImage();
993  Image<unsigned char> tim(*image);
994  unsigned char min, max;
995  tim.GetMinMaxPixelValue(min, max);
996  dmin = min;
997  dmax = max;
998  } else if (_ImageCanvasFloat != NULL){
999  image = &_ImageCanvasFloat->GetOrigimg();
1000  Image<float> tim(*image);
1001  tim.GetMinMaxPixelValue(dmin, dmax);
1002  }
1003  if (image == NULL){
1004  wxMessageBox(wxT("No image loaded"), wxT("Image Values"),
1005  wxOK | wxICON_ERROR, this);
1006  return;
1007  }
1008 
1009  // collect information
1010  stringstream info;
1011  info << "min pixel value: " << dmin << endl;
1012  info << "max pixel value: " << dmax << endl;
1013 
1014  // show information in message box
1015  wxMessageBox(AsciiToWx(info.str()), wxT("Image Values"), wxOK, this);
1016 }
1017 
1018 void BVWXMainFrame::OnMetaData(wxCommandEvent& WXUNUSED(event))
1019 {
1020  wxFont font(10, wxMODERN, wxNORMAL, wxNORMAL, false, wxT("Courier"));
1021  wxDialog* dlg = new wxDialog(this, -1, wxT("Meta Data"), wxDefaultPosition, wxDefaultSize,
1022  wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
1023  wxTextCtrl* text = new wxTextCtrl(dlg, -1, wxT(""),
1024  wxDefaultPosition, wxSize(650, 400),
1025  wxTE_MULTILINE | wxTE_READONLY | wxTE_DONTWRAP);
1026 #ifdef WIN32
1027  text->SetFont(font);
1028 #endif
1029  text->SetDefaultStyle(wxTextAttr(wxNullColour, wxNullColour, font));
1030  text->AppendText(AsciiToWx(_MetaData));
1031  text->SetInsertionPoint(0);
1032  dlg->Fit();
1033  dlg->ShowModal();
1034  dlg->Destroy();
1035 }
1036 
1037 void BVWXMainFrame::OnExit(wxCommandEvent& WXUNUSED(event))
1038 {
1039  Destroy();
1040 }
1041 
1042 void BVWXMainFrame::OnKeyInfo(wxCommandEvent& WXUNUSED(event))
1043 {
1044  wxString text =
1045  wxT("Next Image\tCtrl+[Right]\n")
1046  wxT("Prev Image\tCtrl+[Left]\n")
1047  wxT("Run-Stop\tCtrl+[Space]");
1048 
1049  wxMessageBox(text, wxT("Keys"),
1050  wxOK | wxICON_INFORMATION, this);
1051 }
1052 
1053 
1054 void BVWXMainFrame::
1055 OnAbout(wxCommandEvent &event)
1056 {
1057 
1058  wxString desc;
1059  desc << wxT("The BiasViewWX Image Viewer, part of the\n");
1060  desc << wxT("BIAS library (Basic ImageAlgorithmS)\n\n");
1061 
1062  stringstream text;
1063  text << "Built on " << __DATE__ << " " << __TIME__ << "\n"
1064  // << "from file " << __FILE__ << "\n"
1065  << "GUI using: " << WxToAscii(wxVERSION_STRING)<< "\n";
1066  text<< "Built with support for:\n";
1067 #ifdef BIAS_HAVE_LIBJPEG
1068  text<< "- jpeg (libJPEG).\n";
1069 #endif
1070 #ifdef BIAS_HAVE_OPENCV
1071  text<< "- OpenCV.\n";
1072 #endif
1073 #ifdef BIAS_HAVE_IMAGEMAGICKLIB
1074  text<< "- ImageMagick.\n";
1075 #endif
1076 #ifdef BIAS_HAVE_OPENEXR
1077  text<< "- OpenEXR.\n";
1078 #endif
1079  desc<<AsciiToWx(text.str());
1080 
1081  wxString lic = wxT("BIAS is free software; you can redistribute it and/or modify\n \
1082  it under the terms of the GNU Lesser General Public Licence as published by\n \
1083  the Free Software Foundation; either version 2.1 of the Licence, or\n \
1084  (at your option) any later version.\n \
1085  \n \
1086  BIAS is distributed in the hope that it will be useful,\n \
1087  but WITHOUT ANY WARRANTY; without even the implied warranty of\n \
1088  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n \
1089  GNU Lesser General Public Licence for more details.\n \
1090  \n \
1091  You should have received a copy of the GNU Lesser General Public Licence\n \
1092  along with BIAS; if not, write to the Free Software\n \
1093  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n");
1094 
1095  wxAboutDialogInfo aboutdlg;
1096  aboutdlg.SetDescription( desc );
1097  aboutdlg.SetLicence( lic );
1098  aboutdlg.SetCopyright( wxT("Copyright (C) 2003-2011\n Multimediale Systeme der Informationsverarbeitung\n Institut fuer Informatik\n Christian-Albrechts-Universitaet Kiel") );
1099  aboutdlg.SetWebSite( wxT("http://www.mip.informatik.uni-kiel.de/") );
1100 
1101  wxAboutBox( aboutdlg );
1102 }
1103 
1104 
1105 void BVWXMainFrame::OnRemoveCurrent(wxCommandEvent& WXUNUSED(event)){
1106  // cout << "Image NR:" << _CurrentImage << " out of "
1107  // << (int)_FileNames.size() << " images is currently removed" << endl;
1108 
1109  if (_CurrentImage < (int)_FileNames.size()){
1110  _FileNames.erase(_FileNames.begin()+_CurrentImage);
1111  }
1112  if(_CurrentImage > (int)_FileNames.size()-1){
1113  _CurrentImage=0;
1114  }
1115 
1116  LoadImageFromList(_CurrentImage);
1117 }
1118 
1119 void BVWXMainFrame::OnRemoveAllButCurrent(wxCommandEvent& WXUNUSED(event)){
1120  // cout << "Image NR:" << _CurrentImage << " out of "
1121  // << (int)_FileNames.size() << " images is currently loaded"
1122  // << " before erasing all but current" << endl;
1123 
1124  if (_FileNames.size()<1){
1125  SetStatusText(_T("No images to remove."),0);
1126  return; // nothing to to
1127  }
1128  BIASASSERT( (int)_FileNames.size() > _CurrentImage);
1129  // make current the first and only image in list
1130  _FileNames[0] = _FileNames[_CurrentImage];
1131  _CurrentImage=0;
1132  _FileNames.resize(1);
1133  // update display
1134  LoadImageFromList(_CurrentImage);
1135  // cout << "Image NR:" << _CurrentImage << " out of "
1136  // << (int)_FileNames.size() << " images is currently loaded"
1137  // << " after erasing all but current" << endl;
1138 }
1139 
1140 
1141 void BVWXMainFrame::PrintSavingError(const int errorNo, wxString fname)
1142 {
1143  std::stringstream msg;
1144  msg << "Error saving "
1145  << WxToAscii(fname)
1146  << " with result = "
1147  << errorNo;
1148  SetStatusText(AsciiToWx(msg.str()),0);
1149  wxMessageBox(AsciiToWx(msg.str()),
1150  wxT("Error saving file"),
1151  wxICON_INFORMATION,
1152  this);
1153  BIASERR(msg.str());
1154 }
1155 
1156 void BVWXMainFrame::PrintConversionError(const int errorNo, wxString fname)
1157 {
1158  std::stringstream msg;
1159  msg << "Error converting "
1160  << WxToAscii(fname)
1161  << " with result = "
1162  << errorNo;
1163  SetStatusText(AsciiToWx(msg.str()),0);
1164  wxMessageBox(AsciiToWx(msg.str()),
1165  wxT("Conversion Error"),
1166  wxICON_INFORMATION,
1167  this);
1168  BIASERR(msg.str());
1169 }
1170 
1171 void BVWXMainFrame::PrintEmptyNameMsg()
1172 {
1173  wxString str(wxT("Please, give this image a name if you want to save it"));
1174  wxMessageBox(str, wxT("No Filename"), wxICON_INFORMATION, this);
1175  SetStatusText(str);
1176 }
1177 
1178 void BVWXMainFrame::PrintNoImageToFilter()
1179 {
1180  wxString msg(wxT("No Image Loaded To Filter"));
1181  SetStatusText(msg);
1182  wxMessageBox(msg,
1183  wxT("No Image"),
1184  wxOK | wxICON_INFORMATION,
1185  this);
1186 }
1187 
1188 int BVWXMainFrame::ConvertFLtoUC(ImageBase& img) {
1189  const ImageBase imageTemp = img;
1190  return ImageConvert::ConvertST(imageTemp,
1191  img,
1192  ImageBase::ST_unsignedchar);
1193 }
1194 
1195 
1196 void BVWXMainFrame::OnSaveAs(wxCommandEvent& event)
1197 {
1198  if (!_FileNames.empty()) { // check if the vector with filenames is empty
1199  FileHandling fh = FileHandling();
1200  std::string absoluteName = _FileNames[_CurrentImage];
1201  std::string tmpFileName = fh.Basename(absoluteName) + ".mip";
1202 
1203  wxString message = _T("Save current image to");
1204  wxString defaultDir = AsciiToWx(fh.Directory(absoluteName));
1205  wxString defaultFileName = AsciiToWx(tmpFileName);
1206  wxString wildcard = wxT("Image files (mip;pgm;ppm;jpg;jpeg;png)|*.mip;*.pgm;*.ppm;*.jpg;*.jpeg;*.png|All files (*.*)|*.*");
1207 
1208  wxFileDialog wd(this,
1209  message,
1210  defaultDir,
1211  defaultFileName,
1212  wildcard,
1213  wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
1214 
1215  if (wxID_OK == wd.ShowModal()) {
1216  wxString fname = wd.GetPath();
1217 
1218  if (!(fh.Basename(WxToAscii(fname))).empty()) { // images should be named
1219  int notOK; // var representing saving to disk success
1220 
1221  if (_ImageCanvasUC) {
1222  if (ImageIO::FF_exr != ImageIO::GetFileFormat(WxToAscii(fname))) {
1223  ImageBase* imUC = _ImageCanvasUC->GetOrigImage();
1224  notOK = ImageIO::Save(WxToAscii(fname), *imUC);
1225  if (notOK!=0) PrintSavingError(notOK, fname);
1226  else SetStatusText(wxT("Saving to disk succeeded"));
1227  } else { // FF is exr
1228  wxString msg = wxT("We don't support conversion from lesser to higher storagetype");
1229  wxMessageBox(msg, wxT("Unsupported Conversion"), wxICON_INFORMATION);
1230  SetStatusText(msg);
1231  BIASERR(WxToAscii(msg));
1232  }
1233  } // end _ImageCanvasUC
1234  else if(_ImageCanvasFloat)
1235  {
1236  ImageBase imFL = _ImageCanvasFloat->GetShownImage();
1237  ImageIO::TFileFormat tf = ImageIO::GetFileFormat(WxToAscii(fname));
1238 
1239  if (ImageIO::FF_exr == tf) { // user want *.exr...just save to disk
1240  notOK = ImageIO::Save(WxToAscii(fname), imFL);
1241  if (notOK!=0) PrintSavingError(notOK, fname);
1242  else SetStatusText(wxT("Saving to disk succeeded"));
1243  }
1244  else if (ImageIO::FF_mip == tf)
1245  { // user want *.mip...ask him whether to convert to uchar
1246  wxMessageDialog dl(this,
1247  wxT("Convert to UNSIGNED CHAR?"),
1248  wxT("Conversion Question"),
1249  wxNO_DEFAULT|wxYES_NO|wxCANCEL);
1250 
1251  switch(dl.ShowModal()) {
1252  case wxID_YES:
1253  notOK = BVWXMainFrame::ConvertFLtoUC(imFL);
1254  if (notOK!=0) PrintConversionError(notOK, fname);
1255  break;
1256  case wxID_NO:
1257  notOK = ImageIO::Save(WxToAscii(fname), imFL);
1258  if (notOK!=0) PrintSavingError(notOK, fname);
1259  else SetStatusText(wxT("Saving to disk succeeded"));
1260  break;
1261  case wxID_CANCEL:
1262  break;
1263  default:
1264  SetStatusText(wxT("Unexpected wxMessageDialog return code"));
1265  }
1266  } // end if mip image
1267  else
1268  { //save normally
1269  Image<unsigned char>* ucImg;
1270  ucImg = _ImageCanvasFloat->GetImageCanvas()->GetImageShown();
1271  notOK = ImageIO::Save(WxToAscii(fname), *ucImg);
1272  if (notOK) PrintSavingError(notOK, fname);
1273  else SetStatusText(wxT("Saving to disk succeeded"));
1274  }
1275  }//end if _ImageCanvasFloat
1276  else{
1277  BIASERR("No image canvas!");
1278  SetStatusText(wxT("No image canvas!"));
1279  }
1280  } else { // empty filename
1281  PrintEmptyNameMsg();
1282  }
1283  } // end wd.ShowModal
1284  } else { // vector is empty
1285  SetStatusText(wxT("Nothing to Save"));
1286  }
1287 }
1288 
1289 void BVWXMainFrame::OnPrintCurrent(wxCommandEvent& event)
1290 {
1291  wxPrintDialogData dlgData;
1292  wxPrintData data;
1293 
1294  dlgData.SetPrintData(data);
1295 
1296  wxPrintDialog pDialog(this,&dlgData);
1297  int ret = pDialog.ShowModal();
1298  if(ret==wxID_OK){
1299 
1300  }
1301  else if(ret==wxID_CANCEL)
1302  return;
1303 }
1304 
1305 
1306 void BVWXMainFrame::OnPrint(wxCommandEvent& event)
1307 {
1308  wxPrintDialogData dlgData;
1309 
1310 
1311  wxPrintDialog pDialog(this,&dlgData);
1312  int ret = pDialog.ShowModal();
1313  if(ret==wxID_OK){
1314 
1315  }
1316  else if(ret==wxID_CANCEL)
1317  return;
1318 }
1319 
1320 void BVWXMainFrame::OnSaveCurrent(wxCommandEvent& event)
1321 {
1322  if (!_FileNames.empty()) { // check if the vector with filenames is empty
1323  FileHandling fh = FileHandling();
1324  std::string absoluteName = _FileNames[_CurrentImage];
1325  std::string tmpFileName = fh.Basename(absoluteName) + ".mip";
1326 
1327  wxString message = _T("Save image as currently displayed with storage type unsigned char to:");
1328  wxString defaultDir = AsciiToWx(fh.Directory(absoluteName));
1329  wxString defaultFileName = AsciiToWx(tmpFileName);
1330  wxString wildcard = wxT("Image files (mip;pgm;ppm;jpg;jpeg;png)|*.mip;*.pgm;*.ppm;*.jpg;*.jpeg;*.png|All files (*.*)|*.*");
1331 
1332  wxFileDialog wd(this,
1333  message,
1334  defaultDir,
1335  defaultFileName,
1336  wildcard,
1337  wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
1338 
1339  if (wxID_OK == wd.ShowModal()) {
1340  wxString fname = wd.GetPath();
1341 
1342  if (!(fh.Basename(WxToAscii(fname))).empty()) { // images should be named
1343 
1344  int notOK;
1345  ImageBase* img = NULL;
1346 
1347  if (_ImageCanvasUC) {
1348  img = _ImageCanvasUC->GetOrigImage();
1349  notOK = ImageIO::Save(WxToAscii(fname), *img);
1350  } else {
1351  img = &_ImageCanvasFloat->GetShownImage();
1352 
1353  //if we have a storagetype float get current image as displayed and save it
1354  if(img->GetStorageType()==ImageBase::ST_float)
1355  {
1357  ImageConvert::ConvertST(*img,tmpUC,ImageBase::ST_unsignedchar);
1358  notOK = ImageIO::Save(WxToAscii(fname), tmpUC);
1359  }
1360  else
1361  notOK = ImageIO::Save(WxToAscii(fname), *img);
1362  }
1363 
1364  if (notOK) { // let us see if saving was successfull
1365  PrintSavingError(notOK, fname);
1366  } else {
1367  SetStatusText(wxT("Saving to disk succeeded"));
1368  }
1369 
1370  } else { // empty filename
1371  PrintEmptyNameMsg();
1372  }
1373  } // end wd.ShowModal
1374 
1375  } else { // vector is empty
1376  SetStatusText(wxT("Nothing to Save"));
1377  }
1378 }
1379 
1380 
1381 void BVWXMainFrame::OnSaveAsMovie(wxCommandEvent& WXUNUSED(event)){
1382 #ifdef BIAS_HAVE_FFMPEG
1383  FileHandling fh = FileHandling();
1384  std::string absoluteName = _FileNames[_CurrentImage];
1385  std::string tmpFileName = fh.Basename(absoluteName) + ".mpeg";
1386 
1387  wxString message = _T("Save movie of images to:");
1388  wxString defaultDir = AsciiToWx(fh.Directory(absoluteName));
1389  wxString defaultFileName = AsciiToWx(tmpFileName);
1390  wxString wildcard = wxT("Movie files (avi;mpeg;divx;xvid)|*.avi;*.mpeg;*.divx;*.xvid;|All files (*.*)|*.*");
1391 /*
1392  wxFileDialog wd(this,
1393  message,
1394  defaultDir,
1395  defaultFileName,
1396  wildcard,
1397  wxSAVE|wxOVERWRITE_PROMPT);
1398 
1399  if (wxID_OK == wd.ShowModal()) {
1400  wxString fname = wd.GetPath();
1401  cout<<"Saving movie to:"<<WxToAscii(fname)<<endl;
1402  }*/
1403 
1404  VideoSink_FFmpeg vs;
1405 
1406  ImageBase tmp;
1407  ImageIO::Load(_FileNames[_CurrentImage],tmp);
1408 
1409  wxVideoSettingsDialog dialog(this);
1410  dialog.SetGoPSize(12);
1411  dialog.SetBitrate(500000);//bitrate in Bit/seconds
1412  dialog.SetWidth(tmp.GetWidth());
1413  dialog.SetHeight(tmp.GetHeight());
1414  dialog.SetFPS(25);
1415  dialog.SetMaxBFrames(0);
1416  dialog.SetOutputFilename(wxT("movie.mpeg"));
1417 
1418  int ret = dialog.ShowModal();
1419  if(ret == wxID_OK){
1420  wxString fname = dialog.GetOutputFilename();
1421  vs.SetSize(dialog.GetWidth(),dialog.GetHeight());
1422  vs.SetBitrate(dialog.GetBitrate());
1423  vs.SetFPS(dialog.GetFPS());
1424  vs.SetGopSize(dialog.GetGoPSize());
1425  vs.SetMaxBFrames(dialog.GetMaxBFrames());
1426  vs.SetEncoder(CodecID(dialog.GetCodecID()));
1427 
1428  int ret = vs.Open(WxToAscii(fname));
1429  if( ret < 0) {
1430  stringstream st;
1431  st<<"Opening video ouput file failed: "<<vs.GetError();
1432  wxString msg = AsciiToWx(st.str().c_str());
1433  wxMessageBox(msg, wxT("Encoding failed."),
1434  wxOK | wxICON_ERROR, this);
1435  return;
1436  }
1437 
1438  wxProgressDialog progressDlg(wxT("Encoding..."),
1439  wxT("Encoding movie, please wait."),
1440  100,this,
1441  wxPD_ELAPSED_TIME|wxPD_REMAINING_TIME|wxPD_AUTO_HIDE|wxPD_SMOOTH);
1442 
1443  //check direction
1444  bool reverse = _ReverseCheckBox->GetValue();
1445 
1446  for(unsigned i=0;i<_FileNames.size();i++){
1447  int index = i;
1448  if(reverse) index = _FileNames.size()-1-index;
1449  ret= vs.AddFrame(_FileNames[index]);
1450  if(ret <0) break;
1451  progressDlg.Update(((float)i/(float)_FileNames.size()) * 100.0);
1452  }
1453 
1454  if( ret < 0) {
1455  stringstream st;
1456  st<<"Encoding failed: "<<vs.GetError();
1457  wxString msg = AsciiToWx(st.str().c_str());
1458  wxMessageBox(msg,
1459  wxT("Encoding failed."),
1460  wxOK | wxICON_ERROR, this);
1461  return;
1462  }
1463  else
1464  progressDlg.Update(100);
1465 
1466  SetStatusText(wxT("Saving movie succeeded."));
1467  stringstream st;
1468  st<<"Movie successfully saved to: "<<WxToAscii(fname);
1469  wxString msg = AsciiToWx(st.str().c_str());
1470  wxMessageBox(msg,
1471  wxT("Encoding successful."),
1472  wxOK | wxICON_INFORMATION, this);
1473  }
1474 #else
1475  wxString msg = wxT("No FFMPEG support found in BIAS. Activate it to save images encoded as videosS");
1476  wxMessageBox(msg,
1477  wxT("No FFMPEG support found in BIAS."),
1478  wxOK | wxICON_ERROR, this);
1479 #endif
1480 }
1481 
1482 
1483 void BVWXMainFrame::OnSaveList(wxCommandEvent& WXUNUSED(event))
1484 {
1485  wxString filename = wxFileSelector(_T("Choose file to save the image list to.")
1486  ,_T("") // default path
1487  ,_T("out_images.lst") //def. filename
1488  ,_T(".lst") // def. extension
1489  ,_T("LST files (*.lst)|*.lst|TXT files (*.txt)|*.txt|All files (*.*)|*.*") // wildcard
1490  ,wxFD_SAVE|wxFD_OVERWRITE_PROMPT // flags
1491  );
1492  if ( !filename.empty() ){
1493  ofstream f( WxToAscii(filename) ); // ios::out overwrite, not append
1494  if (!f.good()){
1495  stringstream msg;
1496  msg<<"Could not open "<<filename.c_str()<<" for writing";
1497  SetStatusText( AsciiToWx( msg.str() ));
1498  BIASERR(msg.str());
1499  return;
1500  }
1501  vector<string>::const_iterator it = _FileNames.begin();
1502  int n=0;
1503  for ( ;it<_FileNames.end(); it++){
1504  f<<*it<<endl;
1505  n++;
1506  }
1507  f.close();
1508  stringstream msg; msg<<"Wrote "<<filename.c_str()<<" with "<<n<<" filenames";
1509  SetStatusText( AsciiToWx(msg.str() ));
1510  }
1511 }
1512 
1513 void BVWXMainFrame::OnToolEnter ( wxCommandEvent &){
1514  //cout<<"Entering tool with id:"<<event.GetSelection()<<endl;
1515  //event.skip();
1516 }
1517 
1518 void BVWXMainFrame::OnNext(wxCommandEvent& WXUNUSED(event))
1519 {
1520  _CurrentImage++;
1521  if (_CurrentImage >= (int)_FileNames.size())
1522  {
1523  _CurrentImage = 0;
1524  }
1525  LoadImageFromList(_CurrentImage);
1526 }
1527 
1528 void BVWXMainFrame::OnPrev(wxCommandEvent& WXUNUSED(event))
1529 {
1530  _CurrentImage--;
1531  if (_CurrentImage < 0)
1532  {
1533  _CurrentImage = _FileNames.size() - 1;
1534  }
1535  LoadImageFromList(_CurrentImage);
1536 }
1537 
1538 void BVWXMainFrame::OnRunStop(wxCommandEvent& WXUNUSED(event))
1539 {
1540  if (_Timer.IsRunning())
1541  {
1542  _Timer.Stop();
1543  wxToolBar* tb = GetToolBar();
1544  tb->SetToolNormalBitmap(ID_RunStop,wxIcon(play_xpm));
1545  }
1546  else
1547  {
1548  _Timer.Start(_DelaySpin->GetValue());
1549  wxToolBar* tb = GetToolBar();
1550  tb->SetToolNormalBitmap(ID_RunStop,wxIcon(stopplaying_xpm));
1551  }
1552 }
1553 
1554 void BVWXMainFrame::OnRun(wxCommandEvent& WXUNUSED(event))
1555 {
1556  if (!_Timer.IsRunning())
1557  {
1558  _Timer.Start(_DelaySpin->GetValue());
1559  }
1560 }
1561 
1562 void BVWXMainFrame::OnStop(wxCommandEvent& WXUNUSED(event))
1563 {
1564  if (_Timer.IsRunning())
1565  {
1566  _Timer.Stop();
1567  }
1568 }
1569 
1570 void BVWXMainFrame::OnHistogramm(wxCommandEvent& WXUNUSED(event))
1571 {
1572  if (_FileNames.size() > 0){
1573  const string& fileName = _FileNames[_CurrentImage];
1574 
1575  // load image
1576  ImageBase image;
1577  if (ImageIO::Load(fileName.c_str(), image)!=0){
1578  stringstream msg;
1579  msg << "Error loading " << fileName;
1580  BIASERR(msg.str());
1581  SetStatusText(AsciiToWx(msg.str()));
1582  }
1583 
1584  if(!_ShowHistogramm)
1585  _ShowHistogramm = true;
1586 
1587  ShowHistogramm(image);
1588  }
1589  else
1590  SetStatusText(AsciiToWx("No Images Loaded (No Image = No Histogramm)"));
1591 }
1592 
1593 void BVWXMainFrame::ShowHistogramm(ImageBase& image){
1594  if (_FileNames.size() > 0){
1595  //Check if float or UC
1596  switch (image.GetStorageType()){
1597  case ImageBase::ST_unsignedchar:
1598  if(_ImageCanvasUC != NULL){
1599  _ImageCanvasUC->ShowHistogramm(image, _HistoPosition, _HistoSize);
1600  }
1601  break;
1602  case ImageBase::ST_float:
1603  if(_ImageCanvasFloat != NULL &&
1604  _ImageCanvasFloat->GetImageCanvas() != NULL){
1605  _ImageCanvasFloat->GetImageCanvas()->ShowHistogramm(image,
1606  _HistoPosition,
1607  _HistoSize);
1608  }
1609  break;
1610  default:
1611  break;
1612  }
1613  this->SetFocus();
1614  }
1615  else
1616  cout << "No Images Loaded (No Image = No Histogramm)" << endl;
1617 }
1618 
1619 
1620 void BVWXMainFrame::OnImageValueBar(wxCommandEvent& WXUNUSED(event))
1621 {
1622  _ShowImageValueBar = !_ShowImageValueBar;
1623 
1624  if (_ShowImageValueBar && _FileNames.size() > 0){
1625  const string& fileName = _FileNames[_CurrentImage];
1626 
1627  // load image
1628  ImageBase image;
1629  if (ImageIO::Load(fileName.c_str(), image)!=0){
1630  stringstream msg;
1631  msg << "Error loading " << fileName;
1632  BIASERR(msg.str());
1633  SetStatusText(AsciiToWx(msg.str()));
1634  }
1635  UncompressImage(image);
1636  ShowImageValueBar(image);
1637  }
1638  else{
1639  if(_ImageCanvasUC != NULL && _ImageCanvasUC != NULL)
1640  _ImageCanvasUC->HideImageValueBar();
1641  if(_ImageCanvasFloat != NULL && _ImageCanvasFloat->GetImageCanvas() != NULL)
1642  _ImageCanvasFloat->GetImageCanvas()->HideImageValueBar();
1643  }
1644 }
1645 
1646 void BVWXMainFrame::ShowImageValueBar(ImageBase& image){
1647  if (_FileNames.size() > 0){
1648  //Check if float or UC
1649  switch (image.GetStorageType()){
1650  case ImageBase::ST_unsignedchar:
1651  if(_ImageCanvasUC != NULL){
1652  _ImageCanvasUC->ShowImageValueBar(image, _ValueBarPosition, _ValueBarSize);
1653  }
1654  break;
1655  case ImageBase::ST_float:
1656  if(_ImageCanvasFloat != NULL &&
1657  _ImageCanvasFloat->GetImageCanvas() != NULL){
1658  _ImageCanvasFloat->GetImageCanvas()->ShowImageValueBar(image,
1659  _ValueBarPosition,
1660  _ValueBarSize);
1661  }
1662  break;
1663  default:
1664  break;
1665  }
1666  this->SetFocus();
1667  }
1668  else
1669  cout << "No Images Loaded (No Image = No Histogramm)" << endl;
1670 }
1671 
1672 void BVWXMainFrame::OnDelay(wxSpinEvent& WXUNUSED(event))
1673 {
1674  if (_Timer.IsRunning())
1675  {
1676  _Timer.Start(_DelaySpin->GetValue());
1677  }
1678 }
1679 
1680 void BVWXMainFrame::OnFit(wxCommandEvent& WXUNUSED(event))
1681 {
1682  LoadImageFromList(_CurrentImage);
1683 }
1684 
1685 void BVWXMainFrame::OnKeepScrollPosition(wxCommandEvent& WXUNUSED(event))
1686 {
1687  if (_KeepScrollPositionCheckBox != NULL)
1688  {
1689  if (_KeepScrollPositionCheckBox->IsChecked())
1690  {
1691  if (_ImageCanvasUC!=NULL){
1692  _ImageCanvasUC->KeepScrollPosition(true);
1693  }
1694  if (_ImageCanvasFloat!=NULL){
1695  _ImageCanvasFloat->KeepScrollPosition(true);
1696  }
1697  }else{
1698  if (_ImageCanvasUC!=NULL){
1699  _ImageCanvasUC->KeepScrollPosition(false);
1700  }
1701  if (_ImageCanvasFloat!=NULL){
1702  _ImageCanvasFloat->KeepScrollPosition(false);
1703  }
1704  }
1705  }
1706 }
1707 
1708 void BVWXMainFrame::OnTimer(wxTimerEvent& WXUNUSED(event))
1709 {
1710  if (!_BlockAnimation)
1711  {
1712  // block animation until at least one idle event occurs,
1713  // so the viewer doesn't get stuck if delay is too low.
1714  _BlockAnimation = true;
1715  wxCommandEvent dummyEvent;
1716 
1717  if (_ReverseCheckBox->GetValue())
1718  OnPrev(dummyEvent);
1719  else
1720  OnNext(dummyEvent);
1721  }
1722 }
1723 
1724 void BVWXMainFrame::OnIdle(wxIdleEvent& WXUNUSED(event))
1725 {
1726  _BlockAnimation = false;
1727 }
1728 
1729 void BVWXMainFrame::OnSize(wxSizeEvent& event)
1730 {
1731  if (_FitCheckBox != NULL)
1732  {
1733  if (_FitCheckBox->IsChecked())
1734  {
1735  LoadImageFromList(_CurrentImage);
1736  }
1737  }
1738  this->RefitClients();
1739  event.Skip();
1740 }
1741 
1742 
1743 void BVWXMainFrame::OnChangeChannel_1(wxCommandEvent& event)
1744 {
1745  _SelectedChannel = 1;
1746  stringstream msg;
1747  msg <<_SelectedChannel<<". channel (red?) selected.";
1748  SetStatusText(AsciiToWx(msg.str()));
1749  LoadImageFromList(_CurrentImage);
1750 }
1751 
1752 void BVWXMainFrame::OnChangeChannel_2(wxCommandEvent& event)
1753 {
1754  _SelectedChannel = 2;
1755  stringstream msg;
1756  msg <<_SelectedChannel<<". channel (green?) selected.";
1757  SetStatusText(AsciiToWx(msg.str()));
1758  LoadImageFromList(_CurrentImage);
1759 }
1760 
1761 void BVWXMainFrame::OnChangeChannel_3(wxCommandEvent& event)
1762 {
1763  _SelectedChannel = 3;
1764  stringstream msg;
1765  msg <<_SelectedChannel<<". channel (blue?) selected.";
1766  SetStatusText(AsciiToWx(msg.str()));
1767  LoadImageFromList(_CurrentImage);
1768 }
1769 
1770 
1771 void BVWXMainFrame::OnChangeChannel_4(wxCommandEvent& event)
1772 {
1773  _SelectedChannel = 4;
1774  stringstream msg;
1775  msg <<_SelectedChannel<<". channel selected.";
1776  SetStatusText(AsciiToWx(msg.str()));
1777  LoadImageFromList(_CurrentImage);
1778 }
1779 
1780 void BVWXMainFrame::OnChangeChannel_5(wxCommandEvent& event)
1781 {
1782  _SelectedChannel = 5;
1783  stringstream msg;
1784  msg <<_SelectedChannel<<". channel selected.";
1785  SetStatusText(AsciiToWx(msg.str()));
1786  LoadImageFromList(_CurrentImage);
1787 }
1788 
1789 void BVWXMainFrame::OnChangeChannel_6(wxCommandEvent& event)
1790 {
1791  _SelectedChannel = 6;
1792  stringstream msg;
1793  msg <<_SelectedChannel<<". channel selected.";
1794  SetStatusText(AsciiToWx(msg.str()));
1795  LoadImageFromList(_CurrentImage);
1796 }
1797 
1798 void BVWXMainFrame::OnChangeChannel_7(wxCommandEvent& event)
1799 {
1800  _SelectedChannel = 7;
1801  stringstream msg;
1802  msg <<_SelectedChannel<<". channel selected.";
1803  SetStatusText(AsciiToWx(msg.str()));
1804  LoadImageFromList(_CurrentImage);
1805 }
1806 
1807 void BVWXMainFrame::OnChangeChannel_8(wxCommandEvent& event)
1808 {
1809  _SelectedChannel = 8;
1810  cout<<_SelectedChannel<<". channel selected."<<endl;
1811  LoadImageFromList(_CurrentImage);
1812 }
1813 
1814 
1815 void BVWXMainFrame::OnChangeChannel_ALL(wxCommandEvent& event)
1816 {
1817  stringstream msg;
1818  msg <<"All channel selected.";
1819  SetStatusText(AsciiToWx(msg.str()));
1820  _SelectedChannel = 0;
1821  LoadImageFromList(_CurrentImage);
1822 }
1823 
1824 void BVWXMainFrame::OnFilterCannyEdge(wxCommandEvent& WXUNUSED(event))
1825 {
1826  if ((NULL == _ImageCanvasUC) && (NULL == _ImageCanvasFloat)) {
1827 
1828  PrintNoImageToFilter();
1829 
1830  } else if (_ImageCanvasUC) {
1831 
1832  Image<UCHAR> imgToFilter = (Image<UCHAR>) *_ImageCanvasUC->GetOrigImage();
1834  = new FilterDialogCannyEdge<UCHAR, float>(imgToFilter, this, ID_FilterWindow);
1835  cannyEdge->Show(true);
1836 
1837  } else {
1838 
1839  Image<float> imgToFilter = (Image<float>) _ImageCanvasFloat->GetShownImage();
1841  = new FilterDialogCannyEdge<float, float>(imgToFilter, this, ID_FilterWindow);
1842  cannyEdge->Show(true);
1843 
1844  }
1845 }
1846 
1847 void BVWXMainFrame::OnFilterGauss(wxCommandEvent& WXUNUSED(event))
1848 {
1849  if ((NULL == _ImageCanvasUC) && (NULL == _ImageCanvasFloat)) {
1850 
1851  PrintNoImageToFilter();
1852 
1853  } else if (_ImageCanvasUC) {
1854 
1855  Image<UCHAR> imgToFilter = (Image<UCHAR>) *_ImageCanvasUC->GetOrigImage();
1856 
1857  // ask user about outputst! uchar or float
1858  if (wxYES == wxMessageBox(wxT("Float Storagetype as output?"),
1859  wxT("Storagetype Question"),
1860  wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION,
1861  this))
1862  {
1864  = new FilterDialogGauss<UCHAR, float>(imgToFilter, this, ID_FilterWindow);
1865  gauss->Show(true);
1866  } else {
1868  = new FilterDialogGauss<UCHAR, UCHAR>(imgToFilter, this, ID_FilterWindow);
1869  gauss->Show(true);
1870  }
1871 
1872  } else {
1873 
1874  Image<float> imgToFilter = (Image<float>) _ImageCanvasFloat->GetShownImage();
1876  = new FilterDialogGauss<float, float>(imgToFilter, this, ID_FilterWindow);
1877  gauss->Show(true);
1878 
1879  }
1880 }
1881 
1882 void BVWXMainFrame::OnFilterGradientSobel3x3(wxCommandEvent& WXUNUSED(event))
1883 {
1884  if ((NULL == _ImageCanvasUC) && (NULL == _ImageCanvasFloat)) {
1885 
1886  PrintNoImageToFilter();
1887 
1888  } else if (_ImageCanvasUC) {
1889 
1890  Image<UCHAR> imgToFilter = (Image<UCHAR>) *_ImageCanvasUC->GetOrigImage();
1892  = new FilterDialogGradientSobel3x3<UCHAR, float>(imgToFilter, this, ID_FilterWindow);
1893  sobel3x3->Show(true);
1894 
1895  } else {
1896 
1897  Image<float> imgToFilter = (Image<float>) _ImageCanvasFloat->GetShownImage();
1899  = new FilterDialogGradientSobel3x3<float, float>(imgToFilter, this, ID_FilterWindow);
1900  sobel3x3->Show(true);
1901 
1902  }
1903 
1904 }
1905 
1906 void BVWXMainFrame::OnFilterMean(wxCommandEvent& WXUNUSED(event))
1907 {
1908  if ((NULL == _ImageCanvasUC) && (NULL == _ImageCanvasFloat)) {
1909 
1910  PrintNoImageToFilter();
1911 
1912  } else if (_ImageCanvasUC) {
1913 
1914  Image<UCHAR> imgToFilter = (Image<UCHAR>) *_ImageCanvasUC->GetOrigImage();
1915 
1916  // ask user about outputst! uchar or float
1917  if (wxYES == wxMessageBox(wxT("Float Storagetype as output?"),
1918  wxT("Storagetype Question"),
1919  wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION,
1920  this))
1921  {
1923  = new FilterDialogMean<UCHAR, float>(imgToFilter, this, ID_FilterWindow);
1924  mean->Show(true);
1925  } else {
1927  = new FilterDialogMean<UCHAR, UCHAR>(imgToFilter, this, ID_FilterWindow);
1928  mean->Show(true);
1929  }
1930 
1931 
1932  } else {
1933 
1934  Image<float> imgToFilter = (Image<float>) _ImageCanvasFloat->GetShownImage();
1936  = new FilterDialogMean<float, float>(imgToFilter, this, ID_FilterWindow);
1937  mean->Show(true);
1938 
1939  }
1940 
1941 }
1942 
1943 void BVWXMainFrame::OnFilterMedian(wxCommandEvent& WXUNUSED(event))
1944 {
1945  if ((NULL == _ImageCanvasUC) && (NULL == _ImageCanvasFloat)) {
1946 
1947  PrintNoImageToFilter();
1948 
1949  } else if (_ImageCanvasUC) {
1950 
1951  Image<UCHAR> imgToFilter = (Image<UCHAR>) *_ImageCanvasUC->GetOrigImage();
1952 
1953  // ask user about outputst! uchar or float
1954  if (wxYES == wxMessageBox(wxT("Float Storagetype as output?"),
1955  wxT("Storagetype Question"),
1956  wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION,
1957  this))
1958  {
1960  = new FilterDialogMedian<UCHAR, float>(imgToFilter, this, ID_FilterWindow);
1961  median->Show(true);
1962  } else {
1964  = new FilterDialogMedian<UCHAR, UCHAR>(imgToFilter, this, ID_FilterWindow);
1965  median->Show(true);
1966  }
1967 
1968 
1969  } else {
1970 
1971  Image<float> imgToFilter = (Image<float>) _ImageCanvasFloat->GetShownImage();
1973  = new FilterDialogMedian<float, float>(imgToFilter, this, ID_FilterWindow);
1974  median->Show(true);
1975 
1976  }
1977 
1978 }
1979 
1980 void BVWXMainFrame::OnFilterRescale(wxCommandEvent& WXUNUSED(event))
1981 {
1982  if ((NULL == _ImageCanvasUC) && (NULL == _ImageCanvasFloat)) {
1983 
1984  PrintNoImageToFilter();
1985 
1986  } else if (_ImageCanvasUC) {
1987 
1988  Image<UCHAR> imgToFilter = (Image<UCHAR>) *_ImageCanvasUC->GetOrigImage();
1989 
1990  // ask user about outputst! uchar or float
1991  if (wxYES == wxMessageBox(wxT("Float Storagetype as output?"),
1992  wxT("Storagetype Question"),
1993  wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION,
1994  this))
1995  {
1997  = new FilterDialogRescale<UCHAR, float>(imgToFilter, this, ID_FilterWindow);
1998  sobel3x3->Show(true);
1999  } else {
2001  = new FilterDialogRescale<UCHAR, UCHAR>(imgToFilter, this, ID_FilterWindow);
2002  sobel3x3->Show(true);
2003  }
2004 
2005  } else {
2006 
2007  Image<float> imgToFilter = (Image<float>) _ImageCanvasFloat->GetShownImage();
2009  = new FilterDialogRescale<float, float>(imgToFilter, this, ID_FilterWindow);
2010  sobel3x3->Show(true);
2011 
2012  }
2013 }
2014 
2015 
2016 
2017 
2018 
2019 void BVWXMainFrame::OnFilterSave( wxCommandEvent &event ) {
2020  wxArrayString str = wxArrayString();
2021  str.Add(event.GetString());
2022 
2023  LoadImages(str);
2024 }
void SetOutputFilename(wxString value)
void SetEncoder(enum CodecID codecId)
Set encoder.
void SetSize(int width, int height)
Set frame size of video.
unsigned int GetDepth() const
returns the bytes per channel, which is the sizeof(StorageType) Should match GetSizeDepth(GetStorageT...
Definition: ImageBase.hh:328
Implementation of a GradientSobel3x3 filter dialog.
wxString AsciiToWx(const char *thestring)
Converts a C string to a wxString.
Definition: StringConv.hh:32
Video encoding using FFmpeg library.
void SetFPS(float fps)
Set framerate in frames per second.
bool IsInterleaved() const
Definition: ImageBase.hh:491
void SetMaxBFrames(int maxBFrames)
Set maximal number of bidirectional frames.
int AddFrame(const ImageBase &image)
Add an Image to the stream and write it to the video output file.
void SetColorModel(EColorModel Model)
Definition: ImageBase.hh:561
unsigned int GetSizeByte() const
returns the nr.
Definition: ImageBase.hh:352
int GetCodecID()
Returns the codec ID as in libavcodec/avcodec.h.
display image in wx application, provides zoom and investigation functionality
Definition: ImageCanvas.hh:38
Implementation of a Gauss filter dialog.
bool IsPlanar() const
Definition: ImageBase.hh:484
void GetMinMaxPixelValue(StorageType &min, StorageType &max, unsigned short int channel=0, unsigned int *mincoo=NULL, unsigned int *maxcoo=NULL) const
returns the minimal and maximal pixel value in channel only Finds minimum and maximum pixel value in ...
Definition: Image.cpp:802
unsigned int GetWidth() const
Definition: ImageBase.hh:312
void SetGopSize(int gopSize)
Set the gop size of the video stream.
unsigned int GetBitDepth() const
returns the bits per channel Is not necessairily 8*sizeof(StorageType), could be fewer bits...
Definition: ImageBase.hh:344
Implementing wxVideoSettingsDialogBase.
PGR XB3 in format 7 mode 3 delivers an image that consists of 3 channels with 8bbp (overal 24bpp)...
Definition: ImageBase.hh:152
const BIAS::UUID & GetUID() const
returns the UUID of the image
Definition: ImageBase.hh:449
static std::string Basename(const std::string &fullname)
Get file base name without path from given path and filename.
Implementation of a Mean filter dialog.
int StealImage(ImageBase &source)
steals the image data array from source, after releasing the actual image data and sets source image ...
Definition: ImageBase.cpp:395
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
TFileFormat
format specifier when writing an image to a file Do NOT change order or associated enum value because...
Definition: ImageIO.hh:76
unsigned int GetHeight() const
Definition: ImageBase.hh:319
static int ParseListFile(const std::string &ListFileName, std::vector< std::string > &LinesInFile)
Extracts lines from passed file.
Definition: Param.cpp:1853
static std::string Directory(const std::string &fullname)
Get directory from given path and filename.
Implementation of a CannyEdge filter dialog.
void SetBitrate(int bitrate)
Set bitrate in bits per second.
void SetUID(const BIAS::UUID &id)
Definition: ImageBase.hh:589
int Open(std::string filename)
Open a file for video output and init the codec.
enum EColorModel GetColorModel() const
Definition: ImageBase.hh:407
int GetVersionNumber() const
Definition: ImageBase.hh:477
void PrintAppData(std::ostream &os)
see whats in the camera, for debug
Definition: Camera.cpp:87
Functions to create, check and delete files and to handle file names, such as splitting into director...
Definition: FileHandling.hh:47
enum EStorageType GetStorageType() const
Definition: ImageBase.hh:414
display float images in wx application, provides zoom, scale, shift and investigation functionality ...
std::string GetError()
Get the last error message.
unsigned long int GetPixelCount() const
returns number of pixels in image
Definition: ImageBase.hh:422
This is the base class for images in BIAS.
Definition: ImageBase.hh:102
Implementation of a Median filter dialog.
int ParseMetaData(bool bUse2x64bitTS=true)
After ImageIO::Load() operated on AppData_, this method fills P_, Timestamp, DC_*, ...
Definition: Camera.cpp:154
Implementation of a Rescale filter dialog.