Commit a0a25912 authored by dmMaze's avatar dmMaze
Browse files

optimize drawing

parent d680f33c
Loading
Loading
Loading
Loading
+33 −37
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@ from .misc import ndarray2pixmap, ProjImgTrans
from .textitem import TextBlkItem, TextBlock
from .texteditshapecontrol import TextBlkShapeControl
from .stylewidgets import FadeLabel
from .image_edit import StrokeItem, StrokeItem, ImageEditMode, DrawingLayer
from .image_edit import ImageEditMode, DrawingLayer, StrokeImgItem

CANVAS_SCALE_MAX = 3.0
CANVAS_SCALE_MIN = 0.1
@@ -74,8 +74,8 @@ class Canvas(QGraphicsScene):
    scalefactor_changed = Signal()
    end_create_textblock = Signal(QRectF)
    end_create_rect = Signal(QRectF, int)
    finish_painting = Signal(StrokeItem)
    finish_erasing = Signal(StrokeItem)
    finish_painting = Signal(StrokeImgItem)
    finish_erasing = Signal(StrokeImgItem)
    delete_textblks = Signal()
    format_textblks = Signal()
    layout_textblks = Signal()
@@ -155,7 +155,8 @@ class Canvas(QGraphicsScene):

        self.scalefactor_changed.connect(self.onScaleFactorChanged)
        self.selectionChanged.connect(self.on_selection_changed)     
        self.stroke_path_item: StrokeItem = None
        self.stroke_img_item: StrokeImgItem = None
        self.stroke_path_item = None

        self.editor_index = 0 # 0: drawing 1: text editor
        self.mid_btn_pressed = False
@@ -259,10 +260,15 @@ class Canvas(QGraphicsScene):
            self.alt_pressed = False
        return super().keyReleaseEvent(event)

    def addStrokeItem(self, item: StrokeItem, pen: QPen):
        self.addItem(item)
        item.setPen(pen)
        item.setParentItem(self.drawingLayer)
    def addStrokeImageItem(self, pos: QPointF, pen: QPen, erasing: bool = False):
        if self.stroke_img_item is not None:
            self.stroke_img_item.startNewPoint(pos)
        else:
            self.stroke_img_item = StrokeImgItem(pen, pos, self.imgLayer.pixmap().size())
            self.stroke_img_item.setParentItem(self.baseLayer)

    def updateStrokeImgItem(self, pos: QPointF):
        self.stroke_img_item.lineTo(pos)

    def startCreateTextblock(self, pos: QPointF, hide_control: bool = False):
        pos = pos / self.scale_factor
@@ -297,8 +303,9 @@ class Canvas(QGraphicsScene):
            
        elif self.creating_textblock:
            self.txtblkShapeControl.setRect(QRectF(self.create_block_origin, event.scenePos() / self.scale_factor).normalized())
        elif self.stroke_path_item is not None:
            self.stroke_path_item.addNewPoint(self.imgLayer.mapFromScene(event.scenePos()))
        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()))
        elif self.scale_tool_mode:
            self.scale_tool.emit(event.scenePos())
        elif self.rubber_band.isVisible() and self.rubber_band_origin is not None:
@@ -327,16 +334,14 @@ class Canvas(QGraphicsScene):
            if self.alt_pressed:
                self.scale_tool_mode = True
                self.begin_scale_tool.emit(event.scenePos())
            elif self.painting and self.stroke_path_item is None:
                self.stroke_path_item = StrokeItem(self.imgLayer.mapFromScene(event.scenePos()))
                self.addStrokeItem(self.stroke_path_item, self.painting_pen)
            elif self.painting:
                self.addStrokeImageItem(self.imgLayer.mapFromScene(event.scenePos()), self.painting_pen)

        elif btn == Qt.MouseButton.RightButton:
            # user is drawing using eraser
            if self.painting and self.stroke_path_item is None:
            if self.painting:
                erasing = self.image_edit_mode == ImageEditMode.PenTool
                self.stroke_path_item = StrokeItem(self.imgLayer.mapFromScene(event.scenePos()), erasing)
                self.addStrokeItem(self.stroke_path_item, self.erasing_pen)
                self.addStrokeImageItem(self.imgLayer.mapFromScene(event.scenePos()), self.painting_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())
