Esempio n. 1
0
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'))
Esempio n. 2
0
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'))
Esempio n. 3
0
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