Commit ee5249f94690f62a2941e77293820c7e2335111a
1 parent
430896dc
Exists in
master
and in
68 other branches
STYLE: moved the methode that generates the image previews from dicom.py to a ne…
…w class, DicomInfo.py
Showing
2 changed files
with
269 additions
and
327 deletions
Show diff stats
invesalius/gui/dicom_preview_panel.py
| ... | ... | @@ -21,23 +21,25 @@ |
| 21 | 21 | # -*- coding: UTF-8 -*- |
| 22 | 22 | |
| 23 | 23 | #TODO: To create a beautiful API |
| 24 | +import time | |
| 25 | + | |
| 24 | 26 | import wx |
| 25 | -import wx.lib.agw.buttonpanel as bp | |
| 26 | 27 | import vtk |
| 27 | -from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor | |
| 28 | -import vtkgdcm | |
| 29 | 28 | |
| 29 | +from vtk.util import numpy_support | |
| 30 | +from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor | |
| 30 | 31 | |
| 31 | 32 | import constants as const |
| 32 | 33 | from reader import dicom_reader |
| 33 | 34 | import data.vtk_utils as vtku |
| 34 | -import time | |
| 35 | - | |
| 36 | 35 | |
| 37 | 36 | NROWS = 3 |
| 38 | 37 | NCOLS = 6 |
| 39 | -MAX_VALUE = NCOLS*NROWS | |
| 38 | +NUM_PREVIEWS = NCOLS*NROWS | |
| 39 | +PREVIEW_WIDTH = 70 | |
| 40 | +PREVIEW_HEIGTH = 70 | |
| 40 | 41 | |
| 42 | +PREVIEW_BACKGROUND = (255, 255, 255) # White | |
| 41 | 43 | |
| 42 | 44 | STR_SIZE = _("Image size: %d x %d") |
| 43 | 45 | STR_SPC = _("Spacing: %.2f") |
| ... | ... | @@ -45,6 +47,247 @@ STR_LOCAL = _("Location: %.2f") |
| 45 | 47 | STR_PATIENT = "%s\n%s" |
| 46 | 48 | STR_ACQ = _("%s %s\nMade in InVesalius") |
| 47 | 49 | |
| 50 | +class DicomInfo(object): | |
| 51 | + """ | |
| 52 | + Keep the informations and the image used by preview. | |
| 53 | + """ | |
| 54 | + def __init__(self, id, dicom, title, subtitle): | |
| 55 | + self.id = id | |
| 56 | + self.dicom = dicom | |
| 57 | + self.title = title | |
| 58 | + self.subtitle = subtitle | |
| 59 | + self._preview = None | |
| 60 | + | |
| 61 | + @property | |
| 62 | + def preview(self): | |
| 63 | + if self._preview: | |
| 64 | + return self._preview | |
| 65 | + else: | |
| 66 | + colorer = vtk.vtkImageMapToWindowLevelColors() | |
| 67 | + colorer.SetInput(self.dicom.image.imagedata) | |
| 68 | + colorer.SetWindow(float(self.dicom.image.window)) | |
| 69 | + colorer.SetLevel(float(self.dicom.image.level)) | |
| 70 | + colorer.SetOutputFormatToRGB() | |
| 71 | + colorer.Update() | |
| 72 | + | |
| 73 | + width, height, z = colorer.GetOutput().GetDimensions() | |
| 74 | + | |
| 75 | + r = colorer.GetOutput().GetPointData().GetScalars() | |
| 76 | + ni = numpy_support.vtk_to_numpy(r) | |
| 77 | + img = wx.ImageFromBuffer(width, height, ni) | |
| 78 | + img = img.Rescale(PREVIEW_WIDTH, PREVIEW_HEIGTH).Mirror(False) | |
| 79 | + self._preview = wx.BitmapFromImage(img) | |
| 80 | + return self._preview | |
| 81 | + | |
| 82 | + | |
| 83 | +class Preview(wx.Panel): | |
| 84 | + """ | |
| 85 | + The little previews. | |
| 86 | + """ | |
| 87 | + def __init__(self, parent): | |
| 88 | + super(Preview, self).__init__(parent, style= wx.BORDER) | |
| 89 | + # Will it be white? | |
| 90 | + self.select_on = False | |
| 91 | + self._init_ui() | |
| 92 | + self._bind_events() | |
| 93 | + | |
| 94 | + def _init_ui(self): | |
| 95 | + self.title = wx.StaticText(self, -1, _("Image"), | |
| 96 | + style=wx.ALIGN_CENTER) | |
| 97 | + self.subtitle = wx.StaticText(self, -1, _("Image"), | |
| 98 | + style=wx.ALIGN_CENTER) | |
| 99 | + self.image_viewer = wx.StaticBitmap(self, -1, size=(70, 70)) | |
| 100 | + | |
| 101 | + #self.panel = wx.Panel(self, -1) | |
| 102 | + | |
| 103 | + self.SetBackgroundColour(PREVIEW_BACKGROUND) | |
| 104 | + | |
| 105 | + sizer_image = wx.BoxSizer(wx.HORIZONTAL) | |
| 106 | + sizer_image.Add(self.image_viewer, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL) | |
| 107 | + | |
| 108 | + self.sizer = wx.BoxSizer(wx.VERTICAL) | |
| 109 | + self.sizer.AddSpacer(2) | |
| 110 | + self.sizer.Add(self.title, 0, | |
| 111 | + wx.GROW|wx.EXPAND|wx. ALIGN_CENTER_HORIZONTAL) | |
| 112 | + self.sizer.Add(self.subtitle, 0, | |
| 113 | + wx.GROW|wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL) | |
| 114 | + self.sizer.Add(sizer_image, 5, wx.GROW|wx.EXPAND|wx.ALL, 4) | |
| 115 | + self.sizer.Fit(self) | |
| 116 | + | |
| 117 | + self.SetSizer(self.sizer) | |
| 118 | + | |
| 119 | + self.Layout() | |
| 120 | + self.Update() | |
| 121 | + self.Fit() | |
| 122 | + self.SetAutoLayout(1) | |
| 123 | + | |
| 124 | + def _bind_events(self): | |
| 125 | + self.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | |
| 126 | + #self.interactor.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | |
| 127 | + #self.panel.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | |
| 128 | + #self.title.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | |
| 129 | + #self.subtitle.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | |
| 130 | + | |
| 131 | + self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | |
| 132 | + #self.interactor.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | |
| 133 | + #self.panel.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | |
| 134 | + #self.title.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | |
| 135 | + #self.subtitle.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | |
| 136 | + | |
| 137 | + self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | |
| 138 | + #self.interactor.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | |
| 139 | + #self.panel.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | |
| 140 | + #self.title.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | |
| 141 | + #self.subtitle.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | |
| 142 | + | |
| 143 | + self.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | |
| 144 | + #self.interactor.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | |
| 145 | + #self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | |
| 146 | + #self.title.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | |
| 147 | + #self.subtitle.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | |
| 148 | + | |
| 149 | + def SetDicomToPreview(self, dicom_info): | |
| 150 | + """ | |
| 151 | + Set a dicom to preview. | |
| 152 | + """ | |
| 153 | + self.SetTitle(dicom_info.title) | |
| 154 | + self.SetSubtitle(dicom_info.subtitle) | |
| 155 | + self.ID = dicom_info.id | |
| 156 | + image = dicom_info.preview | |
| 157 | + self.image_viewer.SetBitmap(image) | |
| 158 | + self.data = dicom_info.id | |
| 159 | + self.Update() | |
| 160 | + | |
| 161 | + def SetTitle(self, title): | |
| 162 | + self.title.SetLabel(title) | |
| 163 | + | |
| 164 | + def SetSubtitle(self, subtitle): | |
| 165 | + self.subtitle.SetLabel(subtitle) | |
| 166 | + | |
| 167 | + def OnEnter(self, evt): | |
| 168 | + if not self.select_on: | |
| 169 | + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHILIGHT) | |
| 170 | + c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) | |
| 171 | + self.SetBackgroundColour(c) | |
| 172 | + | |
| 173 | + def OnLeave(self, evt): | |
| 174 | + if not self.select_on: | |
| 175 | + c = (255,255,255) | |
| 176 | + self.SetBackgroundColour(c) | |
| 177 | + | |
| 178 | + def OnSelect(self, evt): | |
| 179 | + print "OnSelect" | |
| 180 | + self.select_on = True | |
| 181 | + ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNHIGHLIGHT) | |
| 182 | + ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HOTLIGHT) | |
| 183 | + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) | |
| 184 | + ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_GRADIENTACTIVECAPTION) | |
| 185 | + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW) | |
| 186 | + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_ACTIVEBORDER) | |
| 187 | + #*c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DLIGHT) | |
| 188 | + #*c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHILIGHT) | |
| 189 | + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHIGHLIGHT) | |
| 190 | + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DDKSHADOW) | |
| 191 | + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW) | |
| 192 | + #self.SetBackgroundColour(c) | |
| 193 | + self.Select() | |
| 194 | + | |
| 195 | + def Select(self, on=True): | |
| 196 | + if self.select_on: | |
| 197 | + c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) | |
| 198 | + else: | |
| 199 | + c = (255,255,255) | |
| 200 | + self.SetBackgroundColour(c) | |
| 201 | + self.Refresh() | |
| 202 | + | |
| 203 | + def OnDClick(self, evt): | |
| 204 | + evt = PreviewEvent(myEVT_SELECT, self.GetId()) | |
| 205 | + evt.SetSelectedID(self.ID) | |
| 206 | + evt.SetItemData(self.data) | |
| 207 | + self.GetEventHandler().ProcessEvent(evt) | |
| 208 | + | |
| 209 | + def ShowShadow(self): | |
| 210 | + self._nImgSize = 16 | |
| 211 | + nPadding = 4 | |
| 212 | + print "ShowShadow" | |
| 213 | + dc = wx.BufferedPaintDC(self) | |
| 214 | + style = self.GetParent().GetWindowStyleFlag() | |
| 215 | + | |
| 216 | + backBrush = wx.WHITE_BRUSH | |
| 217 | + if 1: #style & INB_BORDER: | |
| 218 | + borderPen = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW)) | |
| 219 | + #else: | |
| 220 | + # borderPen = wx.TRANSPARENT_PEN | |
| 221 | + | |
| 222 | + size = self.GetSize() | |
| 223 | + | |
| 224 | + # Background | |
| 225 | + dc.SetBrush(backBrush) | |
| 226 | + | |
| 227 | + borderPen.SetWidth(1) | |
| 228 | + dc.SetPen(borderPen) | |
| 229 | + dc.DrawRectangle(0, 0, size.x, size.y) | |
| 230 | + #bUsePin = (style & INB_USE_PIN_BUTTON and [True] or [False])[0] | |
| 231 | + | |
| 232 | + borderPen = wx.BLACK_PEN | |
| 233 | + borderPen.SetWidth(1) | |
| 234 | + dc.SetPen(borderPen) | |
| 235 | + dc.DrawLine(0, size.y, size.x, size.y) | |
| 236 | + dc.DrawPoint(0, size.y) | |
| 237 | + | |
| 238 | + clientSize = 0 | |
| 239 | + #bUseYcoord = (style & INB_RIGHT or style & INB_LEFT) | |
| 240 | + bUseYcoord = 1 | |
| 241 | + | |
| 242 | + if bUseYcoord: | |
| 243 | + clientSize = size.GetHeight() | |
| 244 | + else: | |
| 245 | + clientSize = size.GetWidth() | |
| 246 | + | |
| 247 | + if 1: | |
| 248 | + # Default values for the surronounding rectangle | |
| 249 | + # around a button | |
| 250 | + rectWidth = self._nImgSize * 2 # To avoid the recangle to 'touch' the borders | |
| 251 | + rectHeight = self._nImgSize * 2 | |
| 252 | + | |
| 253 | + # Incase the style requires non-fixed button (fit to text) | |
| 254 | + # recalc the rectangle width | |
| 255 | + if 1: | |
| 256 | + #if style & INB_FIT_BUTTON and \ | |
| 257 | + # not ((style & INB_LEFT) or (style & INB_RIGHT)) and \ | |
| 258 | + # not self._pagesInfoVec[i].GetCaption() == "" and \ | |
| 259 | + # not (style & INB_SHOW_ONLY_IMAGES): | |
| 260 | + | |
| 261 | + | |
| 262 | + #rectWidth = ((textWidth + nPadding * 2) > rectWidth and [nPadding * 2 + textWidth] or [rectWidth])[0] | |
| 263 | + | |
| 264 | + rectWidth = ((nPadding * 2) > rectWidth and [nPadding * 2] or [rectWidth])[0] | |
| 265 | + # Make the width an even number | |
| 266 | + if rectWidth % 2 != 0: | |
| 267 | + rectWidth += 1 | |
| 268 | + | |
| 269 | + # If Pin button is used, consider its space as well (applicable for top/botton style) | |
| 270 | + # since in the left/right, its size is already considered in 'pos' | |
| 271 | + #pinBtnSize = (bUsePin and [20] or [0])[0] | |
| 272 | + | |
| 273 | + #if pos + rectWidth + pinBtnSize > clientSize: | |
| 274 | + # break | |
| 275 | + | |
| 276 | + # Calculate the button rectangle | |
| 277 | + modRectWidth = rectWidth - 2# or [rectWidth])[0] | |
| 278 | + modRectHeight = rectHeight# or [rectHeight - 2])[0] | |
| 279 | + | |
| 280 | + pos = rectWidth | |
| 281 | + | |
| 282 | + if bUseYcoord: | |
| 283 | + buttonRect = wx.Rect(1, pos, modRectWidth, modRectHeight) | |
| 284 | + else: | |
| 285 | + buttonRect = wx.Rect(pos , 1, modRectWidth, modRectHeight) | |
| 286 | + | |
| 287 | + def ShowShadow2(self): | |
| 288 | + pass | |
| 289 | + | |
| 290 | + | |
| 48 | 291 | class SingleImagePreview(wx.Panel): |
| 49 | 292 | def __init__(self, parent): |
| 50 | 293 | wx.Panel.__init__(self, parent, -1) |
| ... | ... | @@ -265,278 +508,6 @@ class SerieEvent(PreviewEvent): |
| 265 | 508 | def __init__(self , evtType, id): |
| 266 | 509 | super(SerieEvent, self).__init__(evtType, id) |
| 267 | 510 | |
| 268 | -class Preview(wx.Panel): | |
| 269 | - """ | |
| 270 | - Where the images will be showed. | |
| 271 | - """ | |
| 272 | - def __init__(self, parent): | |
| 273 | - super(Preview, self).__init__(parent) | |
| 274 | - # Will it be white? | |
| 275 | - self.select_on = False | |
| 276 | - self._init_ui() | |
| 277 | - #self._init_vtk() | |
| 278 | - #self._bind_events() | |
| 279 | - | |
| 280 | - def _init_ui(self): | |
| 281 | - | |
| 282 | - self.title = wx.StaticText(self, -1, _("Image"), | |
| 283 | - style=wx.ALIGN_CENTER) | |
| 284 | - | |
| 285 | - self.subtitle = wx.StaticText(self, -1, _("Image"), | |
| 286 | - style=wx.ALIGN_CENTER) | |
| 287 | - | |
| 288 | - self.image_viewer = wx.StaticBitmap(self, -1) | |
| 289 | - | |
| 290 | - #self.panel = wx.Panel(self, -1) | |
| 291 | - | |
| 292 | - self.SetBackgroundColour((255,255,255)) | |
| 293 | - | |
| 294 | - self.sizer = wx.BoxSizer(wx.VERTICAL) | |
| 295 | - self.sizer.AddSpacer(2) | |
| 296 | - self.sizer.Add(self.title, 1, | |
| 297 | - wx.GROW|wx.EXPAND|wx. ALIGN_CENTER_HORIZONTAL) | |
| 298 | - self.sizer.Add(self.subtitle, 1, | |
| 299 | - wx.GROW|wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL) | |
| 300 | - self.sizer.Add(self.image_viewer, 5, wx.GROW|wx.EXPAND|wx.ALL, 4) | |
| 301 | - self.sizer.Fit(self) | |
| 302 | - | |
| 303 | - | |
| 304 | - self.SetSizer(self.sizer) | |
| 305 | - | |
| 306 | - | |
| 307 | - self.Layout() | |
| 308 | - self.Update() | |
| 309 | - self.Fit() | |
| 310 | - self.SetAutoLayout(1) | |
| 311 | - | |
| 312 | - | |
| 313 | - def _init_vtk(self): | |
| 314 | - | |
| 315 | - self.interactor = wxVTKRenderWindowInteractor(self.panel, -1, size=(70, 70)) | |
| 316 | - | |
| 317 | - sizer = wx.BoxSizer(wx.HORIZONTAL) | |
| 318 | - sizer.Add(self.interactor, 1, wx.GROW|wx.EXPAND) | |
| 319 | - sizer.Fit(self.panel) | |
| 320 | - | |
| 321 | - self.panel.SetSizer(sizer) | |
| 322 | - | |
| 323 | - self.panel.Layout() | |
| 324 | - self.panel.Update() | |
| 325 | - self.panel.SetAutoLayout(1) | |
| 326 | - | |
| 327 | - self.actor = vtk.vtkImageActor() | |
| 328 | - | |
| 329 | - self.render = vtk.vtkRenderer() | |
| 330 | - self.render.AddActor(self.actor) | |
| 331 | - | |
| 332 | - self.interactor.SetInteractorStyle(None) | |
| 333 | - self.interactor.GetRenderWindow().AddRenderer(self.render) | |
| 334 | - | |
| 335 | - | |
| 336 | - def _bind_events(self): | |
| 337 | - self.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | |
| 338 | - self.interactor.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | |
| 339 | - self.panel.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | |
| 340 | - self.title.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | |
| 341 | - self.subtitle.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | |
| 342 | - | |
| 343 | - self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | |
| 344 | - self.interactor.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | |
| 345 | - self.panel.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | |
| 346 | - self.title.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | |
| 347 | - self.subtitle.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | |
| 348 | - | |
| 349 | - self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | |
| 350 | - self.interactor.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | |
| 351 | - self.panel.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | |
| 352 | - self.title.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | |
| 353 | - self.subtitle.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | |
| 354 | - | |
| 355 | - self.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | |
| 356 | - self.interactor.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | |
| 357 | - self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | |
| 358 | - self.title.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | |
| 359 | - self.subtitle.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | |
| 360 | - | |
| 361 | - | |
| 362 | - | |
| 363 | - | |
| 364 | - def OnEnter(self, evt): | |
| 365 | - if not self.select_on: | |
| 366 | - #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHILIGHT) | |
| 367 | - c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) | |
| 368 | - self.SetBackgroundColour(c) | |
| 369 | - | |
| 370 | - | |
| 371 | - def OnLeave(self, evt): | |
| 372 | - if not self.select_on: | |
| 373 | - c = (255,255,255) | |
| 374 | - self.SetBackgroundColour(c) | |
| 375 | - | |
| 376 | - def OnSelect(self, evt): | |
| 377 | - self.select_on = True | |
| 378 | - ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNHIGHLIGHT) | |
| 379 | - ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HOTLIGHT) | |
| 380 | - #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) | |
| 381 | - ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_GRADIENTACTIVECAPTION) | |
| 382 | - #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW) | |
| 383 | - #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_ACTIVEBORDER) | |
| 384 | - #*c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DLIGHT) | |
| 385 | - #*c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHILIGHT) | |
| 386 | - #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHIGHLIGHT) | |
| 387 | - #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DDKSHADOW) | |
| 388 | - #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW) | |
| 389 | - #self.SetBackgroundColour(c) | |
| 390 | - self.Select() | |
| 391 | - | |
| 392 | - def Select(self, on=True): | |
| 393 | - self.select_on = on | |
| 394 | - if on: | |
| 395 | - c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHIGHLIGHT) | |
| 396 | - else: | |
| 397 | - c = (255,255,255) | |
| 398 | - self.SetBackgroundColour(c) | |
| 399 | - | |
| 400 | - | |
| 401 | - def OnDClick(self, evt): | |
| 402 | - evt = PreviewEvent(myEVT_SELECT, self.GetId()) | |
| 403 | - evt.SetSelectedID(self.ID) | |
| 404 | - evt.SetItemData(self.data) | |
| 405 | - self.GetEventHandler().ProcessEvent(evt) | |
| 406 | - | |
| 407 | - def SetTitle(self, title): | |
| 408 | - self.title.SetLabel(title) | |
| 409 | - | |
| 410 | - def SetSubtitle(self, subtitle): | |
| 411 | - self.subtitle.SetLabel(subtitle) | |
| 412 | - | |
| 413 | - def SetDicomToPreview(self, image_file): | |
| 414 | - """ | |
| 415 | - Set a Image to preview. | |
| 416 | - """ | |
| 417 | - self.SetTitle(image_file[3]) | |
| 418 | - self.SetSubtitle(image_file[4]) | |
| 419 | - | |
| 420 | - self.Layout() | |
| 421 | - self.Update() | |
| 422 | - | |
| 423 | - self.ID = image_file[5] | |
| 424 | - | |
| 425 | - #image_reader = vtkgdcm.vtkGDCMImageReader() | |
| 426 | - #image_reader.SetFileName(image_file[0]) | |
| 427 | - #image = image_reader.GetOutput() | |
| 428 | - | |
| 429 | - image = image_file[-1].image.jpeg_file | |
| 430 | - #img = wx.Image(image, wx.BITMAP_TYPE_JPEG) | |
| 431 | - #img.Rescale(70, 70) | |
| 432 | - #bmp = wx.BitmapFromImage(img) | |
| 433 | - self.image_viewer.SetBitmap(image) | |
| 434 | - | |
| 435 | - #scale = image.GetScalarRange() | |
| 436 | - | |
| 437 | - #cast = vtk.vtkImageMapToWindowLevelColors() | |
| 438 | - ##cast.SetShift(abs(scale[0])) | |
| 439 | - ##cast.SetScale(255.0/(scale[1] - scale[0])) | |
| 440 | - ##cast.ClampOverflowOn() | |
| 441 | - #cast.SetInput(image) | |
| 442 | - ##cast.SetOutputScalarTypeToUnsignedChar() | |
| 443 | - #try: | |
| 444 | - # window = float(image_file[1]) | |
| 445 | - # level = float(image_file[2]) | |
| 446 | - #except TypeError: | |
| 447 | - # #TODO: These values are good? | |
| 448 | - # level = 230 | |
| 449 | - # window = 150 | |
| 450 | - | |
| 451 | - #self.data = image_file[-1] | |
| 452 | - | |
| 453 | - #cast.SetWindow(window) | |
| 454 | - #cast.SetLevel(level) | |
| 455 | - #self.actor.SetInput(cast.GetOutput()) | |
| 456 | - #self.render.ResetCamera() | |
| 457 | - #self.interactor.Render() | |
| 458 | - | |
| 459 | - def ShowShadow(self): | |
| 460 | - self._nImgSize = 16 | |
| 461 | - nPadding = 4 | |
| 462 | - print "ShowShadow" | |
| 463 | - dc = wx.BufferedPaintDC(self) | |
| 464 | - style = self.GetParent().GetWindowStyleFlag() | |
| 465 | - | |
| 466 | - backBrush = wx.WHITE_BRUSH | |
| 467 | - if 1: #style & INB_BORDER: | |
| 468 | - borderPen = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW)) | |
| 469 | - #else: | |
| 470 | - # borderPen = wx.TRANSPARENT_PEN | |
| 471 | - | |
| 472 | - size = self.GetSize() | |
| 473 | - | |
| 474 | - # Background | |
| 475 | - dc.SetBrush(backBrush) | |
| 476 | - | |
| 477 | - borderPen.SetWidth(1) | |
| 478 | - dc.SetPen(borderPen) | |
| 479 | - dc.DrawRectangle(0, 0, size.x, size.y) | |
| 480 | - #bUsePin = (style & INB_USE_PIN_BUTTON and [True] or [False])[0] | |
| 481 | - | |
| 482 | - borderPen = wx.BLACK_PEN | |
| 483 | - borderPen.SetWidth(1) | |
| 484 | - dc.SetPen(borderPen) | |
| 485 | - dc.DrawLine(0, size.y, size.x, size.y) | |
| 486 | - dc.DrawPoint(0, size.y) | |
| 487 | - | |
| 488 | - clientSize = 0 | |
| 489 | - #bUseYcoord = (style & INB_RIGHT or style & INB_LEFT) | |
| 490 | - bUseYcoord = 1 | |
| 491 | - | |
| 492 | - if bUseYcoord: | |
| 493 | - clientSize = size.GetHeight() | |
| 494 | - else: | |
| 495 | - clientSize = size.GetWidth() | |
| 496 | - | |
| 497 | - | |
| 498 | - if 1: | |
| 499 | - # Default values for the surronounding rectangle | |
| 500 | - # around a button | |
| 501 | - rectWidth = self._nImgSize * 2 # To avoid the recangle to 'touch' the borders | |
| 502 | - rectHeight = self._nImgSize * 2 | |
| 503 | - | |
| 504 | - # Incase the style requires non-fixed button (fit to text) | |
| 505 | - # recalc the rectangle width | |
| 506 | - if 1: | |
| 507 | - #if style & INB_FIT_BUTTON and \ | |
| 508 | - # not ((style & INB_LEFT) or (style & INB_RIGHT)) and \ | |
| 509 | - # not self._pagesInfoVec[i].GetCaption() == "" and \ | |
| 510 | - # not (style & INB_SHOW_ONLY_IMAGES): | |
| 511 | - | |
| 512 | - | |
| 513 | - #rectWidth = ((textWidth + nPadding * 2) > rectWidth and [nPadding * 2 + textWidth] or [rectWidth])[0] | |
| 514 | - | |
| 515 | - rectWidth = ((nPadding * 2) > rectWidth and [nPadding * 2] or [rectWidth])[0] | |
| 516 | - # Make the width an even number | |
| 517 | - if rectWidth % 2 != 0: | |
| 518 | - rectWidth += 1 | |
| 519 | - | |
| 520 | - # If Pin button is used, consider its space as well (applicable for top/botton style) | |
| 521 | - # since in the left/right, its size is already considered in 'pos' | |
| 522 | - #pinBtnSize = (bUsePin and [20] or [0])[0] | |
| 523 | - | |
| 524 | - #if pos + rectWidth + pinBtnSize > clientSize: | |
| 525 | - # break | |
| 526 | - | |
| 527 | - # Calculate the button rectangle | |
| 528 | - modRectWidth = rectWidth - 2# or [rectWidth])[0] | |
| 529 | - modRectHeight = rectHeight# or [rectHeight - 2])[0] | |
| 530 | - | |
| 531 | - pos = rectWidth | |
| 532 | - | |
| 533 | - if bUseYcoord: | |
| 534 | - buttonRect = wx.Rect(1, pos, modRectWidth, modRectHeight) | |
| 535 | - else: | |
| 536 | - buttonRect = wx.Rect(pos , 1, modRectWidth, modRectHeight) | |
| 537 | - | |
| 538 | - def ShowShadow2(self): | |
| 539 | - pass | |
| 540 | 511 | |
| 541 | 512 | |
| 542 | 513 | class DicomPreviewSeries(wx.Panel): |
| ... | ... | @@ -611,14 +582,18 @@ class DicomPreviewSeries(wx.Panel): |
| 611 | 582 | self.group_list = group_list |
| 612 | 583 | n = 0 |
| 613 | 584 | for group in group_list: |
| 614 | - info = (group.dicom.image, | |
| 615 | - float(group.dicom.image.window), | |
| 616 | - float(group.dicom.image.level), | |
| 617 | - group.title, | |
| 618 | - _("%d Images") %(group.nslices), | |
| 619 | - n, | |
| 620 | - group_list, | |
| 621 | - group.dicom) | |
| 585 | + #info = (group.dicom.image, | |
| 586 | + # float(group.dicom.image.window), | |
| 587 | + # float(group.dicom.image.level), | |
| 588 | + # group.title, | |
| 589 | + # _("%d Images") %(group.nslices), | |
| 590 | + # n, | |
| 591 | + # group_list, | |
| 592 | + # group.dicom) | |
| 593 | + info = DicomInfo(n, group.dicom, | |
| 594 | + group.title, | |
| 595 | + _("%d Images") %(group.nslices), | |
| 596 | + ) | |
| 622 | 597 | self.files.append(info) |
| 623 | 598 | n+=1 |
| 624 | 599 | |
| ... | ... | @@ -630,7 +605,7 @@ class DicomPreviewSeries(wx.Panel): |
| 630 | 605 | |
| 631 | 606 | def _display_previews(self): |
| 632 | 607 | initial = self.displayed_position * NCOLS |
| 633 | - final = initial + MAX_VALUE | |
| 608 | + final = initial + NUM_PREVIEWS | |
| 634 | 609 | |
| 635 | 610 | if len(self.files) < final: |
| 636 | 611 | for i in xrange(final-len(self.files)): |
| ... | ... | @@ -733,13 +708,9 @@ class DicomPreview(wx.Panel): |
| 733 | 708 | dicom_files = group.GetHandSortedList() |
| 734 | 709 | n = 0 |
| 735 | 710 | for dicom in dicom_files: |
| 736 | - info = (dicom.image.imagedata, | |
| 737 | - dicom.image.window, | |
| 738 | - dicom.image.level, | |
| 739 | - _("Image %d") % (dicom.image.number), | |
| 740 | - "%.2f" % (dicom.image.position[2]), | |
| 741 | - n, | |
| 742 | - dicom) | |
| 711 | + info = DicomInfo(n, dicom, | |
| 712 | + _("Image %d") % (dicom.image.number), | |
| 713 | + "%.2f" % (dicom.image.position[2])) | |
| 743 | 714 | self.files.append(info) |
| 744 | 715 | n+=1 |
| 745 | 716 | |
| ... | ... | @@ -758,13 +729,10 @@ class DicomPreview(wx.Panel): |
| 758 | 729 | dicom_files = group.GetHandSortedList() |
| 759 | 730 | n = 0 |
| 760 | 731 | for dicom in dicom_files: |
| 761 | - info = (dicom.image, | |
| 762 | - dicom.image.window, | |
| 763 | - dicom.image.level, | |
| 732 | + info = DicomInfo(n, dicom, | |
| 764 | 733 | _("Image %d") % (dicom.image.number), |
| 765 | 734 | "%.2f" % (dicom.image.position[2]), |
| 766 | - n, | |
| 767 | - dicom) | |
| 735 | + ) | |
| 768 | 736 | self.files.append(info) |
| 769 | 737 | n+=1 |
| 770 | 738 | |
| ... | ... | @@ -775,10 +743,9 @@ class DicomPreview(wx.Panel): |
| 775 | 743 | |
| 776 | 744 | self._display_previews() |
| 777 | 745 | |
| 778 | - | |
| 779 | 746 | def _display_previews(self): |
| 780 | 747 | initial = self.displayed_position * NCOLS |
| 781 | - final = initial + MAX_VALUE | |
| 748 | + final = initial + NUM_PREVIEWS | |
| 782 | 749 | print "len:", len(self.files) |
| 783 | 750 | |
| 784 | 751 | if len(self.files) < final: | ... | ... |
invesalius/reader/dicom.py
| ... | ... | @@ -20,12 +20,9 @@ |
| 20 | 20 | import time |
| 21 | 21 | |
| 22 | 22 | import gdcm |
| 23 | -import Image | |
| 24 | -import vtk | |
| 25 | 23 | import vtkgdcm |
| 26 | 24 | import wx |
| 27 | 25 | |
| 28 | -from vtk.util import numpy_support | |
| 29 | 26 | |
| 30 | 27 | # In DICOM file format, if multiple values are present for the |
| 31 | 28 | # "Window Center" (Level) and "Window Width", both attributes |
| ... | ... | @@ -1839,7 +1836,7 @@ class Acquisition(object): |
| 1839 | 1836 | class Image(object): |
| 1840 | 1837 | |
| 1841 | 1838 | def __init__(self): |
| 1842 | - self._jpeg_file = None | |
| 1839 | + pass | |
| 1843 | 1840 | |
| 1844 | 1841 | def SetParser(self, parser): |
| 1845 | 1842 | self.level = parser.GetImageWindowLevel() |
| ... | ... | @@ -1873,25 +1870,3 @@ class Image(object): |
| 1873 | 1870 | spacing[1] = round(spacing[1],2) |
| 1874 | 1871 | spacing[2] = round(spacing[2],2) |
| 1875 | 1872 | self.spacing = spacing |
| 1876 | - | |
| 1877 | - @property | |
| 1878 | - def jpeg_file(self): | |
| 1879 | - if self._jpeg_file: | |
| 1880 | - return self._jpeg_file | |
| 1881 | - else: | |
| 1882 | - colorer = vtk.vtkImageMapToWindowLevelColors() | |
| 1883 | - colorer.SetInput(self.imagedata) | |
| 1884 | - colorer.SetWindow(float(self.window)) | |
| 1885 | - colorer.SetLevel(float(self.level)) | |
| 1886 | - colorer.SetOutputFormatToRGB() | |
| 1887 | - colorer.Update() | |
| 1888 | - | |
| 1889 | - width, height, z = colorer.GetOutput().GetDimensions() | |
| 1890 | - | |
| 1891 | - r = colorer.GetOutput().GetPointData().GetScalars() | |
| 1892 | - ni = numpy_support.vtk_to_numpy(r) | |
| 1893 | - #ni = ni.reshape(width, height, 3) | |
| 1894 | - img = wx.ImageFromBuffer(width, height, ni) | |
| 1895 | - img = img.Rescale(70, 70).Mirror(False) | |
| 1896 | - self._jpeg_file = wx.BitmapFromImage(img) | |
| 1897 | - return self._jpeg_file | ... | ... |