Commit 7137baa63a517a83e188f29eae9fa58f6b9f1ea7
1 parent
dc0b4234
Exists in
master
and in
68 other branches
ADD: Photo feature (fix #59)
Showing
5 changed files
with
193 additions
and
11 deletions
Show diff stats
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() | ... | ... |