@@ -357,23 +362,22 @@ class Canvas(QGraphicsScene):
            btn = 0 if btn == Qt.MouseButton.LeftButton else 1
            return self.endCreateTextblock(btn=btn)
        elif btn == Qt.MouseButton.RightButton:
            if self.stroke_path_item is not None:
                self.finish_erasing.emit(self.stroke_path_item)
            if self.stroke_img_item is not None:
                self.finish_erasing.emit(self.stroke_img_item)
            if self.rubber_band.isVisible():
                self.rubber_band.hide()
                self.rubber_band_origin = None
        elif btn == Qt.MouseButton.LeftButton:
            if self.stroke_path_item is not None:
                self.finish_painting.emit(self.stroke_path_item)
            if self.stroke_img_item is not None:
                self.finish_painting.emit(self.stroke_img_item)
            elif self.scale_tool_mode:
                self.scale_tool_mode = False
                self.end_scale_tool.emit()
            self.stroke_path_item = None
        return super().mouseReleaseEvent(event)

    def updateCanvas(self):
        self.editing_textblkitem = None
        self.stroke_path_item = None
        self.stroke_img_item = None
        self.txtblkShapeControl.setBlkItem(None)
        self.mid_btn_pressed = False

@@ -395,9 +399,7 @@ class Canvas(QGraphicsScene):

    def setDrawingLayer(self, img: Union[QPixmap, np.ndarray] = None):
        
        ditems = self.get_drawings(visible=False)
        for item in ditems:
            self.removeItem(item)
        self.drawingLayer.clearAllDrawings()

        if not self.imgtrans_proj.img_valid:
            return
@@ -454,9 +456,8 @@ class Canvas(QGraphicsScene):
        self.creating_textblock = False
        self.create_block_origin = None
        self.editing_textblkitem = None
        if self.stroke_path_item is not None:
            self.removeItem(self.stroke_path_item)
            self.stroke_path_item = None
        if self.stroke_img_item is not None:
            self.removeItem(self.stroke_img_item)

    def on_undostack_changed(self):
        if self.undoStack.count() != 0:
@@ -470,12 +471,7 @@ class Canvas(QGraphicsScene):
            self.proj_savestate_changed.emit(un_saved)

    def removeItem(self, item: QGraphicsItem) -> None:
        if item == self.stroke_path_item:
            self.stroke_path_item = None
        return super().removeItem(item)

    def get_drawings(self, visible=False) -> List[QGraphicsItem]:
        ditems = self.drawingLayer.childItems()
        if visible:
            ditems = [item for item in ditems if item.isVisible()]
        return ditems
 No newline at end of file
        super().removeItem(item)
        if isinstance(item, StrokeImgItem):
            item.setParentItem(None)
            self.stroke_img_item = None
 No newline at end of file
+48 −57
Original line number Diff line number Diff line
from qtpy.QtCore import Signal, Qt, QPointF, QSize, QLineF, QDateTime, QRectF
from qtpy.QtCore import Signal, Qt, QPointF, QSize, QLineF, QDateTime, QRectF, QPoint
from qtpy.QtWidgets import QPushButton, QComboBox, QSizePolicy, QBoxLayout, QCheckBox, QHBoxLayout, QGraphicsView, QStackedWidget, QVBoxLayout, QLabel, QGraphicsPixmapItem, QGraphicsEllipseItem
from qtpy.QtGui import QPen, QColor, QCursor, QPainter, QPixmap, QBrush, QFontMetrics, QImage

@@ -16,7 +16,7 @@ from utils.textblock_mask import canny_flood, connected_canny_flood
from utils.logger import logger

from .dl_manager import DLManager
from .image_edit import ImageEditMode, StrokeItem, PixmapItem, DrawingLayer
from .image_edit import ImageEditMode, PixmapItem, DrawingLayer, StrokeImgItem
from .configpanel import InpaintConfigPanel
from .stylewidgets import Widget, SeparatorWidget, ColorPicker, PaintQSlider
from .canvas import Canvas
@@ -221,7 +221,7 @@ class DrawingPanel(Widget):
        super().__init__(*args, **kwargs)
        self.dl_manager: DLManager = None
        self.canvas = canvas
        self.inpaint_stroke: StrokeItem = None
        self.inpaint_stroke: StrokeImgItem = None
        self.rect_inpaint_dict: dict = None

        border_pen = QPen(INPAINT_BRUSH_COLOR, 3, Qt.PenStyle.DashLine)
