我想实现一种方法,每次调用时将 QPixmap (4.8) 中每个像素的 alpha 减少 1。在调用之间,可能会向图像添加新行(alpha 为 255)。此外,我希望有一个较低的 alpha 阈值,例如 15。初始 alpha 为 0 的像素将保留该 alpha。在伪代码中:
if alpha == 0:
newAlpha = 0
else:
newAlpha = max(15, alpha - 1)
现在我想到了两种方法。第一个是转换为 QImage 和逐像素减少 alpha。然而,这有两个缺点: 性能和颜色伪影:一些像素的颜色变化很大。将生成的 qpixmap QPainting 到另一个填充有一种颜色(带有QPainter::CompositionMode_SourceOver
)的 qpixmap 时会出现伪影。这可能是由于抖动?!我尝试了两种可用的,都产生这些类型的人工制品。
QImage image = pixmap.toImage();
for (int y = 0; y < image.height(); ++y) {
for (int x = 0; x < image.width(); ++x) {
QRgb col = image.pixel(x,y);
int alpha = qAlpha(col);
if(alpha>15) {
alpha -= 1;
QRgb newCol = qRgba(qRed(col), qGreen(col), qBlue(col), alpha);
image.setPixel(x,y, newCol);
}
}
}
pixmap = QPixmap::fromImage(image, Qt::DiffuseAlphaDither | Qt::NoOpaqueDetection);
人工制品出现如下:
QPixmap screen;
...
screen.fill(Qt::transparent);
QPainter painter( &screen );
// remove anti-aliasing, which (with current composition mode) results in even stronger artefacts
painter.setRenderHints(0);
background.fill(someRandomColor);
painter.drawPixmap(0, 0, w, h, background);
painter.drawPixmap(0, 0, w, h, pixmap);
painter.end();
或者,我尝试使用 QPixmap 绘图操作映射上述伪代码。例如,QPainter 的合成模式QPainter::CompositionMode_DestinationIn
有助于降低 alpha。但我不知道如何处理阈值同时保持 0 alpha 值。
所以现在实际上有三个问题:
我可以通过 QImage 绕道避免颜色伪影吗?
或者我可以将上面的伪代码映射到纯 QPixmap/QPainter 操作吗?
对此有完全不同的想法吗?
编辑:
QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
似乎确实去除了人工制品。在它转化为QImage::Format_ARGB32_Premultiplied
人工制品之前。但现在它的性能更差