0

我正在使用 PyQt,并且已将图像从磁盘加载到QPixmap. 我还创建了一个面具,使用:

self.mask = QImage(self.image.width(), self.image.height(), QImage.Format_Mono)
self.mask.fill(0)

我想将两者结合起来进行显示,这样当我渲染它时,遮罩中的任何黑色像素都会在图像上以半透明的红色绘制。

我创建了一个自定义小部件,它在绘制事件中呈现图像,如下所示:

def paintEvent(self, event):
    p = QPainter(self)
    r = event.rect()

    p.drawPixmap(r, self.image, r)

这工作正常。我不太清楚的是如何获取蒙版中的数据并仅在目标图像中的那些像素上绘制半透明红色。

我尝试将蒙版变成剪切区域,如下所示:

mask = QPixmap.fromImage(self.mask.createMaskFromColor(self.mask.color(0)))
p.setClipRegion(QRegion(mask))

color = QColor(255, 0, 0, 128)
p.setPen(Qt.NoPen)
p.setBrush(QBrush(color))
p.drawRect(r)

...但它不绘制任何东西(如果我不调用,它会在整个图像上绘制一个半透明的红色框setClipRegion)。

我还尝试将蒙版创建为QImage.Format_ARGB4444_Premultiplied, 并使用透明度。虽然这确实有效,但我可以在我的程序中编辑遮罩(并验证遮罩的某些部分是透明的,而某些部分是不透明的)该self.mask.createAlphaMask()方法返回一个纯白色矩形。

“创建掩码”方法实际上有什么作用吗?

4

1 回答 1

2

要么改变你的面具的设计,要么根据你的面具创建一个新的 QImage。然后在目的地上绘制 QImage。它不仅是一种有效的方法,而且是一种比绘制单个像素或某事更快的方法。相似的。我尝试了几种方法,这是迄今为止最快的(在 QGLWidget 上)。

这个想法是您直接在 QImage 中编码透明度以及未标记的像素,如下所示:

QImage dest(<width>, <height>, QImage::Format_ARGB32);
dest.fill(qRgba(0, 0, 0, 0));
for (int y = 0; y < <height>; ++y) {
    QRgb *destrow = (QRgb*)dest.scanLine(y);
    for (int x = 0; x < <width>; ++x) {
        if (<should be marked>)
            destrow[x] = qRgba(255, 0, 0, 127);
    }
}
painter.drawImage(0, 0, dest);

作为参考,请查看此处的代码:

https://sourceforge.net/p/gerbil/svn/60/tree/trunk/gerbil-gui/bandview.cpp#l59

于 2012-11-01T00:42:00.893 回答