Beispiel #1
0
 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()
Beispiel #2
0
 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()
Beispiel #3
0
    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)
Beispiel #4
0
    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)
Beispiel #5
0
    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
Beispiel #6
0
    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)
Beispiel #7
0
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)))
Beispiel #8
0
    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