@@ -478,29 +478,54 @@ class DrawingPanel(Widget):
            self.currentTool.setChecked(True)
        return super().showEvent(event)

    def on_finish_painting(self, stroke_item: StrokeItem):
        if stroke_item.isEmpty():
            self.canvas.removeItem(stroke_item)
            return
    def on_finish_painting(self, stroke_item: StrokeImgItem):
        stroke_item.finishPainting()
        if not self.canvas.imgtrans_proj.img_valid:
            self.canvas.removeItem(stroke_item)
            return
        if self.currentTool == self.penTool:
            self.canvas.undoStack.push(StrokeItemUndoCommand(self.canvas.drawingLayer, stroke_item))
            rect, _, qimg = stroke_item.clip()
            if rect is not None:
                self.canvas.undoStack.push(StrokeItemUndoCommand(self.canvas.drawingLayer, rect, qimg))
            self.canvas.removeItem(stroke_item)
        elif self.currentTool == self.inpaintTool:
            self.mergeInpaintStroke(stroke_item)
            self.inpaint_stroke = stroke_item
            if self.canvas.gv.ctrl_pressed:
                return
            else:
                self.runInpaint()

    def mergeInpaintStroke(self, inpaint_stroke: StrokeItem):
        if self.inpaint_stroke is None:
            self.inpaint_stroke = inpaint_stroke
        else:
            if not inpaint_stroke.isEmpty():
                self.inpaint_stroke.addStroke(inpaint_stroke.stroke)
            self.canvas.removeItem(inpaint_stroke)
    def on_finish_erasing(self, stroke_item: StrokeImgItem):
        stroke_item.finishPainting()
        # inpainted-erasing logic is essentially the same as inpainting
        if self.currentTool == self.inpaintTool:
            rect, mask, _ = stroke_item.clip(mask_only=True)
            if mask is None:
                self.canvas.removeItem(stroke_item)
                return
            mask = 255 - mask
            mask_h, mask_w = mask.shape[:2]
            mask_x, mask_y = rect[0], rect[1]
            inpaint_rect = [mask_x, mask_y, mask_w + mask_x, mask_h + mask_y]
            origin = self.canvas.imgtrans_proj.img_array
            origin = origin[inpaint_rect[1]: inpaint_rect[3], inpaint_rect[0]: inpaint_rect[2]]
            inpainted = self.canvas.imgtrans_proj.inpainted_array
            inpainted = inpainted[inpaint_rect[1]: inpaint_rect[3], inpaint_rect[0]: inpaint_rect[2]]
            inpaint_mask = self.canvas.imgtrans_proj.mask_array[inpaint_rect[1]: inpaint_rect[3], inpaint_rect[0]: inpaint_rect[2]]
            # no inpainted need to be erased
            if inpaint_mask.sum() == 0:
                return
            mask = cv2.bitwise_and(mask, inpaint_mask)
            inpaint_mask = np.zeros_like(inpainted)
            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))

        elif self.currentTool == self.penTool:
            rect, _, qimg = stroke_item.clip()
            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):

@@ -511,15 +536,14 @@ class DrawingPanel(Widget):
                logger.warning("inpainting goes wrong")
                self.clearInpaintItems()
                return
            mask = self.inpaint_stroke.getSubimg(convert_mask=True)
            pos = self.inpaint_stroke.subBlockPos()
                
            rect, mask, _ = self.inpaint_stroke.clip(mask_only=True)
            if mask is None:
                self.clearInpaintItems()
                return

            # we need to enlarge the mask window a bit to get better results
            mask_h, mask_w = mask.shape[:2]
            mask_x, mask_y = pos.x(), pos.y()
            mask_x, mask_y = rect[0], rect[1]
            img = self.canvas.imgtrans_proj.inpainted_array
            inpaint_rect = [mask_x, mask_y, mask_w + mask_x, mask_h + mask_y]
            rect_enlarged = enlarge_window(inpaint_rect, img.shape[1], img.shape[0])
