I'm trying to draw a semi-transparent rectangle on top of an image to act as a highlight. Unfortunately, nothing I try seems to be able to perform the transparency effect I want. Instead I just get solid filled rectangles, with no transparency.
Here's what I'm doing right now:
void PageView::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QImage img=...;
painter.drawImage(0, 0, img);
...
// draw a light blue, transparent rectangle to highlight
QRect rect=...;
painter.fillRect(rect, QColor(128, 128, 255, 128));
...
}
Unfortunately, for me, this draws a solid blue rectangle, instead of the semi-transparent one I expect due to giving the QBrush an alpha value.
I've also tried drawing to an intermediate QImage or QPixMap, playing around with painter.setCompositionMode(...). No luck so far.
Thus my question: How can I convince Qt to draw a semi-transparent rectangle to my PageView?
EDIT: If it's relevant, I'm building this under Qt 4.8.1 on Windows.
The code works for me with a slight modification as it does not compile as you have it:
painter.fillRect(rect, QBrush(QColor(128, 128, 255, 128)));
NOTE:
The OP was painting the semi transparent rectangle in a loop causing the same area to be painted multiple times. This will result in an additive effect which will eventually cause that area to look the same as a solid fill.
Related
I'm looking for a fast and effective way to draw a QPixmap with QPainter, but have the pixmap appear darker then normal. Is there some sort of filter or effect that can be applied to either the QPixmap or QPainter while drawing to create this effect?
You don't have pixel access in QPixmap, so going over the pixels and darkening them is out of the question.
You can however fill a pixmap with a transparent black brush, and use a number of composition modes to further customize the result.
QPainter painter(this);
QPixmap pm("d:/test.jpg");
painter.drawPixmap(QRect(0, 0, 400, 200), pm);
painter.translate(0, 200);
painter.drawPixmap(QRect(0, 0, 400, 200), pm);
painter.fillRect(QRect(0, 0, 400, 200), QBrush(QColor(0, 0, 0, 200)));
Some of the earlier comments will leave a dark gray rectangle on your screen. Using the composition mode, will darken everything visible, yet leaving any transparent areas still transparent.
painter.setCompositionMode (QPainter::CompositionMode_DestinationIn);
painter.fillRect (rect, QBrush (QColor (0,0,0,128)));
I am using QGraphicsView and Scene over which two QGraphicsPixmap item are set.
One is showing some image, another one is having transparent pixmap which is used to show marking.
I am using qpainter to draw over a transparent qpixmap.
I am using drawline between two points with qpen having rounded point with some pen size.
Problem is:
If i load some png image, with some part of image being transparent, I want to disable marking (on marking pixmap) over transparent region of image.
Is there any way to automatically restrict area of marking of qpainter?
It would be easiest to combine your two pixmaps into a single QGraphicsPixmapItem. Then you could simply use the correct QPainter::CompositionMode, which would need to be
QPainter::CompositionMode_SourceAtop
The source pixel is blended on top of the destination, with the alpha of the source pixel reduced by the alpha of the destination pixel.
e.g.:
QPixmap markingPixmap(sourceImage.size());
markingPixmap.fill(Qt::transparent);
{ // scope for painter1
QPainter painter1(&markingPixmap);
painter1.setPen(...);
painter1.drawLine(...);
}
QPainter painter(&sourceImage);
painter.setCompositionMode(QPainter::CompositionMode_SourceAtop);
painter.drawPixmap(0, 0, markingPixmap);
(Code untested!)
Or you could even use a QBitmap, see QPainter::drawPixmap():
If pixmap is a QBitmap it is drawn with the bits that are "set" using the pens color. If backgroundMode is Qt::OpaqueMode, the "unset" bits are drawn using the color of the background brush; if backgroundMode is Qt::TransparentMode, the "unset" bits are transparent. Drawing bitmaps with gradient or texture colors is not supported.
(You would need to try if this respects the CompositionMode.)
For visual markers in an imaging application on top of images I would like to enhance the contrast of said markers by using a fill color with high contrast to the local background (e.g. inverted). This requires for the object to read its background in a QGraphicsScene.
Is there an efficient (built-in) way of doing this or does it require something like rendering the scene without the marker, reading pixels in its position and then paint() the marker accordingly?
There is no straight way to get the rendered color of some point in QGraphicsScene. You should actually render the scene and see the color. One workaround is to render the scene to a QImage and pick the color from desired pixel:
QImage image=QImage(width,height,QImage::Format_RGB32);
QPainter painter( &image );
painter.setRenderHint(QPainter::Antialiasing);
myScene->render( &painter, image.rect(),QRectF(0,0,width,height), Qt::KeepAspectRatio );
painter.end();
QColor color = QColor(image.pixel(x,y));
I am fairly new to Qt and have been doing a lot of reading and practicing exercises.
I have searched for this one quite a lot but I could not find any examples.
I have a QPixmap object to which I load a .png image.
I need to create a copy of this QPixmap with a dark mask applied to it.
Basically I want this QPixmap's image to be covered with a layer of solid black of which the opacity is set to 50%.
I know how to set the opacity of a QPixmap's image but how can I add a layer of solid black with opacity on it?
Thank you!
You can use a QPainter and you a semi-transparent QBrush to paint that dark layer onto your QPixmap.
Assuming pic is a QPixmap loaded with your image:
QPainter p(&pic);
QBrush b(QColor(0,0,0,128)); // adjust color and alpha to taste
p.setBrush(b);
p.drawRect(0, 0, 200, 200);
Effect (before/after):
vs
The opaque black border can be removed by setting an semi-transparent pen before painting.
Copy the pixmap before applying the "mask" if you want to preserve the original.
I tried to add a gradient background on my main QWidget by adding (background-image:url(images/background.png) to its stylesheet but I noticed HUGE performance drops and I haven't written any code yet.
background image is a gradient , 16bit 1x800 px png.
So my question is, how can I add a nice gradient to my QWidgets / QFrames without slowing down the program? Using only the designer.
Try this:
QPalette thePalette = this->palette();
QLinearGradient gradient(0, 0, 0, 50);
gradient.setColorAt(0, QColor(227,177,27));
gradient.setColorAt(0.25, QColor(170,177,167));
gradient.setColorAt(1, Qt::white);
QBrush brush(gradient);
thePalette.setBrush(QPalette::Window, brush);
setPalette(thePalette);
and modify freely the colors and the positions. Although that this is code, it might be useful.