6

My program generate 3 different images and I'd like to combine them using some opacity settings.

First I have the raw image, which I already converted into a QPixmap to display it in a QGraphicsView.

First Image.

Then with this image I make some calculation and generate a QImage because I need basic pixel access, I also add a legend.

Second Image.

What I'd like to do is to be able to blend the two images while being able to modify the opacity. I don't have the tools to show an example, it should look like this:

Third image

But with the first image and the data image blended with opacity. Also I'd like the legend to stay 100% visible. I can create a different QImage for the legend if it's needed.

Also I know exactly which pixel should be considered transparent instead of white if it comes to that.

In the future I would like to adjust the opacity just with a slider so I think it would be better if there was a solution that didn't involve calculating a whole new image every-time...

Any lead would be appreciated...

Leo
  • 1,129
  • 4
  • 23
  • 38

2 Answers2

3

You could use QGraphicsPixmapItem::setOpacity to set the alpha blend value in the range 0.0...1.0 for the overlay image and have separate graphics items for the background an the foreground.

If you actually need to generate a pixmap with the blended image, you can use setOpacity on QPainter before drawing the pixmap on it.

Pete
  • 4,784
  • 26
  • 33
  • I did what you suggested however I have one last problem, the white pixel of my QImage are also blended, do you know how to avoid this? I would like the white pixel to act like there were transparent. A picture of what I have now: [Picture](http://imgur.com/vEpxI) – Leo Jun 20 '12 at 15:34
  • Why don't you put the raw image over the top of the image with the legend and modify the opacity of the raw image? Or are there items in the raw image that need to be set transparent? In which case you'll need to modify the raw image to set these pixels alpha value to 0. – Pete Jun 20 '12 at 15:45
  • That's what I did but I still have the same problem: [like this](http://imgur.com/a6qWk). I change the opacity of the raw image and put the legend and data visualization underneath but the white of the last still blend with the raw image. – Leo Jun 20 '12 at 15:53
  • 2
    @Leo You should split the legend and the "overlay image" (the blue/white one). For the overlay image, replace white pixels with transparent pixels before assigning it to the graphics item. Then put the overlay above the raw image and apply the opacity. The other way around, as suggested by Pete, has the problem that the raw image has the opacity also on the parts where the overlay (which would then be below the raw image) should be transparent. Or place the raw image below (with full opacity) AND above (with partial opacity) the overlay. But you need transparency instead of white pixels anyway – leemes Jun 20 '12 at 15:54
  • so you want to change the alpha of the data part of the image over the top of the raw image and leave the raw image intact with no blending? – Pete Jun 20 '12 at 15:55
  • Yes. If we mean the same with "data part" and "overlay image". – leemes Jun 20 '12 at 15:56
  • Note that if you gonna use antialiasing at the borders of the triangle shape, you get in trouble when replacing fully white pixels with fully transparent pixels. Either don't use antialiasing (which you currently don't use), or generate it (if possible) with transparent instead of white background – leemes Jun 20 '12 at 15:57
  • Maybe it is even easier not to pre-render the overlay but do the rendering in a custom graphics item (by overriding the paint event). But this depends on how (and how fast) you can generate the overlay image. Note that the paint event can be called very often. – leemes Jun 20 '12 at 15:59
  • @leemes @Pete I did this: `qimage.fill(Qt::transparent);` instead of `qimage.fill(Qt::white);` but after the conversion from QImage to QPixmap all the transparent pixels are considered black. I'm using a `QImage::Format_RGB888` if that's of any help... – Leo Jun 20 '12 at 16:01
  • 2
    `QImage::Format_RGB888` doesn't have an alpha channel. You need `QImage::Format_ARGB32` or `..._Premultiplied`. (http://qt-project.org/doc/qt-4.8/qimage.html#Format-enum) **Note:** "Certain operations (such as image composition using alpha blending) are faster using premultiplied ARGB32 than with plain ARGB32." -- So this is exactly what you need. :) – leemes Jun 20 '12 at 16:04
  • @leemes Thanks, it works [perfectly](http://imgur.com/sZWVJ), now I just have to adjust to which image to change the opacity! – Leo Jun 20 '12 at 16:08
  • @Leo your last screenshot looks like the raw image is above the overlay. Swap them (place the overlay above the raw image) if I'm correct. In any case, apply the opacity to the *upper* graphics item. – leemes Jun 20 '12 at 16:11
  • @leemes you're correct, that's what I meant with "adjust to which image to change the opacity". But it's only minor tweaking form now on ;) – Leo Jun 20 '12 at 16:16
0

There is a QImage type that supports an alpha channel QImage::Format_ARGB32_Premultiplied which will display the two images with an opacity controlled by the alpha - simply draw the two QImages over the top of each other

But it is premultiplied so you need to adjust all the pixels if you change A

Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
  • Having to adjust all the pixels every-time I change A plus having to convert the first QPixmap to a QImage really bother me, I'd like to find something a little more efficient but I'll dig your idea if I don't find anything else. – Leo Jun 20 '12 at 15:29
  • There's no need to convert to a pixmap, the QImage display is done in HW anyway. – Martin Beckett Jun 20 '12 at 15:36
  • I don't know what HW is so I may not fully understand your sentence but which pixmap are you talking about? – Leo Jun 20 '12 at 15:40
  • @leo - sorry, QPixmap is only useful if you are drawing lots of the same small image. Otherwise you can work completely in QImage and draw QImages directly to a painter. Drawing a QImage and the blending is done in hardware (HW) ie by the graphics card so is fast if use use the ARGB32 format – Martin Beckett Jun 20 '12 at 15:42
  • I think what you propose should work but Pete's solution seems easier to implement with my code as it already is. – Leo Jun 20 '12 at 15:54