@@ -545,36 +569,6 @@ class DrawingPanel(Widget):
        self.canvas.undoStack.push(InpaintUndoCommand(self.canvas, inpainted, mask, inpaint_rect))
        self.clearInpaintItems()

    def on_finish_erasing(self, stroke_item: StrokeItem):

        # inpainted-erasing logic is essentially the same as inpainting
        if self.currentTool == self.inpaintTool:
            mask = stroke_item.getSubimg(convert_mask=True)
            self.canvas.removeItem(stroke_item)
            if mask is None:
                return
            mask = 255 - mask
            pos = stroke_item.subBlockPos()
            mask_h, mask_w = mask.shape[:2]
            mask_x, mask_y = pos.x(), pos.y()
            inpaint_rect = [mask_x, mask_y, mask_w + mask_x, mask_h + mask_y]
            origin = self.canvas.imgtrans_proj.img_array
            origin = origin[inpaint_rect[1]: inpaint_rect[3], inpaint_rect[0]: inpaint_rect[2]]
            inpainted = self.canvas.imgtrans_proj.inpainted_array
            inpainted = inpainted[inpaint_rect[1]: inpaint_rect[3], inpaint_rect[0]: inpaint_rect[2]]
            inpaint_mask = self.canvas.imgtrans_proj.mask_array[inpaint_rect[1]: inpaint_rect[3], inpaint_rect[0]: inpaint_rect[2]]
            # no inpainted need to be erased
            if inpaint_mask.sum() == 0:
                return
            mask = cv2.bitwise_and(mask, inpaint_mask)
            inpaint_mask = np.zeros_like(inpainted)
            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))

        elif self.currentTool == self.penTool:
            self.canvas.undoStack.push(StrokeItemUndoCommand(self.canvas.drawingLayer, self.canvas.stroke_path_item, True))

    def on_inpaint_failed(self):
        if self.currentTool == self.inpaintTool and self.inpaint_stroke is not None:
            self.clearInpaintItems()
@@ -737,16 +731,13 @@ class DrawingPanel(Widget):
                self.canvas.image_edit_mode = ImageEditMode.InpaintTool

class StrokeItemUndoCommand(QUndoCommand):
    def __init__(self, target_layer: DrawingLayer, stroke_item: StrokeItem, erasing=False):
    def __init__(self, target_layer: DrawingLayer, rect: Tuple[int], qimg: QImage, erasing=False):
        super().__init__()

        self.qimg = stroke_item.convertToQImg().convertToFormat(QImage.Format.Format_ARGB32_Premultiplied)
        pos = stroke_item.subBlockPos()
        self.x = pos.x()
        self.y = pos.y()
        self.qimg = qimg
        self.x = rect[0]
        self.y = rect[1]
        self.target_layer = target_layer
        self.key = str(QDateTime.currentMSecsSinceEpoch())
        target_layer.scene().removeItem(stroke_item)
        if erasing:
            self.compose_mode = QPainter.CompositionMode.CompositionMode_DestinationOut
        else:
+60 −134
Original line number Diff line number Diff line
from typing import Tuple, List, Union
import numpy as np

import cv2
from qtpy.QtCore import QRectF, Qt, QPointF, QSize, QPoint, QDateTime
from qtpy.QtWidgets import QStyleOptionGraphicsItem, QGraphicsPixmapItem, QWidget, QGraphicsPathItem, QGraphicsItem
from qtpy.QtGui import QPen, QColor, QPainterPath, QCursor, QPainter, QPixmap, QImage, QBrush
@@ -24,155 +25,67 @@ class ImageEditMode:

