Commit 7137baa63a517a83e188f29eae9fa58f6b9f1ea7

Authored by tatiana
1 parent dc0b4234

ADD: Photo feature (fix #59)

invesalius/constants.py
... ... @@ -55,9 +55,10 @@ TEXT_POS_VCENTRE_LEFT = (X, 0.5) # SetVerticalJustificationToCentered
55 55  
56 56  
57 57 # Slice orientation
58   -AXIAL = 0
59   -CORONAL = 1
60   -SAGITAL = 2
  58 +AXIAL = 1
  59 +CORONAL = 2
  60 +SAGITAL = 3
  61 +VOLUME = 4
61 62  
62 63 # Colour representing each orientation
63 64 ORIENTATION_COLOUR = {'AXIAL': (1,0,0), # Red
... ... @@ -355,7 +356,7 @@ FILETYPE_JPG = wx.NewId()
355 356 FILETYPE_PNG = wx.NewId()
356 357 FILETYPE_PS = wx.NewId()
357 358 FILETYPE_POV = wx.NewId()
358   -FILETYPE_OBJ = wx.NewId()
  359 +FILETYPE_TIF = wx.NewId()
359 360  
360 361 IMAGE_TILING = {"1 x 1":(1,1), "1 x 2":(1,2),
361 362 "1 x 3":(1,3), "1 x 4":(1,4),
... ...
invesalius/data/viewer_slice.py
... ... @@ -829,6 +829,63 @@ class Viewer(wx.Panel):
829 829 'Show text actors on viewers')
830 830 ps.Publisher().subscribe(self.OnHideText,
831 831 'Hide text actors on viewers')
  832 + ps.Publisher().subscribe(self.OnExportPicture,'Export picture to file')
  833 +
  834 +
  835 +
  836 + def OnExportPicture(self, pubsub_evt):
  837 + ps.Publisher().sendMessage('Begin busy cursor')
  838 +
  839 + id, filename, filetype = pubsub_evt.data
  840 + dict = {"AXIAL": const.AXIAL,
  841 + "CORONAL": const.CORONAL,
  842 + "SAGITAL": const.SAGITAL}
  843 +
  844 + if id == dict[self.orientation]:
  845 + print "ok"
  846 + if filetype == const.FILETYPE_POV:
  847 + print 1
  848 + renwin = self.interactor.GetRenderWindow()
  849 + image = vtk.vtkWindowToImageFilter()
  850 + image.SetInput(renwin)
  851 + writer = vtk.vtkPOVExporter()
  852 + writer.SetFilePrefix(filename.split(".")[0])
  853 + writer.SetRenderWindow(renwin)
  854 + writer.Write()
  855 + return
  856 + else:
  857 + print 2
  858 + #Use tiling to generate a large rendering.
  859 + image = vtk.vtkRenderLargeImage()
  860 + image.SetInput(self.ren)
  861 + image.SetMagnification(2)
  862 +
  863 + image = image.GetOutput()
  864 +
  865 +
  866 + # write image file
  867 + if (filetype == const.FILETYPE_BMP):
  868 + print 3
  869 + writer = vtk.vtkBMPWriter()
  870 + elif (filetype == const.FILETYPE_JPG):
  871 + print 4
  872 + writer = vtk.vtkJPEGWriter()
  873 + elif (filetype == const.FILETYPE_PNG):
  874 + print 5
  875 + writer = vtk.vtkPNGWriter()
  876 + elif (filetype == const.FILETYPE_PS):
  877 + print 6
  878 + writer = vtk.vtkPostScriptWriter()
  879 + elif (filetype == const.FILETYPE_TIF):
  880 + print 7
  881 + writer = vtk.vtkTIFFWriter()
  882 + filename = "%s.tif"%filename.strip(".tif")
  883 +
  884 + writer.SetInput(image)
  885 + writer.SetFileName(filename)
  886 + writer.Write()
  887 +
  888 + ps.Publisher().sendMessage('End busy cursor')
832 889  
833 890 def OnShowText(self, pubsub_evt):
834 891 print "OnShowText"
... ...
invesalius/data/viewer_volume.py
... ... @@ -127,8 +127,53 @@ class Viewer(wx.Panel):
127 127 ps.Publisher().subscribe(self.OnShowText,
128 128 'Show text actors on viewers')
129 129 ps.Publisher().subscribe(self.OnCloseProject, 'Close project data')
  130 + ps.Publisher().subscribe(self.OnExportPicture,'Export picture to file')
130 131  
131   -
  132 +
  133 +
  134 + def OnExportPicture(self, pubsub_evt):
  135 + ps.Publisher().sendMessage('Begin busy cursor')
  136 + id, filename, filetype = pubsub_evt.data
  137 +
  138 + if id == const.VOLUME:
  139 + if filetype == const.FILETYPE_POV:
  140 + renwin = self.interactor.GetRenderWindow()
  141 + image = vtk.vtkWindowToImageFilter()
  142 + image.SetInput(renwin)
  143 + writer = vtk.vtkPOVExporter()
  144 + writer.SetFilePrefix(filename.split(".")[0])
  145 + writer.SetRenderWindow(renwin)
  146 + writer.Write()
  147 + return
  148 + else:
  149 + #Use tiling to generate a large rendering.
  150 + image = vtk.vtkRenderLargeImage()
  151 + image.SetInput(self.ren)
  152 + image.SetMagnification(2)
  153 +
  154 + image = image.GetOutput()
  155 +
  156 +
  157 + # write image file
  158 + if (filetype == const.FILETYPE_BMP):
  159 + writer = vtk.vtkBMPWriter()
  160 + elif (filetype == const.FILETYPE_JPG):
  161 + writer = vtk.vtkJPEGWriter()
  162 + elif (filetype == const.FILETYPE_PNG):
  163 + writer = vtk.vtkPNGWriter()
  164 + elif (filetype == const.FILETYPE_PS):
  165 + writer = vtk.vtkPostScriptWriter()
  166 + elif (filetype == const.FILETYPE_TIF):
  167 + writer = vtk.vtkTIFFWriter()
  168 + filename = "%s.tif"%filename.strip(".tif")
  169 +
  170 + writer.SetInput(image)
  171 + writer.SetFileName(filename)
  172 + writer.Write()
  173 + ps.Publisher().sendMessage('End busy cursor')
  174 +
  175 +
  176 +
132 177 def OnCloseProject(self, pubsub_evt):
133 178 if self.raycasting_volume:
134 179 self.raycasting_volume = False
... ...
invesalius/gui/dialogs.py
... ... @@ -25,8 +25,8 @@ from wx.lib.wordwrap import wordwrap
25 25 import wx.lib.pubsub as ps
26 26  
27 27  
28   -
29   -import project
  28 +import constants as const
  29 +import project as proj
30 30 import session as ses
31 31  
32 32  
... ... @@ -126,9 +126,6 @@ class ProgressDialog(object):
126 126  
127 127  
128 128  
129   -
130   -
131   -
132 129 #---------
133 130 WILDCARD_OPEN = "InVesalius 3 project (*.inv3)|*.inv3|"\
134 131 "All files (*.*)|*.*"
... ... @@ -476,5 +473,54 @@ class NewSurfaceDialog(wx.Dialog):
476 473 #def GetValue(self):
477 474 # return self.text.GetValue() + _("| mask: ") + MASK_LIST[self.combo_surface_name.GetSelection()]
478 475  
  476 +INDEX_TO_EXTENSION = {0: "bmp", 1: "jpg", 2: "png", 3: "ps", 4:"povray", 5:"tiff"}
  477 +WILDCARD_SAVE_PICTURE = _("BMP image")+" (*.bmp)|*.bmp|"+\
  478 + _("JPG image")+" (*.jpg)|*.jpg|"+\
  479 + _("PNG image")+" (*.png)|*.png|"+\
  480 + _("PostScript document")+" (*.ps)|*.ps|"+\
  481 + _("POV-Ray file)")+" (*.pov)|*.pov|"+\
  482 + _("TIFF image")+" (*.tif)|*.tif"
  483 +
  484 +
  485 +def ExportPicture(type_=""):
  486 + import constants as const
  487 +
  488 + INDEX_TO_TYPE = {0: const.FILETYPE_BMP,
  489 + 1: const.FILETYPE_JPG,
  490 + 2: const.FILETYPE_PNG,
  491 + 3: const.FILETYPE_PS,
  492 + 4: const.FILETYPE_POV,
  493 + 5: const.FILETYPE_TIF}
  494 +
  495 + print "ExportPicture"
  496 + project = proj.Project()
  497 +
  498 + if sys.platform == 'win32':
  499 + project_name = project.name
  500 + else:
  501 + project_name = project.name+".jpg"
  502 +
  503 +
  504 + dlg = wx.FileDialog(None,
  505 + "Save %s picture as..." %type_,
  506 + "", # last used directory
  507 + "%s_%s"%(project_name, type_), # filename
  508 + WILDCARD_SAVE_PICTURE,
  509 + wx.SAVE|wx.OVERWRITE_PROMPT)
  510 + dlg.SetFilterIndex(1) # default is VTI
  511 +
  512 + if dlg.ShowModal() == wx.ID_OK:
  513 + filetype_index = dlg.GetFilterIndex()
  514 + filetype = INDEX_TO_TYPE[filetype_index]
  515 + extension = INDEX_TO_EXTENSION[filetype_index]
  516 + filename = dlg.GetPath()
  517 + print "filename", filename
  518 + if sys.platform != 'win32':
  519 + if filename.split(".")[-1] != extension:
  520 + filename = filename + "."+ extension
  521 + return filename, filetype
  522 + else:
  523 + return ()
  524 +
479 525  
480 526  
... ...
invesalius/gui/task_exporter.py
... ... @@ -26,6 +26,7 @@ import wx.lib.platebtn as pbtn
26 26 import wx.lib.pubsub as ps
27 27  
28 28 import constants as const
  29 +import gui.dialogs as dlg
29 30 import project as proj
30 31  
31 32 BTN_MASK = wx.NewId()
... ... @@ -180,6 +181,8 @@ class InnerTaskPanel(wx.Panel):
180 181 button_picture = pbtn.PlateButton(self, BTN_PICTURE, "",
181 182 BMP_TAKE_PICTURE,
182 183 style=button_style)
  184 + self.button_picture = button_picture
  185 +
183 186 button_surface = pbtn.PlateButton(self, BTN_SURFACE, "",
184 187 BMP_EXPORT_SURFACE,
185 188 style=button_style)
... ... @@ -220,9 +223,39 @@ class InnerTaskPanel(wx.Panel):
220 223 self.SetSizer(main_sizer)
221 224 self.Fit()
222 225 self.sizer = main_sizer
  226 + self.__init_menu()
  227 +
  228 + def __init_menu(self):
  229 +
  230 +
  231 + menu = wx.Menu()
  232 + self.id_to_name = {const.AXIAL:_("Axial slice"),
  233 + const.CORONAL:_("Coronal slice"),
  234 + const.SAGITAL:_("Sagittal slice"),
  235 + const.VOLUME:_("Volume")}
  236 +
  237 + for id in self.id_to_name:
  238 + item = wx.MenuItem(menu, id, self.id_to_name[id])
  239 + menu.AppendItem(item)
  240 +
  241 + self.menu_picture = menu
  242 + menu.Bind(wx.EVT_MENU, self.OnMenuPicture)
  243 +
  244 + def OnMenuPicture(self, evt):
  245 + print "OnMenuPicture"
  246 + id = evt.GetId()
  247 + value = dlg.ExportPicture(self.id_to_name[id])
  248 + if value:
  249 + filename, filetype = value
  250 + print filename, filetype
  251 + ps.Publisher().sendMessage('Export picture to file',
  252 + (id, filename, filetype))
  253 +
  254 +
223 255  
224 256 def OnLinkExportPicture(self, evt=None):
225   - pass
  257 + self.button_picture.PopupMenu(self.menu_picture)
  258 +
226 259  
227 260 def OnLinkExportMask(self, evt=None):
228 261 project = proj.Project()
... ...