def __init__(self, *args, **kw): super(SampleImageTask, self).__init__(*args, **kw) if self.manager: self.tool_bars[0].items.append(DBSnapshotAction()) self.camera = ToupCamCamera() self.filter_non_run_samples = False
class SampleImageTask(BaseEditorTask, BaseBrowserModel): name = 'Sample Imager' id = 'pychron.image.sample_imager' tool_bars = [SToolBar(SnapshotAction()), SToolBar(UploadAction())] save_event = Event images = List selected_image = Instance(SampleImageRecordView) selected_info_model = Instance(ImageModel, ()) dclicked = Event _prev_name = None def __init__(self, *args, **kw): super(SampleImageTask, self).__init__(*args, **kw) if self.manager: self.tool_bars[0].items.append(DBSnapshotAction()) self.camera = ToupCamCamera() self.filter_non_run_samples = False def save(self, path=None): if self.active_editor and isinstance(self.active_editor, ImageTabEditor): if self.active_editor.dirty: db = self.manager.db dbim = db.get_sample_image(self.active_editor.record_id) dbim.note = self.active_editor.model.note dbim.name = self.active_editor.model.name db.commit() self.active_editor.model.original_note = dbim.note self.active_editor.model.original_name = dbim.name self.active_editor.dirty = False self._load_associated_images(self.selected_samples) def save_as(self): self.save() # actions def upload_image_from_file(self): if not self.selected_samples: self.information_dialog('Please select a sample to associate with the image') return path = self.open_file_dialog(default_directory=os.path.expanduser('~'), wildcard='*.jpg|*.jpeg') if path is not None: with open(path, 'rb') as rfile: self.save_db_snapshot(rfile.read()) self._load_associated_images(self.selected_samples) def save_file_snapshot(self): from pychron.core.helpers.filetools import unique_path2 p, _ = unique_path2(paths.sample_image_dir, 'nosample', extension='.jpg') p, _ = unique_path2(paths.sample_image_dir, 'nosample', extension='.tiff') self.camera.save(p) def save_db_snapshot(self, blob=None): if not self.selected_samples: self.warning_dialog('Please select a sample') return sample = self.selected_samples[0] self.info('adding image to sample. name={}, identifier={}'.format(sample.name, sample.identifier)) name = self._prev_name if not name: # get existing images for this sample db = self.manager.db # sample = db.get_sample(sample.name, identifier=sample.identifier) cnt = db.get_sample_image_count(sample.name, project=sample.project, material=sample.material, identifier=sample.identifier) cnt += 1 name = '{}{:03d}'.format(sample.name, cnt) v = DBSaveView(name=name) info = v.edit_traits() if info.result: self._prev_name = v.name self.debug('save image with name={}'.format(name)) if blob is None: blob = self.camera.get_jpeg_data(quality=75) db.add_sample_image(sample.name, v.name, blob, v.note, identifier=sample.identifier) # task interface def activated(self): self.camera.open() editor = CameraTab(model=self, name='Camera') self._open_editor(editor) self.load_projects(include_recent=False) def prepare_destroy(self): self.camera.close() def create_dock_panes(self): return [SampleBrowserPane(model=self), InfoPane(model=self)] def _selected_projects_changed(self, old, new): if new and self.project_enabled: names = [ni.name for ni in new] self.debug('selected projects={}'.format(names)) # self._load_associated_labnumbers(names) self._load_associated_samples(names) self.dump_browser_selection() def _selected_samples_changed(self, new): if new: self._load_associated_images(new) # def _selected_image_changed(self, new): def _dclicked_changed(self): selected = self.selected_image if selected: db = self.manager.db dbim = db.get_sample_image(selected.record_id) editor = self.get_editor(selected.record_id, key='record_id') if not editor: model = ImageModel(blob=dbim.image, name=dbim.name, create_date=dbim.create_date, note=dbim.note or '') editor = ImageTabEditor(record_id=selected.record_id, model=model, name=dbim.name) self._open_editor(editor) else: self.activate_editor(editor) def _active_editor_changed(self, new): if new and isinstance(new.model, ImageModel): self.selected_info_model = new.model def _load_associated_images(self, sample_records): db = self.manager.db images = [] for si in sample_records: sample = db.get_sample(si.name, si.project, si.material, si.identifier) images.extend([SampleImageRecordView(i) for i in sample.images]) self.images = images def _load_associated_samples(self, names): db = self.manager.db samples = db.get_samples(names) self.debug('get samples n={}'.format(len(samples))) def func(li, prog, i, n): if prog: prog.change_message('Loading Sample {}'.format(li.name)) if li.labnumbers: return [SampleRecordView(li, identifier=ll.identifier) for ll in li.labnumbers] else: return SampleRecordView(li) samples = progress_loader(samples, func) self.samples = samples self.osamples = samples def _default_layout_default(self): return TaskLayout(left=PaneItem(id='pychron.image.browser'), right=PaneItem(id='pychron.image.info'))
class SampleImageTask(BaseEditorTask, BaseBrowserModel): name = 'Sample Imager' id = 'pychron.image.sample_imager' tool_bars = [SToolBar(SnapshotAction()), SToolBar(UploadAction())] save_event = Event images = List selected_image = Instance(SampleImageRecordView) selected_info_model = Instance(ImageModel, ()) dclicked = Event _prev_name = None def __init__(self, *args, **kw): super(SampleImageTask, self).__init__(*args, **kw) if self.manager: self.tool_bars[0].items.append(DBSnapshotAction()) self.camera = ToupCamCamera() self.filter_non_run_samples = False def save(self, path=None): if self.active_editor and isinstance(self.active_editor, ImageTabEditor): if self.active_editor.dirty: db = self.manager.db with db.session_ctx(): dbim = db.get_sample_image(self.active_editor.record_id) dbim.note = self.active_editor.model.note dbim.name = self.active_editor.model.name self.active_editor.model.original_note = dbim.note self.active_editor.model.original_name = dbim.name self.active_editor.dirty = False self._load_associated_images(self.selected_samples) def save_as(self): self.save() # actions def upload_image_from_file(self): if not self.selected_samples: self.information_dialog( 'Please select a sample to associate with the image') return path = self.open_file_dialog(default_directory=os.path.expanduser('~'), wildcard='*.jpg|*.jpeg') if path is not None: with open(path, 'rb') as rfile: self.save_db_snapshot(rfile.read()) self._load_associated_images(self.selected_samples) def save_file_snapshot(self): from pychron.core.helpers.filetools import unique_path2 p, _ = unique_path2(paths.sample_image_dir, 'nosample', extension='.jpg') p, _ = unique_path2(paths.sample_image_dir, 'nosample', extension='.tiff') self.camera.save(p) def save_db_snapshot(self, blob=None): if not self.selected_samples: self.warning_dialog('Please select a sample') return sample = self.selected_samples[0] self.info('adding image to sample. name={}, identifier={}'.format( sample.name, sample.identifier)) name = self._prev_name if not name: # get existing images for this sample db = self.manager.db with db.session_ctx(): # sample = db.get_sample(sample.name, identifier=sample.identifier) cnt = db.get_sample_image_count(sample.name, project=sample.project, material=sample.material, identifier=sample.identifier) cnt += 1 name = '{}{:03d}'.format(sample.name, cnt) v = DBSaveView(name=name) info = v.edit_traits() if info.result: self._prev_name = v.name self.debug('save image with name={}'.format(name)) if blob is None: blob = self.camera.get_jpeg_data(quality=75) db.add_sample_image(sample.name, v.name, blob, v.note, identifier=sample.identifier) # task interface def activated(self): self.camera.open() editor = CameraTab(model=self, name='Camera') self._open_editor(editor) self.load_projects(include_recent=False) def prepare_destroy(self): self.camera.close() def create_dock_panes(self): return [SampleBrowserPane(model=self), InfoPane(model=self)] def _selected_projects_changed(self, old, new): if new and self.project_enabled: names = [ni.name for ni in new] self.debug('selected projects={}'.format(names)) # self._load_associated_labnumbers(names) self._load_associated_samples(names) self.dump_browser_selection() def _selected_samples_changed(self, new): if new: self._load_associated_images(new) # def _selected_image_changed(self, new): def _dclicked_changed(self): selected = self.selected_image if selected: db = self.manager.db with db.session_ctx(): dbim = db.get_sample_image(selected.record_id) editor = self.get_editor(selected.record_id, key='record_id') if not editor: model = ImageModel(blob=dbim.image, name=dbim.name, create_date=dbim.create_date, note=dbim.note or '') editor = ImageTabEditor(record_id=selected.record_id, model=model, name=dbim.name) self._open_editor(editor) else: self.activate_editor(editor) def _active_editor_changed(self, new): if new and isinstance(new.model, ImageModel): self.selected_info_model = new.model def _load_associated_images(self, sample_records): db = self.manager.db with db.session_ctx(): images = [] for si in sample_records: sample = db.get_sample(si.name, si.project, si.material, si.identifier) images.extend( [SampleImageRecordView(i) for i in sample.images]) self.images = images def _load_associated_samples(self, names): db = self.manager.db with db.session_ctx(): samples = db.get_samples(names) self.debug('get samples n={}'.format(len(samples))) def func(li, prog, i, n): if prog: prog.change_message('Loading Sample {}'.format(li.name)) if li.labnumbers: return [ SampleRecordView(li, identifier=ll.identifier) for ll in li.labnumbers ] else: return SampleRecordView(li) samples = progress_loader(samples, func) self.samples = samples self.osamples = samples def _default_layout_default(self): return TaskLayout(left=PaneItem(id='pychron.image.browser'), right=PaneItem(id='pychron.image.info'))
class CameraViewer(HasTraits): _device = Any configure = Button snapshot_event = Event temperature = Range(2000, 15000, mode='slider') tint = Range(200, 2500, mode='slider') hue = Range(-180, 180, mode='slider') saturation = Range(0, 255, mode='slider') brightness = Range(-64, 64, mode='slider') contrast = Range(-100, 100, mode='slider') gamma = Range(0, 180, mode='slider') auto_exposure_enabled = Bool exposure_time = Range(0, 100, mode='slider') awb_button = Button('Auto') contrast_default_button = Button('Defaults') hue_default_button = Button('Defaults') snapshot_name = Str use_auto_snapshot_name = Bool(True) note = Str _no_update = False extension = Enum('JPEG', 'PNG', 'TIFF') # @property # def persistence_path(self): # try: # return os.path.join(paths.hidden_dir, 'camera_settings') # except AttributeError: # return os.path.join(os.path.expanduser('~'), 'Desktop', 'camera_settings') def activate(self): self.open() self._update_parameters() def save_jpeg(self, p): self._device.save_jpeg(p) def save(self, p, *args, **kw): self._device.save(p, *args, **kw) # handlers def _awb_button_fired(self): if self._device: self._device.do_awb(self._update_temptint) def _hue_default_button_fired(self): self.trait_set(hue=0, saturation=128, brightness=0) def _contrast_default_button_fired(self): self.trait_set(contrast=0, gamma=100) @on_trait_change('hue,saturation,brightness,contrast,gamma,auto_exposure, exposure_time') def _handle_color_change(self, name, new): if self._device is not None: if not self._no_update: getattr(self._device, 'set_{}'.format(name))(new) def _temperature_changed(self): self._set_temp_tint() def _tint_changed(self): self._set_temp_tint() # private def _update_temptint(self, args=None): if args is None: args = self._device.get_temperature_tint() if args: with no_update(self): self.trait_set(temperature=int(args[0]), tint=int(args[1])) def _set_temp_tint(self): if not self._no_update: self._device.set_temperature_tint(self.temperature, self.tint) def _update_parameters(self): self._update_temptint() with no_update(self): d = {k: getattr(self._device, 'get_{}'.format(k))() for k in ('hue', 'saturation', 'brightness', 'contrast', 'gamma', 'auto_exposure', 'exposure_time')} try: self.trait_set(**d) except TraitError: pass def open(self): self._device = ToupCamCamera() self._device.open() def close(self): self._device.close() def _configure_fired(self): pass def do_snapshot(self): if self.use_auto_snapshot_name: name = True else: name = self.snapshot_name self.snapshot_event = {'name': name, 'extension': self.extension, 'note': self.note} def save_settings(self): pass def load_settings(self): pass def traits_view(self): hue_grp = VGroup(HGroup(spring, UItem('hue_default_button')), Item('hue'), Item('saturation'), Item('brightness'), show_border=True, label='Hue/Saturation/Brightness') c_gamma_grp = VGroup(HGroup(spring, UItem('contrast_default_button')), Item('contrast'), Item('gamma'), show_border=True, label='Contrast/Gamma') exposure_grp = VGroup(Item('auto_exposure_enabled'), Item('exposure_time', enabled_when='not auto_exposure_enabled'), show_border=True, label='Exposure') white_balance_grp = VGroup(UItem('awb_button'), show_border=True, label='White Balance') # color_grp = VGroup(label='Color') meta_grp = VGroup(HGroup(Item('use_auto_snapshot_name', label='Use Auto'), Item('snapshot_name', label='Name', enabled_when='not use_auto_snapshot_name'), Item('extension')), VGroup(UItem('note', style='custom'), show_border=True, label='Note'), show_border=True, label='Meta') ctrlgrp = VFold(meta_grp, hue_grp, exposure_grp, c_gamma_grp, white_balance_grp) v = View(HSplit(ctrlgrp, UItem('_device', width=640, height=480, editor=CameraEditor())), toolbar=ToolBar(Action(action='do_snapshot', image=icon('camera'), name='Snapshot' ), # Action(action='save_settings', # image=icon('cog')) ), title='Camera', resizable=True) # v = View(VGroup(meta_grp, exposure_grp, c_gamma_grp, # white_balance_grp)) return v
def open(self): self._device = ToupCamCamera() self._device.open()