class StrokeImgItem(QGraphicsItem):
    def __init__(self, pen: QPen, point: QPointF, size: QSize, format: QImage.Format = QImage.Format.Format_ARGB32, ):
        super().__init__()
        self._img = QImage(size, format)
        self._img.fill(Qt.GlobalColor.transparent)
        self.pen = pen
        self.painter = QPainter()
        self._d = d = self.pen.widthF()
        self._r = d / 2
        self.clipped_rect = None

        self.painter = QPainter(self._img)
        self.painter.setPen(pen)
        self.painter.setRenderHint(QPainter.RenderHint.Antialiasing)
        self.painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_Source)
        self.setBoundingRegionGranularity(0)
        self.cur_point = point
        self.drawLine(point, point)
        self._br = QRectF(0, 0, size.width(), size.height())
        self.is_painting = True
        self.lineTo(point)

    def finishPainting(self):
        self.painter.end()
        self.is_painting = False

    def clip(self, mask_only=False, format=QImage.Format.Format_ARGB32_Premultiplied) -> Tuple[List, np.ndarray, QImage]:
        img_array = pixmap2ndarray(self._img, True)
        ar = cv2.boundingRect(cv2.findNonZero(img_array[..., -1]))
        img_array = img_array[ar[1]: ar[1] + ar[3], ar[0]: ar[0] + ar[2]]
        if not (ar[2] > 0 and ar[3] > 0):
            return None, None, None
        if mask_only:
            img_array = img_array[..., -1]
            img_array[img_array > 0] = 255
        return ar, img_array, self._img.copy(*ar).convertToFormat(format)

    def startNewPoint(self, pos: QPointF):
        self.is_painting = True
        self.painter.begin(self._img)
        self.painter.setPen(self.pen)
        self.painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_Source)
        self.cur_point = pos
        self.lineTo(pos)

    def boundingRect(self) -> QRectF:
        return self._br

    def drawLine(self, new_pnt: QPointF):
        self.painter.begin(self._img)
    def lineTo(self, new_pnt: QPointF):
        delta = self.cur_point - new_pnt
        delta_w, delta_h = abs(delta.x()),  abs(delta.y())
        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
            delta_w += self._d
            delta_h += self._d
            rect = QRectF(min_x, min_y, delta_w, delta_h)
            self.painter.drawLine(self.cur_point, new_pnt)
        self.painter.end()
            self.cur_point = new_pnt
            self.update(rect)

    def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem, widget: QWidget) -> None:
        painter.drawImage(0, 0, self._img)


class StrokeItem(QGraphicsPathItem):
    def __init__(self, origin_point: QPointF, erasing: bool = False):
        super().__init__()
        # self.stroke = QPainterPath(QPointF(0, 0))
        self.stroke = QPainterPath(QPointF(origin_point))
        self.erasing = erasing
        self.last_point = origin_point
        self.setPath(self.stroke)
        self.setBoundingRegionGranularity(0)
        self.clip_offset = QPointF(0, 0)

    def addNewPoint(self, new_point: QPointF):
        if new_point != self.last_point:
            self.stroke.lineTo(new_point)
            self.setPath(self.stroke)
            self.last_point = new_point

    def addStroke(self, stroke: QPainterPath):
        self.stroke.addPath(stroke)
        self.setPath(self.stroke)

    def isEmpty(self):
        return self.stroke.isEmpty()

    def convertToPixmapItem(self, convert_mask=False, remove_stroke=True, target_layer: QGraphicsPixmapItem = None) -> QGraphicsPixmapItem:
        if target_layer is None:
            target_layer = self.parentItem()

        pixmap = self.getSubimg(convert_mask, return_pixmap=True)
        if pixmap is None:
            self.scene().removeItem(self)
            return None, None, None
        # pixmap = ndarray2pixmap(img_array)
        pixmap_item = QGraphicsPixmapItem(pixmap)

        pixmap_item.setParentItem(target_layer)
        pos = self.subBlockPos()
        pixmap_item.setPos(pos.x(), pos.y())
        if self.scene() is not None:
            if remove_stroke:
                self.scene().removeItem(self)
            else:
                self.setZValue(3)
        return pixmap_item

    def convertToQImg(self, convert_mask=False) -> QImage:
        img_array = self.getSubimg(convert_mask)
        if img_array is None:
            return None
        qimg = ndarray2pixmap(img_array, return_qimg=True)
        return qimg

    def originOffset(self) -> QPointF:
        thickness = self.pen().widthF() / 2
        return QPointF(thickness, thickness) - self.stroke.boundingRect().topLeft() - self.clip_offset

    def subBlockPos(self) -> QPoint:
        pos = self.pos() - self.originOffset()
        pos.setX(int(round(max(0, pos.x()))))
        pos.setY(int(round(max(0, pos.y()))))
        return pos.toPoint()

    def getSubimg(self, convert_mask=False, return_pixmap=False) -> np.ndarray:
        if self.isEmpty():
            return None

        origin_offset = self.originOffset()
        parent_layer = self.parentItem()
        while parent_layer.parentItem() is not None:
            if isinstance(parent_layer, QGraphicsPixmapItem):
                layer_size = parent_layer.pixmap().size()
            parent_layer = parent_layer.parentItem()

        scale_factor = parent_layer.scale()
        # layer_size = parent_layer.pixmap().size()
        max_width, max_height = layer_size.width(), layer_size.height()
        scene_br = self.sceneBoundingRect()
        stroke_size = scene_br.size()
        stroke_size.setHeight(stroke_size.height() / scale_factor)
        stroke_size.setWidth(stroke_size.width() / scale_factor)
        stroke_size = stroke_size.toSize()

        lt = self.pos() - origin_offset
        xywh = [lt.x(), lt.y(), scene_br.width() / scale_factor, scene_br.height() / scale_factor]
        xyxy = np.array(xywh)
        xyxy[[2, 3]] += xyxy[[0, 1]]

        xyxy = xyxy.astype(np.int)            
        xyxy_clip = xyxy.copy()
        xyxy_clip[[0, 2]] = np.clip(xyxy[[0, 2]], 0, max_width - 1)
        xyxy_clip[[1, 3]] = np.clip(xyxy[[1, 3]], 0, max_height - 1)
        # clipped stroke is empty
        if xyxy_clip[0] >= xyxy_clip[2] or xyxy_clip[1] >= xyxy_clip[3]:
            return None

        pixmap = QPixmap(stroke_size)
        pixmap.fill(Qt.GlobalColor.transparent)
        painter = QPainter(pixmap)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)
        painter.translate(self.originOffset())
        painter.setPen(self.pen())
        painter.setBrush(self.brush())
        painter.drawPath(self.stroke)
        painter.end()

        stroke_clip = xyxy_clip - xyxy
        stroke_clip[2] += stroke_size.width()
        stroke_clip[3] += stroke_size.height()
        self.clip_offset = QPointF(stroke_clip[0], stroke_clip[1])

        if return_pixmap:
            return pixmap
            
        imgarray = pixmap2ndarray(pixmap, keep_alpha=True)
        imgarray = imgarray[stroke_clip[1]: stroke_clip[3], stroke_clip[0]: stroke_clip[2]]
        # print(imgarray.shape, stroke_clip)
        
        if convert_mask:
            mask = imgarray[..., -1]
            mask[mask > 0] = 255
            imgarray[..., :] = mask[..., np.newaxis]
            return mask
            
        return imgarray


