Blending two different images in Qt - c++

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.
.
Then with this image I make some calculation and generate a QImage because I need basic pixel access, I also add a legend.
.
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:
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...

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.

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

Related

make background of sprite transparent in SDL

How to change background color of sprites to transparent by changing alpha after loading it to a SDL_Surface. Are there any functions in SDL which use a floodfill kind of algorithm and change all pixel with a given color to transparent on the outside. I don't want it to happen inside the border of the sprite if the same color is used.
Sample Image:
I would like to make the background blue here transparent before I blit it on the window surface using SDL_BlitSurface.
Only a color key (SDL_SetColorKey()) or a full alpha channel are going to help you here.
Note, that you can provide an alpha channel in your source graphics if you use a format such as PNG. If you only sometimes need/want an alpha, then provide the alpha channel in your source graphics and use SDL_SetSurfaceBlendMode() with SDL_BLENDMODE_NONE to blend without the alpha and SDL_BLENDMODE_BLEND to blend with it.
Both SDL_Surface and SDL_Texture support SDL_BlendMode.
Even if SDL provided another method, such as the fill you mentioned. You wouldn't want to use that. It is more difficult, expensive, and unnecessary overhead. You should stick with best practices here.
You may want to look into SDL_Texture and SDL_Renderer and switch to using a "texture atlas" instead of individual surfaces/textures for each image to maximize performance.

Add transparency when drawing a rectangle in opencv

I am trying to paint rectangles in locations which face detection algorithm locate faces. I want to use alpha transparency in order to draw my rectangles. I have found in opencv documentation the following in here: Note The functions do not support alpha-transparency when the target image is 4-channel. In this case, the color[3] is simply copied to the repainted pixels. Thus, if you want to paint semi-transparent shapes, you can paint them in a separate buffer and then blend it with the main image.
How is it possible to blend main image with buffer image? And what exactly means with buffer image?
You can use the OpenCV addWeighted function to blend your image.
Refer to the documentation of the function.
You can provide the function with the amount of transparency you want to have.
Here is an tutorial to do so.

How to set a "plain" or "flat" background color for a QTableWidgetItem

I have a QTableWidget. I want to have alternating background colors for the rows, but I can't use QTableWidget::setAlternatingRowColors because I need one color for two rows and the other one for the next two and so on (see the below image).
Thus, when I add a QTableWidgetItem, I set the according background color manually by QTableWidgetItem::setBackground().
But I don't get a "flat" or "plain" background by this, but a gradient and rounded corners:
I would like to have the background color all over the cells, without further "decoration". How can I get rid of this?
When you select a single color as the background (QBrush constructed from a QColor), the style engine tries to render a styled background, which in your case draws this gradient with border.
You can trick the style engine by using a QBrush constructed from a QImage, so the render engine draws exactly that image and nothing more. In your case, use an image with a single pixel, namely the color you want as the background. For this, construct a 1x1-sized QImage and set the color of the pixel using fill, then use that image as a brush:
// Create the image (using the default image format)
QImage img(QSize(1, 1), QImage::Format_ARGB32_Premultiplied);
// Set the color, here light gray:
img.fill(QColor(224, 224, 224));
// Apply the image as the background for the item:
item->setBackground(QBrush(img));

Qt : Smooth a circular mask. Remove Jagged edges

I am currently doing the following for putting a circular mask on my image. As a result only circular region of my image is displayed.This works fine however the image tends to have jagged edges (border). Any suggestion on how I could do this.
From the documentation of QPixmap you can learn:
The hasAlpha(), setMask() and mask() functions are legacy and should not be used. They are potentially very slow.
Apart from being slow, they operate on a binary mask (QBitmap) which does not support anti-aliasing, each pixel is either fully opaque or fully transparent. This results in jagged edges.
The solution is to manipulate the alpha channel of the pixmap directly. However, you cannot use drawing operations on a pixmap. Instead, you need to draw on the QImage before converting it via QPixmap::fromImage().
With this method, the alpha channel you manipulate has 8 bits (instead of 1) which allows antialiasing. At the edges you will find a smooth transition between fully opaque and fully transparent.
So to draw the alpha in the original QImage:
Make sure that it actually has an alpha channel, e.g. by calling img.convertToFormat(QImage::Format_ARGB32);
Initialize your QPainter on img as paint device
Set the DestinationIn composition mode on the painter; see http://qt-project.org/doc/qt-4.8/qpainter.html#CompositionMode-enum
Perform the drawEllipse operation with a white brush of a certain alpha.
I think the easiest way is:
oImage.convertToFormat(QImage::Format_ARGB32);
QImage oCircleProfileImage (oImage.width(), oImage.height(), QImage::Format_ARGB32);
oCircleProfileImage.fill(Qt::transparent);
QBrush oImageBrush(oImage);
QPainter oPainter(&oCircleProfileImage);
oPainter.setBrush(oImageBrush);
oPainter.setPen(Qt::NoPen);
oPainter.setRenderHint(QPainter::Antialiasing);
oPainter.drawEllipse(0, 0, oImage.width(), oImage.height());
Where oImage is your image you want to be in a circle.

Displaying images without the black portion

I am trying to display a bitmap using opengl but I don't want the black portion of the image to be displayed. I can do this in DirectX but not in opengl. In other words - I have images of plants with a black background and I want the plants to be drawn so they look realistic (without a black border).
You can do this using alpha-testing:
Add an alpha channel to your image before uploading it to a texture, 0.0 on black pixels and 1.0 everywhere else.
Enable alpha-testing with glEnable( GL_ALPHA_TEST )
glAlphaFunc( GL_LESS, 0.1f )
Render textured quad as usual. OpenGL will skip the zero-alpha texels thanks to the alpha-test.
There are a couple of ways you can do this.
One is to use an image editing program like Photoshop or GIMP to add an alpha channel to your image and then set the black portions of the image to a max alpha value. The upside to this is it allows you to decide which portions of the image you want to be transparent, since a fully programmatic approach can sometimes hide things you want to be seen.
Another method is to loop through every pixel in your bitmap and set the alpha based on some defined threshold (i.e. if you want true black, check to see if each color channel is at 255). The downside to this is it will occasionally cause some of your lines to disappear.
Also, you will need to make sure that you have actually enabled the alpha channel and test, as stated in the answer above. Make sure to double check the order of your calls as well, as this can cause a lot of issues when you're trying to use transparency.
That's about as much as I can suggest since you haven't posted the code itself, but hopefully it should be enough to at least get you on the way to a solution.