class PngScraperFrame(wx.Frame): """ Frame for browsing through a list/directory of images, running a script on each. """ def __init__(self, *args, **kwargs): wx.Frame.__init__(self, *args, **kwargs) self.im: Image.Image = None self.pngs = [] self.cursor = Cursor(ListView(self.pngs)) self.coords: wx.TextCtrl = None self.color: wx.TextCtrl = None self.scroll: wx.ScrolledWindow = None self.image: wx.Image = None self.which: wx.TextCtrl = None self.locals = {} self.shell: py.shell.Shell = None def init(self): self.coords = XRCCTRL(self, 'txt_coords') self.color = XRCCTRL(self, 'txt_color') self.scroll = XRCCTRL(self, 'box_scroll') self.image = XRCCTRL(self, 'bmp_image') self.image.Bind(wx.EVT_LEFT_DOWN, self.on_left_down) self.image.Bind(wx.EVT_RIGHT_DOWN, self.on_right_down) #self.update_image() self.which = XRCCTRL(self, 'txt_which') self.update_which() # button handlers for btn in 'btn_first btn_prev btn_next btn_last'.split(): self.Bind(wx.EVT_BUTTON, self.on_cursor_button, id=XRCID(btn)) # menu handlers self.Bind(wx.EVT_MENU, self.on_exit, id=XRCID('cmd_exit')) self.Bind(wx.EVT_MENU, self.on_open_file, id=XRCID('cmd_open_file')) self.Bind(wx.EVT_MENU, self.on_open_dir, id=XRCID('cmd_open_dir')) self.Bind(wx.EVT_CLOSE, self.on_close_window) # -- manually add pyshell panel = XRCCTRL(self, 'shell_panel') self.locals = { 'self': self, 'wx': wx, 'hook': lambda: None, 'gc': self.get_dc() } self.shell = py.shell.Shell(panel, locals=self.locals) sizer = wx.BoxSizer() sizer.Add(self.shell, 4, wx.EXPAND) self.shell.SetFocus() panel.SetSizer(sizer) sizer.Fit(panel) def on_cursor_button(self, evt): button_map = { "<<": "moveToStart", "<": "movePrevious", ">": "moveNext", ">>": "moveToEnd" } try: getattr(self.cursor, button_map[evt.GetEventObject().Label])() self.update_which() self.update_image() self.shell.run('hook()') except StopIteration: pass def on_open_file(self, _evt): dlg = wx.FileDialog(self, message="Choose a file", defaultDir=os.getcwd(), defaultFile="", wildcard='*.png', style=wx.FD_OPEN | wx.FD_CHANGE_DIR) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() self.pngs.insert(self.cursor.position, path) self.update_which() self.update_image() def on_open_dir(self, _evt): dlg = wx.DirDialog(self, "Choose a directory:", defaultPath=os.getcwd(), style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() while self.pngs: self.pngs.pop() self.pngs.extend(png_list(path)) self.cursor.moveToStart() self.update_which() self.update_image() self.shell.run('hook()') def on_exit(self, _evt): self.Close() def update_which(self): self.which.Value = "%s/%s" % (self.cursor.position, len(self.pngs)) def update_image(self): if len(self.pngs): # set the visible bitmap img = wx.Image(self.pngs[self.cursor.position], wx.BITMAP_TYPE_PNG) self.image.SetBitmap(wx.Bitmap(img)) self.scroll.SetVirtualSize(self.image.Size) # and make the pil image self.im = Image.new('RGB', tuple(self.image.Size)) self.im.frombytes( bytes(self.image.GetBitmap().ConvertToImage().GetData())) def on_right_down(self, _e): self.image.Refresh() def on_left_down(self, e): point = (e.X, e.Y) self.coords.Value = "(%s,%s)" % point self.color.Value = "0x%s" % "".join( hex(v)[2:].upper() for v in self.im.getpixel(point)) # draw crosshairs: dc = wx.ClientDC(self.image) dc.SetPen(wx.Pen("RED")) dc.DrawLine(e.X - 2, e.Y, e.X, e.Y) dc.DrawLine(e.X, e.Y - 2, e.X, e.Y) dc.DrawLine(e.X + 2, e.Y, e.X, e.Y) dc.DrawLine(e.X, e.Y + 2, e.X, e.Y) def get_dc(self): """return the client drawing context""" gc = wx.GCDC(wx.ClientDC(self.image)) ink = wx.Colour(0x99, 0xcc, 0xff, 0x88) gc.SetPen(wx.Pen(ink)) gc.SetBrush(wx.Brush(ink)) return gc def draw_words(self): # @TODO: re-enable draw_words. it was cool. :) raise NotImplementedError # chars = self.chars() # inks = wx.Color(0x99, 0xcc, 0xff, 0x88) , wx.Color(0x99, 0xff, 0xcc, 0x88) # # gc = self.getGC() # # i = 0 # for c in chars: # if c[4] not in ('', ' '): # # ink = inks[i % 2] # i += 1 # # gc.SetPen(wx.Pen(ink)) # gc.SetBrush(wx.Brush(ink)) # # gc.DrawRectangle(*c[:4]) # def drawFirstUnkowns(self, cutoff=200, mode='L'): # "I *THINK* this was to show a new char to learn in context." # chars = self.chars(mode, cutoff) # # seen = {} # # gc = self.getGC() # ink = wx.Color(0xff, 0x00, 0x00, 0x88) # gc.SetPen(wx.Pen(ink)) # gc.SetBrush(wx.Brush(ink)) # # i = 0 # for c in chars: # if type(c[4]) in (int,long): # if c[4] not in seen: # gc.DrawRectangle(*c[:4]) # seen[c[4]]=True # # def chars(self, mode='L', cutoff=200): # return list(scrape.letters(self.im.convert(mode), cutoff)) def draw_baselines(self, baseline_color='#99CCFF', linegap_color='#eeeeee'): img_out = self.im dc = self.get_dc() y = 0 w, h = img_out.size for (top, base, bottom) in scrape.guess_lines(img_out): # draw the baseline dc.SetPen(wx.Pen(baseline_color)) if not base: base = bottom - 2 dc.SetPen(wx.RED_PEN) dc.DrawLines([(0, base), (w, base)]) # shade out the other stuff dc.SetPen(wx.Pen(linegap_color)) dc.SetBrush(wx.Brush(linegap_color)) dc.DrawRectangle(0, y, w, top - y) y = bottom # shade bottom area dc.DrawRectangle(0, y, w, h - y) def on_close_window(self, _evt): self.Destroy()
class AnonymizeDialog(wx.Dialog): """Dialog that shows the options to anonymize DICOM / DICOM RT data.""" def __init__(self): pre = wx.PreDialog() # the Create step is done by XRC. self.PostCreate(pre) def Init(self): """Method called after the dialog has been initialized.""" # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Initialize controls self.txtDICOMFolder = XRCCTRL(self, 'txtDICOMFolder') self.checkPatientName = XRCCTRL(self, 'checkPatientName') self.txtFirstName = XRCCTRL(self, 'txtFirstName') self.txtLastName = XRCCTRL(self, 'txtLastName') self.checkPatientID = XRCCTRL(self, 'checkPatientID') self.txtPatientID = XRCCTRL(self, 'txtPatientID') self.checkPrivateTags = XRCCTRL(self, 'checkPrivateTags') self.bmpError = XRCCTRL(self, 'bmpError') self.lblDescription = XRCCTRL(self, 'lblDescription') # Bind interface events to the proper methods wx.EVT_BUTTON(self, XRCID('btnFolderBrowse'), self.OnFolderBrowse) wx.EVT_CHECKBOX(self, XRCID('checkPatientName'), self.OnCheckPatientName) wx.EVT_CHECKBOX(self, XRCID('checkPatientID'), self.OnCheckPatientID) wx.EVT_BUTTON(self, wx.ID_OK, self.OnOK) # Set and bold the font of the description label if guiutil.IsMac(): font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) font.SetWeight(wx.FONTWEIGHT_BOLD) self.lblDescription.SetFont(font) # Initialize the import location via pubsub pub.subscribe(self.OnImportPrefsChange, 'general.dicom.import_location') pub.sendMessage('preferences.requested.value', 'general.dicom.import_location') # Pre-select the text on the text controls due to a Mac OS X bug self.txtFirstName.SetSelection(-1, -1) self.txtLastName.SetSelection(-1, -1) self.txtPatientID.SetSelection(-1, -1) # Load the error bitmap self.bmpError.SetBitmap(wx.Bitmap(util.GetResourcePath('error.png'))) # Initialize variables self.name = self.txtLastName.GetValue( ) + '^' + self.txtFirstName.GetValue() self.patientid = self.txtPatientID.GetValue() self.privatetags = True def OnImportPrefsChange(self, msg): """When the import preferences change, update the values.""" self.path = unicode(msg.data) self.txtDICOMFolder.SetValue(self.path) def OnFolderBrowse(self, evt): """Get the directory selected by the user.""" dlg = wx.DirDialog( self, defaultPath=self.path, message="Choose a folder to save the anonymized DICOM data...") if dlg.ShowModal() == wx.ID_OK: self.path = dlg.GetPath() self.txtDICOMFolder.SetValue(self.path) dlg.Destroy() def OnCheckPatientName(self, evt): """Enable or disable whether the patient's name is anonymized.""" self.txtFirstName.Enable(evt.IsChecked()) self.txtLastName.Enable(evt.IsChecked()) if not evt.IsChecked(): self.txtDICOMFolder.SetFocus() else: self.txtFirstName.SetFocus() self.txtFirstName.SetSelection(-1, -1) def OnCheckPatientID(self, evt): """Enable or disable whether the patient's ID is anonymized.""" self.txtPatientID.Enable(evt.IsChecked()) if not evt.IsChecked(): self.txtDICOMFolder.SetFocus() else: self.txtPatientID.SetFocus() self.txtPatientID.SetSelection(-1, -1) def OnOK(self, evt): """Return the options from the anonymize data dialog.""" # Patient name if self.checkPatientName.IsChecked(): self.name = self.txtLastName.GetValue() if len(self.txtFirstName.GetValue()): self.name = self.name + '^' + self.txtFirstName.GetValue() else: self.name = '' # Patient ID if self.checkPatientID.IsChecked(): self.patientid = self.txtPatientID.GetValue() else: self.patientid = '' # Private tags if self.checkPrivateTags.IsChecked(): self.privatetags = True else: self.privatetags = False self.EndModal(wx.ID_OK) def OnDestroy(self, evt): """Unbind to all events before the plugin is destroyed.""" pub.unsubscribe(self.OnImportPrefsChange, 'general.dicom.import_location') pub.unsubscribe(self.OnUpdatePatient, 'patient.updated.raw_data')
class AnonymizeDialog(wx.Dialog): """Dialog th # Changed foundstructure to fixed 'True' # I didn't understand the reason why RT Structure Set will be # set to 'not found' in this case. (Actually RT Structure has already been found by the above code.) # In this case, 'RT Plan' is not found, RT Structure Set in patient, and foundstructure = False. # Previous code: foundstructure = Falseat shows the options to anonymize DICOM / DICOM RT data.""" def __init__(self): wx.Dialog.__init__(self) def Init(self): """Method called after the dialog has been initialized.""" # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Initialize controls self.txtDICOMFolder = XRCCTRL(self, 'txtDICOMFolder') self.checkPatientName = XRCCTRL(self, 'checkPatientName') self.txtFirstName = XRCCTRL(self, 'txtFirstName') self.txtLastName = XRCCTRL(self, 'txtLastName') self.checkPatientID = XRCCTRL(self, 'checkPatientID') self.txtPatientID = XRCCTRL(self, 'txtPatientID') self.checkPrivateTags = XRCCTRL(self, 'checkPrivateTags') self.bmpError = XRCCTRL(self, 'bmpError') self.lblDescription = XRCCTRL(self, 'lblDescription') # Bind interface events to the proper methods wx.EVT_BUTTON(self, XRCID('btnFolderBrowse'), self.OnFolderBrowse) wx.EVT_CHECKBOX(self, XRCID('checkPatientName'), self.OnCheckPatientName) wx.EVT_CHECKBOX(self, XRCID('checkPatientID'), self.OnCheckPatientID) wx.EVT_BUTTON(self, wx.ID_OK, self.OnOK) # Set and bold the font of the description label if guiutil.IsMac(): font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) font.SetWeight(wx.FONTWEIGHT_BOLD) self.lblDescription.SetFont(font) # Initialize the import location via pubsub pub.subscribe(self.OnImportPrefsChange, 'general.dicom') pub.sendMessage('preferences.requested.values', msg='general.dicom') # Pre-select the text on the text controls due to a Mac OS X bug self.txtFirstName.SetSelection(-1, -1) self.txtLastName.SetSelection(-1, -1) self.txtPatientID.SetSelection(-1, -1) # Load the error bitmap self.bmpError.SetBitmap(wx.Bitmap(util.GetResourcePath('error.png'))) # Initialize variables self.name = self.txtLastName.GetValue( ) + '^' + self.txtFirstName.GetValue() self.patientid = self.txtPatientID.GetValue() self.privatetags = True def OnImportPrefsChange(self, topic, msg): """When the import preferences change, update the values.""" topic = topic.split('.') if (topic[1] == 'import_location'): self.path = str(msg) self.txtDICOMFolder.SetValue(self.path) def OnFolderBrowse(self, evt): """Get the directory selected by the user.""" dlg = wx.DirDialog( self, defaultPath=self.path, message="Choose a folder to save the anonymized DICOM data...") if dlg.ShowModal() == wx.ID_OK: self.path = dlg.GetPath() self.txtDICOMFolder.SetValue(self.path) dlg.Destroy() def OnCheckPatientName(self, evt): """Enable or disable whether the patient's name is anonymized.""" self.txtFirstName.Enable(evt.IsChecked()) self.txtLastName.Enable(evt.IsChecked()) if not evt.IsChecked(): self.txtDICOMFolder.SetFocus() else: self.txtFirstName.SetFocus() self.txtFirstName.SetSelection(-1, -1) def OnCheckPatientID(self, evt): """Enable or disable whether the patient's ID is anonymized.""" self.txtPatientID.Enable(evt.IsChecked()) if not evt.IsChecked(): self.txtDICOMFolder.SetFocus() else: self.txtPatientID.SetFocus() self.txtPatientID.SetSelection(-1, -1) def OnOK(self, evt): """Return the options from the anonymize data dialog.""" # Patient name if self.checkPatientName.IsChecked(): self.name = self.txtLastName.GetValue() if len(self.txtFirstName.GetValue()): self.name = self.name + '^' + self.txtFirstName.GetValue() else: self.name = '' # Patient ID if self.checkPatientID.IsChecked(): self.patientid = self.txtPatientID.GetValue() else: self.patientid = '' # Private tags if self.checkPrivateTags.IsChecked(): self.privatetags = True else: self.privatetags = False self.EndModal(wx.ID_OK)