問題描述
我有一個功能正常的繪圖應用程序,用于對圖像進行一些分割.為此,我有兩層,原始圖像和我正在繪制的圖像層.
I have a functioning drawing application for some segmentation on images. For this I have two layers, the original image and the image layer I am drawing on.
我現在想實現一種擦除方法.我已經實現了撤消功能,但我也希望用戶能夠選擇畫筆顏色"以便能夠擦除特定部分,例如油漆中的橡皮擦.我認為這可以通過使用不透明的顏色進行繪制來實現,但這只會導致不繪制線條.
I now want to implement a method for erasing. I have implemented undo functionality, but I would also like the user to be able to select a brush "color" as to be able to erase specific parts, like the eraser in paint. I thought this would be possible by drawing with a color with opacity, but that just results in no line being drawn.
因此,我的目標是畫一條線,去除圖像層中的像素值,以便我可以看到底層圖像
The goal for me is therefore to draw a line, that removes the pixel values in the image layer, such that I can see the underlying image
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenuBar, QMenu, QAction
from PyQt5.QtGui import QIcon, QImage, QPainter, QPen
from PyQt5.QtCore import Qt, QPoint
from PyQt5.QtGui import QColor
import sys
class Window(QMainWindow):
def __init__(self):
super().__init__()
top = 400
left = 400
width = 800
height = 600
self.setWindowTitle("MyPainter")
self.setGeometry(top, left, width, height)
self.image = QImage(self.size(), QImage.Format_ARGB32)
self.image.fill(Qt.white)
self.imageDraw = QImage(self.size(), QImage.Format_ARGB32)
self.imageDraw.fill(Qt.transparent)
self.drawing = False
self.brushSize = 2
self.brushColor = Qt.black
self.lastPoint = QPoint()
self.change = False
mainMenu = self.menuBar()
changeColour = mainMenu.addMenu("changeColour")
changeColourAction = QAction("change",self)
changeColour.addAction(changeColourAction)
changeColourAction.triggered.connect(self.changeColour)
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.imageDraw)
painter.setPen(QPen(self.brushColor, self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
painter.drawLine(self.lastPoint, event.pos())
self.lastPoint = event.pos()
self.update()
def mouseReleaseEvent(self, event):
if event.button == Qt.LeftButton:
self.drawing = False
def paintEvent(self, event):
canvasPainter = QPainter(self)
canvasPainter.drawImage(self.rect(), self.image, self.image.rect())
canvasPainter.drawImage(self.rect(), self.imageDraw, self.imageDraw.rect())
def changeColour(self):
if not self.change:
# erase
self.brushColor = QColor(255,255,255,0)
else:
self.brushColor = Qt.black
self.change = not self.change
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
app.exec()
如何擦除像素子集?
在這個例子中,應該為 changeColour
函數中的 self.brushColor
賦予什么顏色?
How to erase a subset of pixels?
As in this example what color should be given to self.brushColor
in the changeColour
function?
白色不是解決方案,因為實際上底部的圖像是一個復雜的圖像,因此我想在擦除時再次使頂層透視".
The colour white is not the solution, because in reality the image at the bottom is a complex image, I therefore want to make the toplayer "see-through" again, when erasing.
推薦答案
你必須改變 compositionMode 到 QPainter::CompositionMode_Clear
并用 eraseRect().
You have to change the compositionMode to QPainter::CompositionMode_Clear
and erase with eraseRect().
from PyQt5 import QtCore, QtGui, QtWidgets
class Window(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
top, left, width, height = 400, 400, 800, 600
self.setWindowTitle("MyPainter")
self.setGeometry(top, left, width, height)
self.image = QtGui.QImage(self.size(), QtGui.QImage.Format_ARGB32)
self.image.fill(QtCore.Qt.white)
self.imageDraw = QtGui.QImage(self.size(), QtGui.QImage.Format_ARGB32)
self.imageDraw.fill(QtCore.Qt.transparent)
self.drawing = False
self.brushSize = 2
self._clear_size = 20
self.brushColor = QtGui.QColor(QtCore.Qt.black)
self.lastPoint = QtCore.QPoint()
self.change = False
mainMenu = self.menuBar()
changeColour = mainMenu.addMenu("changeColour")
changeColourAction = QtWidgets.QAction("change", self)
changeColour.addAction(changeColourAction)
changeColourAction.triggered.connect(self.changeColour)
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
self.drawing = True
self.lastPoint = event.pos()
def mouseMoveEvent(self, event):
if event.buttons() and QtCore.Qt.LeftButton and self.drawing:
painter = QtGui.QPainter(self.imageDraw)
painter.setPen(QtGui.QPen(self.brushColor, self.brushSize, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
if self.change:
r = QtCore.QRect(QtCore.QPoint(), self._clear_size*QtCore.QSize())
r.moveCenter(event.pos())
painter.save()
painter.setCompositionMode(QtGui.QPainter.CompositionMode_Clear)
painter.eraseRect(r)
painter.restore()
else:
painter.drawLine(self.lastPoint, event.pos())
painter.end()
self.lastPoint = event.pos()
self.update()
def mouseReleaseEvent(self, event):
if event.button == QtCore.Qt.LeftButton:
self.drawing = False
def paintEvent(self, event):
canvasPainter = QtGui.QPainter(self)
canvasPainter.drawImage(self.rect(), self.image, self.image.rect())
canvasPainter.drawImage(self.rect(), self.imageDraw, self.imageDraw.rect())
def changeColour(self):
self.change = not self.change
if self.change:
pixmap = QtGui.QPixmap(QtCore.QSize(1, 1)*self._clear_size)
pixmap.fill(QtCore.Qt.transparent)
painter = QtGui.QPainter(pixmap)
painter.setPen(QtGui.QPen(QtCore.Qt.black, 2))
painter.drawRect(pixmap.rect())
painter.end()
cursor = QtGui.QCursor(pixmap)
QtWidgets.QApplication.setOverrideCursor(cursor)
else:
QtWidgets.QApplication.restoreOverrideCursor()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec())
這篇關于在畫布上擦筆的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!