Commit e1645e08 authored by dmMaze's avatar dmMaze
Browse files

support real-time pen-erasing

parent a0a25912
Loading
Loading
Loading
Loading
+19 −9
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@ import numpy as np
from typing import List, Union, Tuple

from qtpy.QtWidgets import QMenu, QGraphicsScene, QGraphicsView, QGraphicsRectItem, QGraphicsItem, QScrollBar, QGraphicsPixmapItem, QGraphicsSceneMouseEvent, QGraphicsSceneContextMenuEvent, QRubberBand
from qtpy.QtCore import Qt, QRect, QRectF, QPointF, QPoint, Signal, QSizeF, QObject, QEvent
from qtpy.QtCore import Qt, QDateTime, QRectF, QPointF, QPoint, Signal, QSizeF, QObject, QEvent
from qtpy.QtGui import QPixmap, QHideEvent, QKeyEvent, QWheelEvent, QResizeEvent, QKeySequence, QPainter, QPen, QPainterPath

try:
@@ -156,7 +156,7 @@ class Canvas(QGraphicsScene):
        self.scalefactor_changed.connect(self.onScaleFactorChanged)
        self.selectionChanged.connect(self.on_selection_changed)     
        self.stroke_img_item: StrokeImgItem = None
        self.stroke_path_item = None
        self.erase_img_key = None

        self.editor_index = 0 # 0: drawing 1: text editor
        self.mid_btn_pressed = False
@@ -265,10 +265,12 @@ class Canvas(QGraphicsScene):
            self.stroke_img_item.startNewPoint(pos)
        else:
            self.stroke_img_item = StrokeImgItem(pen, pos, self.imgLayer.pixmap().size())
            if not erasing:
                self.stroke_img_item.setParentItem(self.baseLayer)

    def updateStrokeImgItem(self, pos: QPointF):
        self.stroke_img_item.lineTo(pos)
            else:
                self.erase_img_key = str(QDateTime.currentMSecsSinceEpoch())
                compose_mode = QPainter.CompositionMode.CompositionMode_DestinationOut
                self.drawingLayer.addQImage(0, 0, self.stroke_img_item._img, compose_mode, self.erase_img_key)

    def startCreateTextblock(self, pos: QPointF, hide_control: bool = False):
        pos = pos / self.scale_factor
@@ -305,7 +307,13 @@ class Canvas(QGraphicsScene):
            self.txtblkShapeControl.setRect(QRectF(self.create_block_origin, event.scenePos() / self.scale_factor).normalized())
        elif self.stroke_img_item is not None:
            if self.stroke_img_item.is_painting:
                self.stroke_img_item.lineTo(self.imgLayer.mapFromScene(event.scenePos()))
                pos = self.imgLayer.mapFromScene(event.scenePos())
                if self.erase_img_key is None:
                    self.stroke_img_item.lineTo(pos)
                else:
                    rect = self.stroke_img_item.lineTo(pos, update=False)
                    if rect is not None:
                        self.drawingLayer.update(rect)
        elif self.scale_tool_mode:
            self.scale_tool.emit(event.scenePos())
        elif self.rubber_band.isVisible() and self.rubber_band_origin is not None:
@@ -341,7 +349,7 @@ class Canvas(QGraphicsScene):
            # user is drawing using eraser
            if self.painting:
                erasing = self.image_edit_mode == ImageEditMode.PenTool
                self.addStrokeImageItem(self.imgLayer.mapFromScene(event.scenePos()), self.painting_pen, erasing)
                self.addStrokeImageItem(self.imgLayer.mapFromScene(event.scenePos()), self.erasing_pen, erasing)
            else:   # rubber band selection
                self.rubber_band_origin = event.scenePos()
                self.rubber_band.setGeometry(QRectF(self.rubber_band_origin, self.rubber_band_origin).normalized())
@@ -378,6 +386,7 @@ class Canvas(QGraphicsScene):
    def updateCanvas(self):
        self.editing_textblkitem = None
        self.stroke_img_item = None
        self.erase_img_key = None
        self.txtblkShapeControl.setBlkItem(None)
        self.mid_btn_pressed = False

@@ -475,3 +484,4 @@ class Canvas(QGraphicsScene):
        if isinstance(item, StrokeImgItem):
            item.setParentItem(None)
            self.stroke_img_item = None
            self.erase_img_key = None
 No newline at end of file
+6 −1
Original line number Diff line number Diff line
@@ -520,12 +520,17 @@ class DrawingPanel(Widget):
            inpaint_mask[mask > 0] = 1
            erased_img = inpaint_mask * inpainted + (1 - inpaint_mask) * origin
            self.canvas.undoStack.push(InpaintUndoCommand(self.canvas, erased_img, mask, inpaint_rect))
            self.canvas.removeItem(stroke_item)

        elif self.currentTool == self.penTool:
            rect, _, qimg = stroke_item.clip()
            if self.canvas.erase_img_key is not None:
                self.canvas.drawingLayer.removeQImage(self.canvas.erase_img_key)
                self.canvas.erase_img_key = None
                self.canvas.stroke_img_item = None
            if rect is not None:
                self.canvas.undoStack.push(StrokeItemUndoCommand(self.canvas.drawingLayer, rect, qimg, True))
        self.canvas.removeItem(stroke_item)
        

    def runInpaint(self, inpaint_dict=None):

+6 −3
Original line number Diff line number Diff line
@@ -69,9 +69,10 @@ class StrokeImgItem(QGraphicsItem):
    def boundingRect(self) -> QRectF:
        return self._br

    def lineTo(self, new_pnt: QPointF):
    def lineTo(self, new_pnt: QPointF, update=True) -> QRectF:
        delta = self.cur_point - new_pnt
        delta_w, delta_h = abs(delta.x()),  abs(delta.y())
        rect = None
        if delta_w + delta_h > 2:
            min_x = min(self.cur_point.x(), new_pnt.x()) - self._r
            min_y = min(self.cur_point.y(), new_pnt.y()) - self._r
@@ -80,7 +81,9 @@ class StrokeImgItem(QGraphicsItem):
            rect = QRectF(min_x, min_y, delta_w, delta_h)
            self.painter.drawLine(self.cur_point, new_pnt)
            self.cur_point = new_pnt
            if update:
                self.update(rect)
        return rect

    def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem, widget: QWidget) -> None:
        painter.drawImage(0, 0, self._img)
@@ -135,7 +138,7 @@ class DrawingLayer(QGraphicsPixmapItem):
    def removeQImage(self, key: str):
        if key in self.qimg_dict:
            self.qimg_dict.pop(key)
            # self.drawing_items_pos.pop(key)
            self.drawing_items_info.pop(key)

    def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem, widget: QWidget):
        pixmap = self.pixmap()