class PenCursor(QCursor):
    def __init__(self, *args, **kwargs):
        super().__init__()
@@ -212,6 +125,7 @@ class DrawingLayer(QGraphicsPixmapItem):
        super().__init__()
        self.qimg_dict = {}
        self.drawing_items_info = {}
        self.drawed_pixmap = None

    def addQImage(self, x: int, y: int, qimg: QImage, compose_mode, key: str):
        self.qimg_dict[key] = qimg
@@ -235,4 +149,16 @@ class DrawingLayer(QGraphicsPixmapItem):
                p.drawImage(info['pos'][0], info['pos'][1], item)
        p.end()
        painter.drawPixmap(self.offset(), pixmap)
        self.drawed_pixmap = pixmap

    def get_drawed_pixmap(self, format=QImage.Format.Format_ARGB32) -> QPixmap:
        pixmap = self.pixmap() if self.drawed_pixmap is None else self.drawed_pixmap
        return pixmap

    def drawed(self) -> bool:
        return len(self.qimg_dict) > 0

    def clearAllDrawings(self):
        self.qimg_dict.clear()
        self.drawing_items_info.clear()
+2 −2
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@ import numpy as np
from utils.io_utils import imread, imwrite

from qtpy.QtCore import Qt, Signal, QPoint, QSize, QThread
from qtpy.QtGui import QImage
from qtpy.QtGui import QImage, QPixmap


class ImgSaveThread(QThread):
@@ -23,7 +23,7 @@ class ImgSaveThread(QThread):
            if len(self.im_save_list) == 0:
                break
            save_path, img = self.im_save_list.pop(0)
            if isinstance(img, QImage):
            if isinstance(img, QImage) or isinstance(img, QPixmap):
                img.save(save_path)
            elif isinstance(img, np.ndarray):
                imwrite(save_path, img)
+18 −12

File changed.

Preview size limit exceeded, changes collapsed.