Наложение двух растровых изображений с альфа-значением, используя QPainter - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь наложить 2 растровых изображения и преобразовать их в одно растровое изображение в сцене QGraphics.Оба растровых изображения прозрачны в определенных местах.Я хочу объединить карты, используя тип смеси «SourceOver», перечисленный здесь : у меня есть простой пример игрушки ниже, чтобы проиллюстрировать мою проблему, где я создал два фиктивных прозрачных растровых изображения, одно зеленое и одно синее.В действительности эти карты загружаются из изображений и закрашиваются, но этот пример воспроизводит проблему.Основываясь на этом Как добавить изображение поверх другого изображения? , я попробовал подход (закомментированные 4 строки) создать QPainter с одним из растровых изображений, а затемнарисуйте другое растровое изображение поверх него, однако это приводит к сбою программы.Любые идеи о том, как это исправить?В конце концов я хочу сохранить комбинированное растровое изображение.

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPixmap, QPainter, QPen, QBrush, QPainterPath
from PyQt5.QtCore import (QLineF, QPointF, QRectF, Qt)

class Viewer(QtWidgets.QGraphicsView):
    def __init__(self, parent):
        super(Viewer, self).__init__(parent)
        self._scene = QtWidgets.QGraphicsScene(self)
        self.photo = QtWidgets.QGraphicsPixmapItem()
        self.label = QtWidgets.QGraphicsPixmapItem()
        self._scene.addItem(self.photo)
        self._scene.addItem(self.label)
        self.setScene(self._scene)        

    def overlayMaps(self):
        blue = QtGui.QPixmap(600, 600) 
        blue.fill(QtGui.QColor(0,0,255,0))
        p = QPainter(blue)
        self.pen = QPen()
        self.pen.setColor(QtGui.QColor(0,0,255,255))
        self.pen.setWidth(10)
        p.setPen(self.pen)
        p.drawLine(0,0,600,600)


        green = QtGui.QPixmap(600, 600)
        green.fill(QtGui.QColor(0,255,0,0))            
        p = QPainter(green)
        self.pen = QPen()
        self.pen.setColor(QtGui.QColor(0,255,0,255))
        self.pen.setWidth(10)
        p.setPen(self.pen)
        p.drawLine(600,0,0,600)

        self.photo.setPixmap(blue)
        self.label.setPixmap(green) 

        resultPixmap = QtGui.QPixmap(self.photo.pixmap().width(), self.photo.pixmap().height())
#        resultPainter = QtGui.QPainter(resultPixmap)
#        resultPainter.setCompositionMode(QtGui.QPainter.CompositionMode_SourceOver)
#        resultPainter.drawPixmap(300,300, self.photo.pixmap()) 
#        resultPainter.drawPixmap(300,300, self.label.pixmap()) 


    def saveOverlayMap(self):
        pass          

class Window(QtWidgets.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.viewer = Viewer(self)
        self.viewer.overlayMaps()

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.setGeometry(500, 300, 600, 600)
    window.show()
    sys.exit(app.exec_())

1 Ответ

0 голосов
/ 22 ноября 2018

Я реализовал функцию, которая выполняет действие объединения в зависимости от режима, для лучшего понимания я переместил элементы.

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

def join_pixmap(p1, p2, mode=QtGui.QPainter.CompositionMode_SourceOver):
    s = p1.size().expandedTo(p2.size())
    result =  QtGui.QPixmap(s)
    result.fill(QtCore.Qt.transparent)
    painter = QtGui.QPainter(result)
    painter.setRenderHint(QtGui.QPainter.Antialiasing)
    painter.drawPixmap(QtCore.QPoint(), p1)
    painter.setCompositionMode(mode)
    painter.drawPixmap(result.rect(), p2, p2.rect())
    painter.end()
    return result

class Viewer(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
        super(Viewer, self).__init__(parent)
        self._scene = QtWidgets.QGraphicsScene(self)
        self.setScene(self._scene)  

        blue = QtGui.QPixmap(100, 100) 
        blue.fill(QtCore.Qt.transparent)
        p = QtGui.QPainter(blue)
        pen = QtGui.QPen(QtGui.QBrush(QtGui.QColor(0,0,255)), 10)
        p.setPen(pen)
        p.drawLine(0, 0, 100, 100)
        p.end()
        self.photo = self._scene.addPixmap(blue)

        green = QtGui.QPixmap(100, 100)
        green.fill(QtCore.Qt.transparent)            
        p = QtGui.QPainter(green)
        pen = QtGui.QPen(QtGui.QBrush(QtGui.QColor(0, 255, 0, 255)), 10)
        p.setPen(pen)
        p.drawLine(100, 0, 0, 100)
        p.end()
        self.label = self._scene.addPixmap(green) 
        self.label.setPos(200, 0)     

        self.overlayMaps()

    def overlayMaps(self):
        p1 = QtGui.QPixmap(self.photo.pixmap())
        p2 = QtGui.QPixmap(self.label.pixmap())

        result_pixmap = join_pixmap(self.photo.pixmap(), self.label.pixmap())
        self.result_item = self._scene.addPixmap(result_pixmap)
        self.result_item.setPos(100, 200)

        result_pixmap.save("result_pixmap.png")

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = Viewer()
    window.resize(640, 480)
    window.show()
    sys.exit(app.exec_())

enter image description here

result_pixmap.png

enter image description here

...