如何使QImage或QPixmap半透明 - 或者为什么setAlphaChannel已过时?

时间:2010-11-13 13:12:22

标签: qt4 transparency qpainter qimage

4.7并且喜欢在qgraphicsview上叠加两个图像。顶部的图像应是半透明的,以便透视它。最初两个图像都是完全不透明的。我期望一些功能可以为每个像素设置一个全局alpha值,但似乎没有这样的功能。最接近它的是QPixmap :: setAlphaChannel(const QPixmap& alphaChannel),但是,自Qt-4.6起,它被标记为过时。相反,手册指的是QPainter的CompositionModes,但我没有成功为我想要的不透明图像添加透明度。 有人能指出我的工作实例或分享一些代码吗?

修改 我很遗憾有一个自己的答案,现在问了几个小时后。 从这个article我发现以下代码完成了这项工作。我只是想知道这是否被认为是“更好”(通常转化为更快),而不是像素化地修改alpha值。

QPainter p; 
p.begin(image);
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
p.fillRect(image->rect(), QColor(0, 0, 0, 120));
p.end();            
mpGraphicsView->scene()->addPixmap(QPixmap::fromImage(image->mirrored(false,true),0));  

3 个答案:

答案 0 :(得分:8)

Qt's composition demo可能有点令人生畏,因为他们试图展示一切。希望演示加上QPainter documentation对您有所帮助。您想使用CompositionMode :: SourceOver并确保将图像转换为ARGB32(预乘)。来自文档:

When the paint device is a QImage, the image format must be set to Format_ARGB32Premultiplied or Format_ARGB32 for the composition modes to have any effect. For performance the premultiplied version is the preferred format.

答案 1 :(得分:8)

使用您的画家对象并设置不透明度。

void ClassName::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setOpacity(1.00);  //0.00 = 0%, 1.00 = 100% opacity.
    painter.drawPixmap(QPixmap(path));
}

答案 2 :(得分:2)

首先,对于图像的内部操作,通常需要使用QImage而不是QPixmap,因为QPixmap的直接访问功能受到限制。原因是QPixmaps存储在呈现设备上,例如, X服务器或GL纹理上的pixmap。另一方面,从QPixmap到QImage并返回是昂贵的,因为它经常导致从显卡内存复制到主内存并返回。

在我看来,你需要一个只改变像素的alpha值的操作,保持原始值不变,用于blitting。一个不优雅但有效的解决方案如下:

for (int y = 0; y < image.height() ++y) {
  QRgb *row = (QRgb*)image.scanLine(y);
  for (int x = 0; x < image.width(); ++x) {
    ((unsigned char*)&row[x])[3] = alpha;
  }
}

注意:改变QImage的每个像素要快得多,然后用painter.drawImage()做比用手绘制相应alpha的每个像素快。{/ p>