def __init__(self, bin, obKey, images, chMap, selected=False, scale=1.0, brightness=1.0, contrast=None): ImagePanel.__init__(self, images, chMap, bin, scale=scale, brightness=brightness, contrast=contrast) self.SetDropTarget(ImageTileDropTarget(self)) self.bin = bin # the SortBin this object belongs to self.classifier = bin.classifier # Classifier needs to capture the mouse on tile selection self.obKey = obKey # (table, image, object) self.selected = selected # whether or not this tile is selected self.leftPressed = False self.showCenter = False self.popupMenu = None self.MapChannels(chMap) self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_LEFT_DCLICK, self.OnDClick) # Show images on double click self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) self.Bind(wx.EVT_MOTION, self.OnMotion) self.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseOver) self.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseOut) self.Bind(wx.EVT_PAINT, self.OnPaint)
def __init__(self, bin, obKey, images, chMap, selected=False, scale=1.0, brightness=1.0, contrast=None, display_whole_image=False): ImagePanel.__init__(self, images, chMap, bin, scale=scale, brightness=brightness, contrast=contrast, display_whole_image=display_whole_image) self.SetDropTarget(ImageTileDropTarget(self)) self.bin = bin # the SortBin this object belongs to self.classifier = bin.classifier # Classifier needs to capture the mouse on tile selection self.obKey = obKey # (table, image, object) self.selected = selected # whether or not this tile is selected self.leftPressed = False self.showCenter = False self.popupMenu = None self.cache = CellCache.getInstance() self.MapChannels(chMap) self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_LEFT_DCLICK, self.OnDClick) # Show images on double click self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) self.Bind(wx.EVT_MOTION, self.OnMotion) self.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseOver) self.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseOut) self.Bind(wx.EVT_PAINT, self.OnPaint)
def OnPaint(self, evt): dc = ImagePanel.OnPaint(self, evt) if self.showCenter: dc.BeginDrawing() dc.SetLogicalFunction(wx.XOR) dc.SetPen(wx.Pen("WHITE",1)) dc.SetBrush(wx.Brush("WHITE", style=wx.TRANSPARENT)) dc.DrawRectangle(self.bitmap.Width/2.-1, self.bitmap.Height/2.-1, 3, 3) dc.EndDrawing() return dc
def BuildFrame(self, show_xsections=True): sbar = self.CreateStatusBar(2, wx.CAPTION|wx.THICK_FRAME) sfont = sbar.GetFont() sfont.SetWeight(wx.BOLD) sfont.SetPointSize(12) sbar.SetFont(sfont) self.SetStatusWidths([-3, -1]) self.SetStatusText('', 0) self.BuildCustomMenus() self.BuildMenu() mainsizer = wx.BoxSizer(wx.HORIZONTAL) self.bgcol = rgb2hex(self.GetBackgroundColour()[:3]) self.panel = ImagePanel(self, data_callback=self.onDataChange, lasso_callback=self.onLasso) if self.config_on_frame: lpanel = self.BuildConfigPanel() mainsizer.Add(lpanel, 0, wx.LEFT|wx.ALIGN_LEFT|wx.TOP|wx.ALIGN_TOP|wx.EXPAND) # show_config_popup=(not self.config_on_frame), img_panel_extent = (2, 2) img_panel_locale = (0, 1) if not show_xsections: print 'Show Cross Sections' img_panel_extent = (1, 1) img_panel_locale = (1, 1) xtop = wx.StaticText(self, label='Top') xside = wx.StaticText(self, label='Side') xinfo = wx.StaticText(self, label='Info') mainsizer.Add(xtop, (0, 1), (1, 1), wx.EXPAND) mainsizer.Add(xinfo, (0, 2), (1, 1), wx.EXPAND) mainsizer.Add(xside, (1, 2), (1, 1), wx.EXPAND) self.panel.messenger = self.write_message self.panel.fig.set_facecolor(self.bgcol) mainsizer.Add(self.panel, 1, wx.EXPAND) self.BindMenuToPanel() mids = self.menuIDs self.Bind(wx.EVT_MENU, self.onCMapSave, id=mids.SAVE_CMAP) self.Bind(wx.EVT_MENU, self.onLogScale, id=mids.LOG_SCALE) self.SetAutoLayout(True) self.SetSizer(mainsizer) self.Fit()
def __init__(self, parent, wxapp, logger, config): wx.Frame.__init__(self, parent, title="wxFalsecolor - Radiance Picture Viewer") self._log = logger self.parser = WxfcOptionParser(logger=self._log) self._config = config self.wxapp = wxapp self.imagepanel = ImagePanel(self) self.rgbeImg = None self.img = None self.path = "" self.filename = "" self.loadingCanceled = False ## layout and show main window self._layout() #TODO: self._addMenu() self.Size = (800, 600) self.Show()
class WxfcFrame(wx.Frame): """main wxfalsecolor frame""" def __init__(self, parent, wxapp, logger, config): wx.Frame.__init__(self, parent, title="wxFalsecolor - Radiance Picture Viewer") self._log = logger self.parser = WxfcOptionParser(logger=self._log) self._config = config self.wxapp = wxapp self.imagepanel = ImagePanel(self) self.rgbeImg = None self.img = None self.path = "" self.filename = "" self.loadingCanceled = False ## layout and show main window self._layout() #TODO: self._addMenu() self.Size = (800, 600) self.Show() def process_cmd_line_args(self): """check arguments, load and convert image""" ## check command line args if self.parser.parseOptions(sys.argv[1:]) != True: self.showError(self.parser.error) return ## load image if present if self.parser.has_option('picture'): self.loadImage(self.parser.get('picture')) self.Update() if self.parser.has_fc_option() == True: self.doFalsecolor() def _addFileButtons(self, panel): """create top buttons""" self.loadButton = wx.Button(panel, wx.ID_ANY, label='open HDR') self.loadButton.Bind(wx.EVT_LEFT_DOWN, self.onLoadImage) self.panelSizer.Add(self.loadButton, proportion=0, flag=wx.EXPAND | wx.ALL, border=5) self.saveButton = wx.Button(panel, wx.ID_ANY, label='save image') self.saveButton.Bind(wx.EVT_LEFT_DOWN, self.onSaveImage) self.saveButton.Disable() self.panelSizer.Add(self.saveButton, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=5) spacepanel = wx.Panel(panel, wx.ID_ANY, size=(-1, 5)) self.panelSizer.Add(spacepanel, proportion=0, flag=wx.EXPAND) def _addMenu(self): """add menu to frame (disabled)""" return self.menubar = wx.MenuBar() self.SetMenuBar(self.menubar) self.fileMenu = wx.Menu() self.menubar.Append(self.file, '&File') self.fileOpen = self.file.Append(wx.ID_ANY, '&Open file') self.Bind(wx.EVT_MENU, self.onLoadImage, self.fileOpen) def _doButtonLayout(self): """create buttons""" panel = wx.Panel(self, style=wx.RAISED_BORDER) self.panelSizer = wx.BoxSizer(wx.VERTICAL) ## 'load' and 'save' buttons self._addFileButtons(panel) ## foldable controls panel self._foldpanel = FoldableControlsPanel(panel, self, wx.ID_ANY) self.lablecontrols = self._foldpanel.lablecontrols self.fccontrols = self._foldpanel.fccontrols self.displaycontrols = self._foldpanel.displaycontrols self.panelSizer.Add(self._foldpanel, proportion=1, flag=wx.EXPAND | wx.ALL, border=5) ## 'quit' button quitbutton = wx.Button(panel, wx.ID_EXIT, label='quit') quitbutton.Bind(wx.EVT_LEFT_DOWN, self.onQuit) self.panelSizer.Add(quitbutton, proportion=0, flag=wx.EXPAND | wx.ALL | wx.ALIGN_BOTTOM, border=10) panel.SetSizer(self.panelSizer) return panel def check_for_update(self, event=None): self.wxapp.check_for_update(event) def doFalsecolor(self, args=[]): """convert Radiance RGBE image to wx.Bitmap""" self._log.debug("doFalsecolor(%s)" % str(args)) if not args: args = self.parser.get_options_as_args() if "-nofc" in args or self.imagepanel.doFalsecolor(args[:]) == True: self.fccontrols.setFromArgs(args[:]) self.displaycontrols.reset() return True else: return False def doPcond(self, args): """apply pcond args to image""" if self.imagepanel.doPcond(args) == True: self.fccontrols.reset() return True else: return False def exit(self, error=None): """close logger and exit""" if error: self._log.error(str(error)) self._config.save_changes() logging.shutdown() self.Close() def expandControlPanel(self, idx): """expand control panel with index idx""" self._foldpanel.expand(idx) def formatNumber(self, n): """use FalsecolorImage formating for consistency""" if self.rgbeImg: return self.rgbeImg.formatNumber(n) else: return str(n) def getLableText(self): """return text of lable text box""" return self.lablecontrols.getLableText() def getRGBVAt(self, pos): """return pixel value at position""" if self.rgbeImg: return self.rgbeImg.getRGBVAt(pos) else: return (-1, -1, -1, -1) def getRGBVAverage(self, start, end): """return average pixel value for rectangle""" if self.rgbeImg: return self.rgbeImg.getRGBVAverage(start, end) else: return (-1, -1, -1, -1) def _layout(self): """main layout of controls and image panel""" ## buttons panel = self._doButtonLayout() ## image - buttons layout self.sizer = wx.BoxSizer(wx.HORIZONTAL) self.sizer.Add(panel, proportion=0, flag=wx.EXPAND) self.sizer.Add(self.imagepanel, proportion=1, flag=wx.EXPAND) self.SetSizer(self.sizer) ## status bar self.statusbar = SplitStatusBar(self) self.SetStatusBar(self.statusbar) def loadImage(self, path, args=[]): """create instance of falsecolor image from <path>""" self._log.info("loadImage(%s)" % path) self.reset() self.rgbeImg = RGBEImage(self, self._log, ["-i", path]) self.rgbeImg.readImageData(path) if self.rgbeImg.error: msg = "Error loading image:\n%s" % self.rgbeImg.error self.showError(msg) self.rgbeImg = None return False else: self.setPath(path) self.saveButton.Enable() self._loadImageData() self.imagepanel.update(self.rgbeImg) return True def _loadImageData(self): """load image data of small images immediately""" ## TODO: evaluate image data (exclude fc images) max_size = self._config.getint("lables", "max_data_load", 1000000) if max_size == 0: self._log.info("automatic data loading disabled") self.lablecontrols.reset() return ## compare image resolution against max_size x, y = self.rgbeImg.getImageResolution() if x * y <= max_size: ## call OnShowValues with fake event self.lablecontrols.OnShowValues(-1) else: self.statusbar.SetStatusText("confirm 'load data' or resize image") nx, ny = beautyscale(x, y, max_size) info = { 'x': x, 'y': y, 'new_x': nx, 'new_y': ny, 'backup_name': self.rgbeImg.getBackupName(), 'do_resize': False } dlg = ResizeDialog(parent=self, ID=-1, title="foo") dlg.setImageInfo(info) result = dlg.ShowModal() if result == wx.ID_OK: if dlg.cb_resize.IsChecked(): self.resizeRGBEImage(dlg) else: self._log.info("loading original image data") self.lablecontrols.OnShowValues(-1) else: self._log.info("loading of image data cancelled by user") self.lablecontrols.reset() self.statusbar.SetStatusText("skipping 'load data'.") dlg.Destroy() #msg = "This is a large image.\nDo you want to load image data now?" #dlg = wx.MessageDialog(self, message=msg, caption="Load data?", style=wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION) #if dlg.ShowModal() == wx.ID_YES: #else: def loadValues(self): """load luminance/illuminance data from image""" return self.rgbeImg.hasArrayData(self) def onImagePanelClick(self): """action on click on imagepanel""" if self.imagepanel.hasLables(): self.lablecontrols.loadClearButton.Enable() elif self.lablecontrols.loadClearButton.GetLabelText() == "load data": self.lablecontrols.loadClearButton.Enable() else: self.lablecontrols.loadClearButton.Disable() def onLoadImage(self, event): """load new Radiance RGBE image""" filedialog = wx.FileDialog( self, message='Choose an image to open', defaultDir='', defaultFile='', wildcard= 'Radiance Image Files (*.hdr,*.pic)|*.hdr;*.pic|all files |*.*', style=wx.OPEN) if filedialog.ShowModal() == wx.ID_OK: path = filedialog.GetPath() self.loadImage(path) def onQuit(self, event): """hasta la vista""" self.exit() def onSaveImage(self, event): """save bmp image to file""" dirname, filename = os.path.split(self.path) filebase = os.path.splitext(filename)[0] #formats = "|".join(["HDR file|*.hdr", WX_IMAGE_WILDCARD, "PIC (old)|*.pic"]) formats = "|".join( ["HDR file|*.hdr", WX_IMAGE_WILDCARD, "PPM file|*.ppm"]) filedialog = wx.FileDialog(self, message='save image', defaultDir=dirname, defaultFile=filebase + '.hdr', wildcard=formats, style=wx.SAVE) if filedialog.ShowModal() == wx.ID_OK: path = filedialog.GetPath() result = self.rgbeImg.saveToFile(path) if result != True: msg = "Error saving image:\n" + self.rgbeImg.error self.showError(msg) else: self.statusbar.SetStatusText("saved file '%s'" % path) def reset(self): """reset array to inital (empty) values""" self.displaycontrols.reset() self.imagepanel.clearLabels() self.fccontrols.reset() if self.rgbeImg: self.imagepanel.update(self.rgbeImg) if self.rgbeImg.isIrridiance(): self.fccontrols.reset("Lux") def resizeRGBEImage(self, dlg): """create backup copy, resize and save image""" w = int(dlg.img_width.GetValue()) h = int(dlg.img_height.GetValue()) backup = dlg.img_backup.GetValue() self._log.info("resizing image: w=%d, h=%d, backup='%s'" % (w, h, backup)) if backup != "": self.rgbeImg.saveToFile(backup) self.rgbeImg.resize(w, h) if self.rgbeImg.hasFilepath(): self.rgbeImg.saveToFile(self.rgbeImg.picture) self.rgbeImg.readImageData(self.rgbeImg.picture) def setPath(self, path): """update frame with new image path""" self.path = path self.filename = os.path.split(path)[1] self.SetTitle("wxFalsecolor - '%s'" % self.filename) def showAboutDialog(self, event=None): """show dialog with license etc""" info = wx.AboutDialogInfo() info.Name = "wxfalsecolor" info.Version = "%s" % VERSION info.Copyright = "(c) 2015 Thomas Bleicher" info.Description = "cross-platform GUI frontend for falsecolor" info.WebSite = ("http://tbleicher.github.io/wxfalsecolor/", "wxfalsecolor home page") info.Developers = ["Thomas Bleicher", "Axel Jacobs"] lines = [" ".join(line.split()) for line in LICENSE.split("\n\n")] info.License = wordwrap("\n\n".join(lines), 500, wx.ClientDC(self)) wx.AboutBox(info) def showError(self, msg): """show dialog with error message""" self._log.error(" ".join(msg.split())) self.statusbar.SetStatusText(msg) dlg = wx.MessageDialog(self, message=msg, caption="Error", style=wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() def showHeaders(self, event=None): """display image headers in popup dialog""" if not self.rgbeImg: return header = self.rgbeImg.getHeader() if header == False: self.showError("Image header not available!") return header2 = self.rgbeImg.getDataHeader() if header2 and header != header2: header += "\n\nmodified:\n" header += header2 ## create new dialog window dlg = HeaderDialog(self, header) dlg.Show() def showPixelValueAt(self, pos): """set pixel position of mouse cursor""" value = "" if self.rgbeImg: r, g, b, v = self.rgbeImg.getRGBVAt(pos) if r > 0: value = "rgb=(%.3f,%.3f,%.3f)" % (r, g, b) if v > 0 and self.rgbeImg.isIrridiance(): value = "%s value=%s lux" % (value, self.formatNumber(v)) self.statusbar.SetStatusText( "'%s': x,y=(%d,%d) %s" % (self.filename, pos[0], pos[1], value))
class ImageFrame(BaseFrame): """ MatPlotlib Image Display ons a wx.Frame, using ImagePanel """ def __init__(self, parent=None, size=(550, 450), config_on_frame=True, lasso_callback=None, show_xsections=True, output_title='Image', **kws): self.config_on_frame = config_on_frame self.lasso_callback = lasso_callback BaseFrame.__init__(self, parent=parent, title = 'Image Display Frame', size=size, **kws) self.BuildFrame(show_xsections=show_xsections) def display(self, img, title=None, colormap=None, **kw): """plot after clearing current plot """ if title is not None: self.SetTitle(title) self.panel.display(img, **kw) if colormap is not None: self.set_colormap(colormap) def BuildCustomMenus(self): "build menus" mids = self.menuIDs mids.SAVE_CMAP = wx.NewId() mids.LOG_SCALE = wx.NewId() mids.FLIP_H = wx.NewId() mids.FLIP_V = wx.NewId() mids.FLIP_O = wx.NewId() mids.ROT_CW = wx.NewId() mids.CUR_ZOOM = wx.NewId() mids.CUR_LASSO = wx.NewId() mids.CUR_PROF = wx.NewId() m = wx.Menu() m.Append(mids.UNZOOM, "Zoom Out\tCtrl+Z", "Zoom out to full data range") m.Append(mids.SAVE_CMAP, "Save Image of Colormap") m.AppendSeparator() m.Append(mids.LOG_SCALE, "Log Scale Intensity\tCtrl+L", "", wx.ITEM_CHECK) m.Append(mids.ROT_CW, 'Rotate clockwise\tCtrl+R', '') m.Append(mids.FLIP_V, 'Flip Top/Bottom\tCtrl+T', '') m.Append(mids.FLIP_H, 'Flip Left/Right\tCtrl+F', '') # m.Append(mids.FLIP_O, 'Flip to Original', '') m.AppendSeparator() m.AppendRadioItem(mids.CUR_ZOOM, 'Cursor Mode: Zoom to Box\tCtrl+B', 'Left-Drag Cursor to zoom to box') m.AppendRadioItem(mids.CUR_PROF, 'Cursor Mode: Profile\tCtrl+K', 'Left-Drag Cursor to select cut for profile') m.AppendRadioItem(mids.CUR_LASSO, 'Cursor Mode: Lasso\tCtrl+N', 'Left-Drag Cursor to select points') m.AppendSeparator() self.Bind(wx.EVT_MENU, self.onFlip, id=mids.FLIP_H) self.Bind(wx.EVT_MENU, self.onFlip, id=mids.FLIP_V) self.Bind(wx.EVT_MENU, self.onFlip, id=mids.FLIP_O) self.Bind(wx.EVT_MENU, self.onFlip, id=mids.ROT_CW) self.Bind(wx.EVT_MENU, self.onCursorMode, id=mids.CUR_ZOOM) self.Bind(wx.EVT_MENU, self.onCursorMode, id=mids.CUR_PROF) self.Bind(wx.EVT_MENU, self.onCursorMode, id=mids.CUR_LASSO) sm = wx.Menu() for itype in Interp_List: wid = wx.NewId() sm.AppendRadioItem(wid, itype, itype) self.Bind(wx.EVT_MENU, Closure(self.onInterp, name=itype), id=wid) self.user_menus = [('&Options', m), ('Smoothing', sm)] def onInterp(self, evt=None, name=None): if name not in Interp_List: name = Interp_List[0] self.panel.conf.interp = name self.panel.redraw() def onCursorMode(self, event=None): conf = self.panel.conf wid = event.GetId() conf.cursor_mode = 'zoom' if wid == self.menuIDs.CUR_PROF: conf.cursor_mode = 'profile' elif wid == self.menuIDs.CUR_LASSO: conf.cursor_mode = 'lasso' def onFlip(self, event=None): conf = self.panel.conf wid = event.GetId() mids = self.menuIDs if wid == mids.FLIP_H: conf.flip_lr = not conf.flip_lr elif wid == mids.FLIP_V: conf.flip_ud = not conf.flip_ud elif wid == mids.FLIP_O: conf.flip_lr, conf.flip_ud = False, False elif wid == mids.ROT_CW: conf.rot = True self.panel.unzoom_all() def BuildFrame(self, show_xsections=True): sbar = self.CreateStatusBar(2, wx.CAPTION|wx.THICK_FRAME) sfont = sbar.GetFont() sfont.SetWeight(wx.BOLD) sfont.SetPointSize(12) sbar.SetFont(sfont) self.SetStatusWidths([-3, -1]) self.SetStatusText('', 0) self.BuildCustomMenus() self.BuildMenu() mainsizer = wx.BoxSizer(wx.HORIZONTAL) self.bgcol = rgb2hex(self.GetBackgroundColour()[:3]) self.panel = ImagePanel(self, data_callback=self.onDataChange, lasso_callback=self.onLasso) if self.config_on_frame: lpanel = self.BuildConfigPanel() mainsizer.Add(lpanel, 0, wx.LEFT|wx.ALIGN_LEFT|wx.TOP|wx.ALIGN_TOP|wx.EXPAND) # show_config_popup=(not self.config_on_frame), img_panel_extent = (2, 2) img_panel_locale = (0, 1) if not show_xsections: print 'Show Cross Sections' img_panel_extent = (1, 1) img_panel_locale = (1, 1) xtop = wx.StaticText(self, label='Top') xside = wx.StaticText(self, label='Side') xinfo = wx.StaticText(self, label='Info') mainsizer.Add(xtop, (0, 1), (1, 1), wx.EXPAND) mainsizer.Add(xinfo, (0, 2), (1, 1), wx.EXPAND) mainsizer.Add(xside, (1, 2), (1, 1), wx.EXPAND) self.panel.messenger = self.write_message self.panel.fig.set_facecolor(self.bgcol) mainsizer.Add(self.panel, 1, wx.EXPAND) self.BindMenuToPanel() mids = self.menuIDs self.Bind(wx.EVT_MENU, self.onCMapSave, id=mids.SAVE_CMAP) self.Bind(wx.EVT_MENU, self.onLogScale, id=mids.LOG_SCALE) self.SetAutoLayout(True) self.SetSizer(mainsizer) self.Fit() def BuildConfigPanel(self): """config panel for left-hand-side of frame""" conf = self.panel.conf lpanel = wx.Panel(self) lsizer = wx.GridBagSizer(7, 4) labstyle = wx.ALIGN_LEFT|wx.LEFT|wx.TOP|wx.EXPAND # interp_choice = wx.Choice(lpanel, choices=Interp_List) # interp_choice.Bind(wx.EVT_CHOICE, self.onInterp) s = wx.StaticText(lpanel, label=' Color Table:', size=(100, -1)) s.SetForegroundColour('Blue') lsizer.Add(s, (0, 0), (1, 3), labstyle, 5) cmap_choice = wx.Choice(lpanel, choices=ColorMap_List) cmap_choice.Bind(wx.EVT_CHOICE, self.onCMap) cmap_name = conf.cmap.name if cmap_name.endswith('_r'): cmap_name = cmap_name[:-2] cmap_choice.SetStringSelection(cmap_name) self.cmap_choice = cmap_choice cmap_reverse = wx.CheckBox(lpanel, label='Reverse Table', size=(140, -1)) cmap_reverse.Bind(wx.EVT_CHECKBOX, self.onCMapReverse) cmap_reverse.SetValue(conf.cmap_reverse) self.cmap_reverse = cmap_reverse cmax = conf.cmap_range self.cmap_data = numpy.outer(numpy.linspace(0, 1, cmax), numpy.ones(cmax/4)) self.cmap_fig = Figure((0.80, 1.0), dpi=100) self.cmap_axes = self.cmap_fig.add_axes([0, 0, 1, 1]) self.cmap_axes.set_axis_off() self.cmap_canvas = FigureCanvasWxAgg(lpanel, -1, figure=self.cmap_fig) self.bgcol = rgb2hex(lpanel.GetBackgroundColour()[:3]) self.cmap_fig.set_facecolor(self.bgcol) self.cmap_image = self.cmap_axes.imshow(self.cmap_data, cmap=conf.cmap, interpolation='bilinear') self.cmap_axes.set_ylim((0, cmax), emit=True) self.cmap_lo_val = wx.Slider(lpanel, -1, conf.cmap_lo, 0, conf.cmap_range, size=(-1, 180), style=wx.SL_INVERSE|wx.SL_VERTICAL) self.cmap_hi_val = wx.Slider(lpanel, -1, conf.cmap_hi, 0, conf.cmap_range, size=(-1, 180), style=wx.SL_INVERSE|wx.SL_VERTICAL) self.cmap_lo_val.Bind(wx.EVT_SCROLL, self.onStretchLow) self.cmap_hi_val.Bind(wx.EVT_SCROLL, self.onStretchHigh) iauto_toggle = wx.CheckBox(lpanel, label='Autoscale Intensity?', size=(160, -1)) iauto_toggle.Bind(wx.EVT_CHECKBOX, self.onInt_Autoscale) iauto_toggle.SetValue(conf.auto_intensity) lsizer.Add(self.cmap_choice, (1, 0), (1, 4), labstyle, 2) lsizer.Add(self.cmap_reverse, (2, 0), (1, 4), labstyle, 5) lsizer.Add(self.cmap_lo_val, (3, 0), (1, 1), labstyle, 5) lsizer.Add(self.cmap_canvas, (3, 1), (1, 2), wx.ALIGN_CENTER|labstyle) lsizer.Add(self.cmap_hi_val, (3, 3), (1, 1), labstyle, 5) lsizer.Add(iauto_toggle, (4,0), (1,4), labstyle) self.imin_val = LabelEntry(lpanel, conf.int_lo, size=40, labeltext='I min:', action = Closure(self.onThreshold, argu='lo')) self.imax_val = LabelEntry(lpanel, conf.int_hi, size=40, labeltext='I max:', action = Closure(self.onThreshold, argu='hi')) self.imax_val.Disable() self.imin_val.Disable() lsizer.Add(self.imin_val.label, (5, 0), (1, 1), labstyle, 5) lsizer.Add(self.imax_val.label, (6, 0), (1, 1), labstyle, 5) lsizer.Add(self.imin_val, (5, 1), (1, 2), labstyle, 5) lsizer.Add(self.imax_val, (6, 1), (1, 2), labstyle, 5) lpanel.SetSizer(lsizer) lpanel.Fit() return lpanel def onCMap(self, event=None): self.set_colormap(event.GetString()) def onLasso(self, data=None, selected=None, mask=None, **kw): print 'lasso:' , selected[:10] if hasattr(self.lasso_callback , '__call__'): self.lasso_callback(data=conf.data, selected=sel, mask=mask) def onDataChange(self, data, x=None, y=None, **kw): imin, imax = data.min(), data.max() self.imin_val.SetValue("%.4g" % imin) self.imax_val.SetValue("%.4g" % imax) self.panel.conf.int_lo = imin self.panel.conf.int_hi = imax def onThreshold(self, event=None, argu='hi'): if (wx.EVT_TEXT_ENTER.evtType[0] == event.GetEventType()): try: val = float(str(event.GetString()).strip()) except: return elif (wx.EVT_KILL_FOCUS.evtType[0] == event.GetEventType()): val = float(self.imax_val.GetValue()) if argu == 'lo': val = float(self.imin_val.GetValue()) if argu == 'lo': self.panel.conf.int_lo = val else: self.panel.conf.int_hi = val self.panel.redraw() def onInt_Autoscale(self, event=None): val = self.panel.conf.auto_intensity = event.IsChecked() if val: try: self.onDataChange(self.panel.conf.data) except: pass self.imax_val.Disable() self.imin_val.Disable() else: self.imax_val.Enable() self.imin_val.Enable() self.panel.redraw() def onCMapReverse(self, event=None): self.panel.conf.cmap_reverse = event.IsChecked() try: cmap_name = self.panel.conf.cmap.name if cmap_name.endswith('_r'): cmap_name = cmap_name[:-2] self.set_colormap(cmap_name) except: pass def set_colormap(self, cmap_name, reverse=None): conf = self.panel.conf if reverse is None: reverse = conf.cmap_reverse self.cmap_reverse.SetValue(0) if reverse: cmap_name = cmap_name + '_r' self.cmap_reverse.SetValue(1) this_cmap_name =self.cmap_choice.GetStringSelection() if cmap_name != this_cmap_name: self.cmap_choice.SetStringSelection(cmap_name) conf.cmap = getattr(colormap, cmap_name) self.redraw_cmap() def redraw_cmap(self): conf = self.panel.conf if not hasattr(conf, 'image'): return conf.image.set_cmap(conf.cmap) self.cmap_image.set_cmap(conf.cmap) lo = conf.cmap_lo hi = conf.cmap_hi cmax = 1.0 * conf.cmap_range wid = numpy.ones(cmax/4) self.cmap_data[:lo, :] = 0 self.cmap_data[lo:hi] = numpy.outer(numpy.linspace(0., 1., hi-lo), wid) self.cmap_data[hi:, :] = 1 self.cmap_image.set_data(self.cmap_data) self.cmap_canvas.draw() self.panel.redraw() def onStretchLow(self, event=None): self.StretchCMap(event.GetInt(), self.cmap_hi_val.GetValue()) def onStretchHigh(self, event=None): self.StretchCMap(self.cmap_lo_val.GetValue(), event.GetInt()) def StretchCMap(self, low, high): lo, hi = min(low, high), max(low, high) if (hi-lo)<2: hi = min(hi, self.panel.conf.cmap_range) lo = max(lo, 0) self.cmap_lo_val.SetValue(lo) self.cmap_hi_val.SetValue(hi) self.panel.conf.cmap_lo = lo self.panel.conf.cmap_hi = hi self.redraw_cmap() def onLogScale(self, event=None): self.panel.conf.log_scale = not self.panel.conf.log_scale self.panel.redraw() def onCMapSave(self, event=None): """save color table image""" file_choices = "PNG (*.png)|*.png" ofile = 'Colormap.png' dlg = wx.FileDialog(self, message='Save Colormap as...', defaultDir = os.getcwd(), defaultFile=ofile, wildcard=file_choices, style=wx.SAVE|wx.CHANGE_DIR) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() self.cmap_canvas.print_figure(path, dpi=300)
def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) self.SetSize((400, 300)) # Menu Bar self.frame_menubar = wx.MenuBar() wxglade_tmp_menu = wx.Menu() wxglade_tmp_menu.Append(wx.ID_SAVE, "Screenshot", "") self.Bind(wx.EVT_MENU, self.OnSave, id=wx.ID_SAVE) wxglade_tmp_menu.Append(wx.ID_EXIT, "Quit", "") self.Bind(wx.EVT_MENU, self.OnQuit, id=wx.ID_EXIT) self.frame_menubar.Append(wxglade_tmp_menu, "File") self.SetMenuBar(self.frame_menubar) # Menu Bar end self.sim_image = ImagePanel(self, wx.ID_ANY) self.sim = Sim() self.single_click = wx.Button(self, wx.ID_ANY, "Single") self.double_click = wx.Button(self, wx.ID_ANY, "Double") self.single_click_copy_1 = wx.Button(self, wx.ID_ANY, "Long") self.down_flip = wx.Button(self, wx.ID_ANY, "Down") self.up_flip = wx.Button(self, wx.ID_ANY, "Up") self.left_flip = wx.Button(self, wx.ID_ANY, "Left") self.right_flip = wx.Button(self, wx.ID_ANY, "Right") self.azimuth = wx.Slider(self, wx.ID_ANY, 0, 0, 359, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.inclination = wx.Slider(self, wx.ID_ANY, 0, -90, 90, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.roll = wx.Slider(self, wx.ID_ANY, 0, -180, 180, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.__set_properties() self.__do_layout() self.Bind(wx.EVT_BUTTON, lambda evt: self.sim.set_input(Input.SINGLE_CLICK), self.single_click) self.Bind(wx.EVT_BUTTON, lambda evt: self.sim.set_input(Input.DOUBLE_CLICK), self.double_click) self.Bind(wx.EVT_BUTTON, lambda evt: self.sim.set_input(Input.LONG_CLICK), self.single_click_copy_1) self.Bind(wx.EVT_BUTTON, lambda evt: self.sim.set_input(Input.FLIP_DOWN), self.down_flip) self.Bind(wx.EVT_BUTTON, lambda evt: self.sim.set_input(Input.FLIP_UP), self.up_flip) self.Bind(wx.EVT_BUTTON, lambda evt: self.sim.set_input(Input.FLIP_LEFT), self.left_flip) self.Bind(wx.EVT_BUTTON, lambda evt: self.sim.set_input(Input.FLIP_RIGHT), self.right_flip) self.Bind(wx.EVT_COMMAND_SCROLL, self.orientation_changed, self.azimuth) self.Bind(wx.EVT_COMMAND_SCROLL, self.orientation_changed, self.inclination) self.Bind(wx.EVT_COMMAND_SCROLL, self.orientation_changed, self.roll)
class MyFrame(wx.Frame): def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) self.SetSize((400, 300)) # Menu Bar self.frame_menubar = wx.MenuBar() wxglade_tmp_menu = wx.Menu() wxglade_tmp_menu.Append(wx.ID_SAVE, "Screenshot", "") self.Bind(wx.EVT_MENU, self.OnSave, id=wx.ID_SAVE) wxglade_tmp_menu.Append(wx.ID_EXIT, "Quit", "") self.Bind(wx.EVT_MENU, self.OnQuit, id=wx.ID_EXIT) self.frame_menubar.Append(wxglade_tmp_menu, "File") self.SetMenuBar(self.frame_menubar) # Menu Bar end self.sim_image = ImagePanel(self, wx.ID_ANY) self.sim = Sim() self.single_click = wx.Button(self, wx.ID_ANY, "Single") self.double_click = wx.Button(self, wx.ID_ANY, "Double") self.single_click_copy_1 = wx.Button(self, wx.ID_ANY, "Long") self.down_flip = wx.Button(self, wx.ID_ANY, "Down") self.up_flip = wx.Button(self, wx.ID_ANY, "Up") self.left_flip = wx.Button(self, wx.ID_ANY, "Left") self.right_flip = wx.Button(self, wx.ID_ANY, "Right") self.azimuth = wx.Slider(self, wx.ID_ANY, 0, 0, 359, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.inclination = wx.Slider(self, wx.ID_ANY, 0, -90, 90, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.roll = wx.Slider(self, wx.ID_ANY, 0, -180, 180, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.__set_properties() self.__do_layout() self.Bind(wx.EVT_BUTTON, lambda evt: self.sim.set_input(Input.SINGLE_CLICK), self.single_click) self.Bind(wx.EVT_BUTTON, lambda evt: self.sim.set_input(Input.DOUBLE_CLICK), self.double_click) self.Bind(wx.EVT_BUTTON, lambda evt: self.sim.set_input(Input.LONG_CLICK), self.single_click_copy_1) self.Bind(wx.EVT_BUTTON, lambda evt: self.sim.set_input(Input.FLIP_DOWN), self.down_flip) self.Bind(wx.EVT_BUTTON, lambda evt: self.sim.set_input(Input.FLIP_UP), self.up_flip) self.Bind(wx.EVT_BUTTON, lambda evt: self.sim.set_input(Input.FLIP_LEFT), self.left_flip) self.Bind(wx.EVT_BUTTON, lambda evt: self.sim.set_input(Input.FLIP_RIGHT), self.right_flip) self.Bind(wx.EVT_COMMAND_SCROLL, self.orientation_changed, self.azimuth) self.Bind(wx.EVT_COMMAND_SCROLL, self.orientation_changed, self.inclination) self.Bind(wx.EVT_COMMAND_SCROLL, self.orientation_changed, self.roll) # end wxGlade def __set_properties(self): # begin wxGlade: MyFrame.__set_properties self.SetTitle("frame") # end wxGlade def __do_layout(self): # begin wxGlade: MyFrame.__do_layout sizer_2 = wx.BoxSizer(wx.VERTICAL) sizer_3 = wx.BoxSizer(wx.HORIZONTAL) sizer_6 = wx.StaticBoxSizer( wx.StaticBox(self, wx.ID_ANY, "Orientation"), wx.HORIZONTAL) grid_sizer_1 = wx.FlexGridSizer(3, 2, 0, 4) sizer_5 = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, "Flip"), wx.VERTICAL) sizer_4 = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, "Button"), wx.VERTICAL) sizer_2.Add(self.sim_image, 1, wx.EXPAND, 0) sizer_4.Add(self.single_click, 0, wx.ALIGN_CENTER | wx.ALL, 2) sizer_4.Add(self.double_click, 0, wx.ALIGN_CENTER | wx.ALL, 2) sizer_4.Add(self.single_click_copy_1, 0, wx.ALIGN_CENTER | wx.ALL, 2) sizer_3.Add(sizer_4, 0, wx.ALL | wx.EXPAND, 2) sizer_5.Add(self.down_flip, 0, wx.ALIGN_CENTER | wx.ALL, 2) sizer_5.Add(self.up_flip, 0, wx.ALIGN_CENTER | wx.ALL, 2) sizer_5.Add(self.left_flip, 0, wx.ALIGN_CENTER | wx.ALL, 2) sizer_5.Add(self.right_flip, 0, wx.ALIGN_CENTER | wx.ALL, 2) sizer_3.Add(sizer_5, 0, wx.ALL | wx.EXPAND, 2) label_1 = wx.StaticText(self, wx.ID_ANY, "Azimuth:", style=wx.ALIGN_RIGHT) grid_sizer_1.Add(label_1, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 0) grid_sizer_1.Add(self.azimuth, 0, wx.ALL | wx.EXPAND, 0) label_2 = wx.StaticText(self, wx.ID_ANY, "Inclination:", style=wx.ALIGN_RIGHT) grid_sizer_1.Add(label_2, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 0) grid_sizer_1.Add(self.inclination, 0, wx.ALL | wx.EXPAND, 0) label_3 = wx.StaticText(self, wx.ID_ANY, "Roll:", style=wx.ALIGN_RIGHT) grid_sizer_1.Add(label_3, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 0) grid_sizer_1.Add(self.roll, 0, wx.ALL | wx.EXPAND, 0) grid_sizer_1.AddGrowableCol(1) sizer_6.Add(grid_sizer_1, 1, wx.ALL | wx.EXPAND, 3) sizer_3.Add(sizer_6, 4, wx.ALL, 2) sizer_2.Add(sizer_3, 0, wx.EXPAND, 0) self.SetSizer(sizer_2) self.Layout() # end wxGlade def orientation_changed(self, event): # wxGlade: MyFrame.<event_handler> self.sim.sensor.set_orientation(self.azimuth.GetValue(), self.inclination.GetValue(), self.roll.GetValue()) def message_handler(self, message): result = self.sim.handleMessage(message) if message[0:2] == [0x01, 0x78]: self.sim_image.paintNow(self.sim.get_image()) return result def OnSave(self, event): # wxGlade: MyFrame.<event_handler> fname = "screenshot.png" self.sim.get_image().save(fname, "PNG") def OnQuit(self, event): # wxGlade: MyFrame.<event_handler> self.Close()