def __on_process_done(self, img): size = fit(img.size, self.size) img = img.resize(size) self.drawers = [ RectangleDrawer(self.position, self.size, inside_color=ScanAnimation.BACKGROUND_COLOR), PillowImageDrawer(self.position, img) ] self.set_canvas(self.canvas) # reset canvas on all new drawers self.canvas.redraw()
def __on_scan_done(self, img): size = fit(img.size, self.size) img = img.resize(size) self.scan_animation = None self.drawers = [ RectangleDrawer(self.position, self.size, inside_color=ScanAnimation.BACKGROUND_COLOR), PillowImageDrawer(self.position, img), SpinnerAnimation(((self.position[0] + (self.size[0] / 2) - SpinnerAnimation.ICON_SIZE / 2), (self.position[1] + (self.size[1] / 2) - SpinnerAnimation.ICON_SIZE / 2))), ] self.set_canvas(self.canvas) # reset canvas on all new drawers self.canvas.redraw()
def on_scan_done(self, img, scan_resolution): scan_stop = time.time() self.__config['scan_time'].value['calibration'] = (scan_stop - self.__scan_start) self._on_scan_end() self.calibration['image'] = img self.calibration['resolution'] = scan_resolution calibration = self.__config['scanner_calibration'].value if calibration: calibration = calibration[1] img_drawer = PillowImageDrawer((0, 0), self.calibration['image']) self.calibration['image_gui'].add_drawer(img_drawer) self.grips = ImgGripHandler(img_drawer, img_drawer.size, self.calibration['zoom'], default_grips_positions=calibration, canvas=self.calibration['image_gui']) self.calibration['image_gui'].add_drawer(self.grips) self.grips.visible = True self.calibration["scan_button"].set_sensitive(True)
def on_scan_done(self, img, scan_resolution): scan_stop = time.time() self.schedulers['progress'].cancel(self.__scan_progress_job) self.__config['scan_time'].value['calibration'] = (scan_stop - self.__scan_start) self.calibration['image'] = img self.calibration['resolution'] = scan_resolution self.progressbar.set_fraction(0.0) calibration = self.__config['scanner_calibration'].value if calibration: calibration = calibration[1] img_drawer = PillowImageDrawer((0, 0), self.calibration['image']) self.calibration['image_gui'].remove_all_drawers() self.calibration['image_gui'].add_drawer(img_drawer) self.grips = ImgGripHandler(img_drawer, self.calibration['image_gui'], self.calibration['zoom'], default_grips_positions=calibration) self.grips.visible = True self.set_mouse_cursor("Normal") self.calibration["scan_button"].set_sensitive(True)
def __on_ocr_started_cb(self, img): assert (self.canvas) if len(self.scan_drawers) > 0: if hasattr(self.scan_drawers[-1], 'target_size'): size = self.scan_drawers[-1].target_size position = self.scan_drawers[-1].target_position else: size = self.scan_drawers[-1].size position = self.scan_drawers[-1].position self.scan_drawers = [] else: size = fit(img.size, self.canvas.visible_size) position = self.position target_sizes = self._compute_reduced_sizes(self.canvas.visible_size, size) # animations with big images are too slow # --> reduce the image size img = img.resize(target_sizes) target_positions = self._compute_reduced_positions( self.canvas.visible_size, size, target_sizes) self.ocr_drawers = {} for angle in list(target_positions.keys()): drawer = PillowImageDrawer(position, img) drawer.set_canvas(self.canvas) self.ocr_drawers[angle] = [drawer] self.animators = [] for (angle, drawers) in self.ocr_drawers.items(): drawer = drawers[0] drawer.size = size logger.info("Animator: Angle %d: %s %s -> %s %s" % (angle, str(drawer.position), str(drawer.size), str(target_positions[angle]), str(target_sizes))) # reduce the rotation to its minimum anim_angle = angle % 360 if (anim_angle > 180): anim_angle = -1 * (360 - anim_angle) new_animators = [ LinearCoordAnimator(drawer, target_positions[angle], self.SCAN_TO_OCR_ANIM_TIME, attr_name='position', canvas=self.canvas), LinearCoordAnimator(drawer, target_sizes, self.SCAN_TO_OCR_ANIM_TIME, attr_name='size', canvas=self.canvas), LinearSimpleAnimator(drawer, anim_angle, self.SCAN_TO_OCR_ANIM_TIME, attr_name='angle', canvas=self.canvas), ] # all the animators last the same length of time # so any of them is good enough for this signal new_animators[0].connect( 'animator-end', lambda animator: GLib.idle_add( self.__on_ocr_rotation_anim_done_cb)) self.animators += new_animators
def __init__(self, img, canvas, zoom_widget, default_grips_positions=None): GObject.GObject.__init__(self) if zoom_widget is None: zoom_widget = Gtk.Adjustment(value=1.0, lower=0.01, upper=1.0, step_increment=0.01, page_increment=0.10) self.zoom_widget = zoom_widget self.__visible = False self.img = img self.img_size = self.img.size self.canvas = canvas self.img_drawer = PillowImageDrawer((0, 0), img) if default_grips_positions is None: default_grips_positions = ((0, 0), self.img_size) else: default_grips_positions = ( ( min( max(0, default_grips_positions[0][0]), self.img_size[0] ), min( max(0, default_grips_positions[0][1]), self.img_size[1] ), ), ( min( max(0, default_grips_positions[1][0]), self.img_size[0] ), min( max(0, default_grips_positions[1][1]), self.img_size[1] ), ), ) default_grips_positions = ( ( min(default_grips_positions[0][0], default_grips_positions[1][0]), min(default_grips_positions[0][1], default_grips_positions[1][1]), ), ( max(default_grips_positions[0][0], default_grips_positions[1][0]), max(default_grips_positions[0][1], default_grips_positions[1][1]), ), ) self.grips = ( ImgGrip(default_grips_positions[0], self.img_size), ImgGrip(default_grips_positions[1], self.img_size), ) select_rectangle = ImgGripRectangle(self.grips) self.selected = None # the grip being moved self.__cursors = { 'default': Gdk.Cursor.new(Gdk.CursorType.HAND1), 'visible': Gdk.Cursor.new(Gdk.CursorType.HAND1), 'on_grip': Gdk.Cursor.new(Gdk.CursorType.TCROSS) } zoom_widget.connect("value-changed", lambda x: GLib.idle_add(self.__on_zoom_changed)) canvas.connect("absolute-button-press-event", self.__on_mouse_button_pressed_cb) canvas.connect("absolute-motion-notify-event", self.__on_mouse_motion_cb) canvas.connect("absolute-button-release-event", self.__on_mouse_button_released_cb) self.last_rel_position = (False, 0, 0) self.toggle_zoom((0.0, 0.0)) self.canvas.remove_all_drawers() self.canvas.add_drawer(self.img_drawer) self.canvas.add_drawer(select_rectangle) for grip in self.grips: self.canvas.add_drawer(grip)
class ImgGripHandler(GObject.GObject): __gsignals__ = { 'grip-moved': (GObject.SignalFlags.RUN_LAST, None, ()), 'zoom-changed': (GObject.SignalFlags.RUN_LAST, None, ()), } def __init__(self, img, canvas, zoom_widget, default_grips_positions=None): GObject.GObject.__init__(self) if zoom_widget is None: zoom_widget = Gtk.Adjustment(value=1.0, lower=0.01, upper=1.0, step_increment=0.01, page_increment=0.10) self.zoom_widget = zoom_widget self.__visible = False self.img = img self.img_size = self.img.size self.canvas = canvas self.img_drawer = PillowImageDrawer((0, 0), img) if default_grips_positions is None: default_grips_positions = ((0, 0), self.img_size) else: default_grips_positions = ( ( min( max(0, default_grips_positions[0][0]), self.img_size[0] ), min( max(0, default_grips_positions[0][1]), self.img_size[1] ), ), ( min( max(0, default_grips_positions[1][0]), self.img_size[0] ), min( max(0, default_grips_positions[1][1]), self.img_size[1] ), ), ) default_grips_positions = ( ( min(default_grips_positions[0][0], default_grips_positions[1][0]), min(default_grips_positions[0][1], default_grips_positions[1][1]), ), ( max(default_grips_positions[0][0], default_grips_positions[1][0]), max(default_grips_positions[0][1], default_grips_positions[1][1]), ), ) self.grips = ( ImgGrip(default_grips_positions[0], self.img_size), ImgGrip(default_grips_positions[1], self.img_size), ) select_rectangle = ImgGripRectangle(self.grips) self.selected = None # the grip being moved self.__cursors = { 'default': Gdk.Cursor.new(Gdk.CursorType.HAND1), 'visible': Gdk.Cursor.new(Gdk.CursorType.HAND1), 'on_grip': Gdk.Cursor.new(Gdk.CursorType.TCROSS) } zoom_widget.connect("value-changed", lambda x: GLib.idle_add(self.__on_zoom_changed)) canvas.connect("absolute-button-press-event", self.__on_mouse_button_pressed_cb) canvas.connect("absolute-motion-notify-event", self.__on_mouse_motion_cb) canvas.connect("absolute-button-release-event", self.__on_mouse_button_released_cb) self.last_rel_position = (False, 0, 0) self.toggle_zoom((0.0, 0.0)) self.canvas.remove_all_drawers() self.canvas.add_drawer(self.img_drawer) self.canvas.add_drawer(select_rectangle) for grip in self.grips: self.canvas.add_drawer(grip) def __on_zoom_changed(self): self.img_drawer.size = ( self.img_size[0] * self.scale, self.img_size[1] * self.scale, ) for grip in self.grips: grip.scale = self.scale if self.last_rel_position[0]: rel_pos = self.last_rel_position[1:] self.last_rel_position = (False, 0, 0) else: h = self.canvas.get_hadjustment() v = self.canvas.get_vadjustment() adjs = [h, v] rel_pos = [] for adj in adjs: upper = adj.get_upper() - adj.get_page_size() lower = adj.get_lower() if (upper - lower) <= 0: # XXX(Jflesch): Weird bug ? break val = adj.get_value() val -= lower val /= (upper - lower) rel_pos.append(val) if len(rel_pos) >= 2: GLib.idle_add(self.__replace_scrollbars, rel_pos) self.canvas.recompute_size() self.emit("zoom-changed") def __replace_scrollbars(self, rel_cursor_pos): adjustements = [ (self.canvas.get_hadjustment(), rel_cursor_pos[0]), (self.canvas.get_vadjustment(), rel_cursor_pos[1]), ] for (adjustment, val) in adjustements: upper = adjustment.get_upper() - adjustment.get_page_size() lower = adjustment.get_lower() val = (val * (upper - lower)) + lower adjustment.set_value(int(val)) def __get_scale(self): return float(self.zoom_widget.get_value()) scale = property(__get_scale) def toggle_zoom(self, rel_cursor_pos): if self.scale != 1.0: scale = 1.0 else: scale = min( float(self.canvas.visible_size[0]) / self.img_size[0], float(self.canvas.visible_size[1]) / self.img_size[1] ) self.last_rel_position = (True, rel_cursor_pos[0], rel_cursor_pos[1]) self.zoom_widget.set_value(scale) def __on_mouse_button_pressed_cb(self, widget, event): if not self.visible: return self.selected = None for grip in self.grips: if grip.is_on_grip((event.x, event.y)): self.selected = grip grip.selected = True break def __move_grip(self, event_pos): """ Move a grip, based on the position """ if not self.selected: return None new_x = event_pos[0] / self.scale new_y = event_pos[1] / self.scale self.selected.img_position = (new_x, new_y) def __on_mouse_motion_cb(self, widget, event): if not self.visible: return if self.selected: self.__move_grip((event.x, event.y)) is_on_grip = True self.img_drawer.redraw() else: is_on_grip = False for grip in self.grips: if grip.is_on_grip((event.x, event.y)): grip.hover = True is_on_grip = True else: grip.hover = False self.img_drawer.redraw() if is_on_grip: cursor = self.__cursors['on_grip'] else: cursor = self.__cursors['visible'] self.canvas.get_window().set_cursor(cursor) def __on_mouse_button_released_cb(self, widget, event): if not self.selected: # figure out the cursor position on the image (img_w, img_h) = self.img_size rel_cursor_pos = ( float(event.x) / (img_w * self.scale), float(event.y) / (img_h * self.scale), ) self.toggle_zoom(rel_cursor_pos) self.img_drawer.redraw() self.emit('zoom-changed') return if not self.visible: return self.selected.selected = False self.selected = None self.emit('grip-moved') def __get_visible(self): return self.__visible def __set_visible(self, visible): self.__visible = visible for grip in self.grips: grip.visible = visible if self.canvas.get_window(): self.canvas.get_window().set_cursor(self.__cursors['default']) self.img_drawer.redraw() visible = property(__get_visible, __set_visible) def get_coords(self): a_x = min(self.grips[0].img_position[0], self.grips[1].img_position[0]) a_y = min(self.grips[0].img_position[1], self.grips[1].img_position[1]) b_x = max(self.grips[0].img_position[0], self.grips[1].img_position[0]) b_y = max(self.grips[0].img_position[1], self.grips[1].img_position[1]) return ((int(a_x), int(a_y)), (int(b_x), int(b_y)))
def __on_ocr_started_cb(self, img): assert(self.canvas) if len(self.scan_drawers) > 0: if hasattr(self.scan_drawers[-1], 'target_size'): size = self.scan_drawers[-1].target_size position = self.scan_drawers[-1].target_position else: size = self.scan_drawers[-1].size position = self.scan_drawers[-1].position self.scan_drawers = [] else: size = fit(img.size, self.canvas.visible_size) position = self.position target_sizes = self._compute_reduced_sizes( self.canvas.visible_size, size) # animations with big images are too slow # --> reduce the image size img = img.resize(target_sizes) target_positions = self._compute_reduced_positions( self.canvas.visible_size, size, target_sizes) self.ocr_drawers = {} for angle in list(target_positions.keys()): drawer = PillowImageDrawer(position, img) drawer.set_canvas(self.canvas) self.ocr_drawers[angle] = [drawer] self.animators = [] for (angle, drawers) in self.ocr_drawers.items(): drawer = drawers[0] drawer.size = size logger.info("Animator: Angle %d: %s %s -> %s %s" % (angle, str(drawer.position), str(drawer.size), str(target_positions[angle]), str(target_sizes))) # reduce the rotation to its minimum anim_angle = angle % 360 if (anim_angle > 180): anim_angle = -1 * (360 - anim_angle) new_animators = [ LinearCoordAnimator( drawer, target_positions[angle], self.SCAN_TO_OCR_ANIM_TIME, attr_name='position', canvas=self.canvas), LinearCoordAnimator( drawer, target_sizes, self.SCAN_TO_OCR_ANIM_TIME, attr_name='size', canvas=self.canvas), LinearSimpleAnimator( drawer, anim_angle, self.SCAN_TO_OCR_ANIM_TIME, attr_name='angle', canvas=self.canvas), ] # all the animators last the same length of time # so any of them is good enough for this signal new_animators[0].connect( 'animator-end', lambda animator: GLib.idle_add(self.__on_ocr_rotation_anim_done_cb)) self.animators += new_animators