Blending two different images in Qt
Asked Answered
L

2

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...

Leia answered 20/6, 2012 at 14:46 Comment(0)
S
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.

Schulman answered 20/6, 2012 at 15:28 Comment(13)
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: PictureLeia
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.Schulman
That's what I did but I still have the same problem: like this. 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.Leia
@Leia 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 anywayMiscellaneous
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?Schulman
Yes. If we mean the same with "data part" and "overlay image".Miscellaneous
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 backgroundMiscellaneous
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.Miscellaneous
@Miscellaneous @Schulman 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...Leia
QImage::Format_RGB888 doesn't have an alpha channel. You need QImage::Format_ARGB32 or ..._Premultiplied. (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. :)Miscellaneous
@Miscellaneous Thanks, it works perfectly, now I just have to adjust to which image to change the opacity!Leia
@Leia 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.Miscellaneous
@Miscellaneous 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 ;)Leia
A
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

Abbacy answered 20/6, 2012 at 15:20 Comment(5)
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.Leia
There's no need to convert to a pixmap, the QImage display is done in HW anyway.Abbacy
I don't know what HW is so I may not fully understand your sentence but which pixmap are you talking about?Leia
@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 formatAbbacy
I think what you propose should work but Pete's solution seems easier to implement with my code as it already is.Leia

© 2022 - 2024 — McMap. All rights reserved.