1
votes

I need to change the alpha of a QImage I have so it blends with the other QImages behind and infront of it. This needs to be toggled quickly on and off.

Previously I've had to recreate every single image and give them new colors with just a different alpha value. But now I want to retain that same original image instead of redrawing and painting it.

I'm trying to do it like this now:

QImage image;
unsigned int rgb;

for(int y=0;y<image.height();y++){
  for(int x=0;x<image.width();x++){
    rgb=image.pixel(x,y);
    image.setPixel(x,y,qRgba(qRed(rgb),qGreen(rgb),qRed(rgb),120));
  }
}

I'm getting some fairly unpredictable behavior. When I toggle the image sometimes I lose colors or the alpha isn't changed. And if the alpha did get changed when I toggle back (I hardcode the alpha 255 elsewhere instead of 120) it doesn't go back to normal.

This doesn't seem like the right way to do this anyways, it shouldn't be this difficult. It seems like there should be a single function call on an image to change the alpha but I haven't found one yet.

1
You have a typo: the second to last qRgba() argument should be qBlue instead of qRed - Frank Osterfeld
In which context do you paint the images? If you use QPainter, consider using QPainter::setOpacity when painting instead. - Frank Osterfeld

1 Answers

1
votes

If you are using the QImage in QGraphicsView or in some other QWidget, you should look into this QGraphicsEffect:

http://qt-project.org/doc/qt-4.8/qgraphicsopacityeffect.html

http://doc-snapshot.qt-project.org/4.8/qwidget.html#setGraphicsEffect

http://doc-snapshot.qt-project.org/4.8/qgraphicsitem.html#setGraphicsEffect

If you are using a QLabel, I would try this out:

#include <QLabel>
#include <QPainter>

class TransparentQLabel : public QLabel
{
     Q_OBJECT
public:
     explicit TransparentQLabel() : QLabel() {}
     ~TransparentQLabel(){}
     void setOpacity(const qreal & val)
     {
          if (this->pixmap() == null || this->pixmap().isNull())
              return;
          QPixmap result(this->pixmap()->size());
          result.fill(Qt::transparent);

          QPainter painter;
          painter.begin(&result);
          painter.setOpacity(val);
          painter.drawPixmap(0, 0, *(this->pixmap()));
          painter.end();

          QLabel::setPixmap(result);
     }
};

This next bit is only slightly related to your question, but it is nice to know. If you are layering outside of your QApplication onto the operating system, you need some things like this:

 this->setWindowFlags( Qt::WindowStaysOnTopHint |
                              Qt::FramelessWindowHint | Qt::Tool);
 this->setAttribute(Qt::WA_TranslucentBackground, true);
 this->setAttribute (Qt::WA_TransparentForMouseEvents, true);

Here is an example of this stuff in action:

http://qt-project.org/wiki/QSplashScreen-Replacement-for-Semitransparent-Images

Hope that helps.