簡體   English   中英

PyQt5使用半透明顏色繪制圖像

[英]PyQt5 Drawing over image with semi transparent color

我正在嘗試使用QPainter繪制圖像。 使用純色時效果很好。 使用半透明顏色時,會出現點。

同樣,在一個位置繪制多條線時,顏色會倍增並產生較深的顏色。

import sys
from PyQt5.QtCore import Qt, QPoint
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtGui import QPixmap, QPainter, QPen, QColor


class Menu(QMainWindow):

    def __init__(self):
        super().__init__()
        self.drawing = False
        self.lastPoint = QPoint()
        self.image = QPixmap(r"C:\Users\www\Desktop\image.jpg")
        self.setGeometry(100, 100, 500, 300)
        self.resize(self.image.width(), self.image.height())
        self.show()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawPixmap(self.rect(), self.image)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drawing = True
            self.lastPoint = event.pos()

    def mouseMoveEvent(self, event):
        if event.buttons() and Qt.LeftButton and self.drawing:
            painter = QPainter(self.image)
            painter.setPen(QPen(QColor(121,252,50,50), 20, Qt.SolidLine))
            painter.drawLine(self.lastPoint, event.pos())
            self.lastPoint = event.pos()
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button == Qt.LeftButton:
            self.drawing = False


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainMenu = Menu()
    sys.exit(app.exec_())

在此處輸入圖片說明

在同一位置繪制幾次時,我需要將顏色保留為原始顏色(而不是每次都變深)。

鼠標的移動是“離散的”,這意味着每當您移動鼠標時,都不會獲得連續的像素坐標:如果將鼠標從(0, 0)足夠快地移動到(20, 20) ,您可能只會得到中間最多兩個或三個mouseMoveEvents,每個鼠標事件產生單個片段。
您看到的“點”實際上是您繪制的不同線條碰撞的區域,特別是因為鼠標移動不連續。 如果您認為它是用水彩繪畫,則就像您在每次鼠標移動時畫一條小線,然后等到它變干,然后再從上一點開始畫另一條線。

在每個mouseMoveEvent上繪制唯一的線后,這些線段的邊緣就會疊加在一起,從而導致這些“透明度較低的點”(因為您使用的是不透明的顏色),它們是線段發生碰撞的點,並且,因為繪畫通常是“加性的”,所以您會得到兩個或更多的區域,在這些區域中疊加的顏色會導致顏色更加不透明:想象一下,看副未對准的太陽鏡。

相反, QPainterPath可以繪制沒有該“偽像”的連續線,只要它們是同一繪制器路徑的一部分即可 (無論其子路徑是什么,包括子路徑的多邊形,橢圓形,弧形等)。 然后,每當您告訴QPainter繪制一個元素時,它將被疊加到先前的元素上。
為了更好地說明這一點,在左圖中,我使用您的顏色繪制了一條具有相同頂點的兩條不同的線,這就是mousePressEvent(開始繪制)的情況,向右快速移動(繪制第一行) ),然后將另一個移到底部(畫另一行)。 右側有相同的“行”,但使用唯一的QPainterPath。

普通頂點線

在此示例代碼中,我臨時創建了一個繪制器路徑,該路徑存儲當前的“繪制路徑”,直到釋放鼠標為止,然后該路徑才實際應用於QPixmap。

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPixmap, QPainter, QPen, QColor, QPainterPath


class Menu(QWidget):
    def __init__(self):
        super().__init__()
        self.drawingPath = None
        self.image = QPixmap(r"testimage.jpg")
        self.resize(self.image.width(), self.image.height())
        self.show()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawPixmap(self.rect(), self.image)
        if self.drawingPath:
            painter.setPen(QPen(QColor(121,252,50,50), 20, Qt.SolidLine))
            painter.drawPath(self.drawingPath)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            # start a new QPainterPath and *move* to the current point
            self.drawingPath = QPainterPath()
            self.drawingPath.moveTo(event.pos())

    def mouseMoveEvent(self, event):
        if event.buttons() and Qt.LeftButton and self.drawingPath:
            # add a line to the painter path, without "removing" the pen
            self.drawingPath.lineTo(event.pos())
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton and self.drawingPath:
            # draw the painter path to the pixmap
            painter = QPainter(self.image)
            painter.setPen(QPen(QColor(121,252,50,50), 20, Qt.SolidLine))
            painter.drawPath(self.drawingPath)
            self.drawingPath = None
            self.update()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainMenu = Menu()
    sys.exit(app.exec_())

這樣做只有一個問題: 當前的繪制路徑上繪制不會導致顏色更加不透明,這意味着,只要按下鼠標按鈕,無論您在同一點上“繪制”多少次,顏色將始終相同。 要獲得“更不透明的顏色”效果,您需要在相交處進行繪制,每次都開始一條新路徑。

PS:我使用了QWidget,因為在某些情況下,QMainWindow可以從單擊非交互式區域(例如在這種情況下)開始抓取鼠標移動,並使用它來移動界面。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM