Correct way to display a QImage with QGLWidget? - qt

How do I display a QImage in a QGLWidget? Do I have to draw a rectangle and add a texture on it or there is a better fashion?

You can use overpainting to draw a QImage over the QGLWidget, but it would certainly be faster pushing the image data out to the GPU by using the image as a texture.

Related

Drawing inside a QFrame: coordinate system

I would like to draw inside a Qt QFrame, however the QFrame will have a border. As far as I understand, the paintEvent receives a QPainter which is associated to the whole frameRect, so I will have to offset my paint operations of the border. Is this correct? Is there a way of getting a QPainter already associated to the inner part of the widget, without the (variable in size) border?
you have to consider the contentsRect contentsRect()-> Returns the area inside the widget's margins.using the return value rect of contensRect() you can restrict to draw anything inside the rect.
One way to do this would be to embed a QWidget inside the QFrame, place it in a simple QVBoxLayout layout or QStackedLayout layout with no margins and paint the QWidget instead. You'll probably get better performance if you simply offset your painting, though.

Change color of transparent image in Qt

I have a transparent image (QImage) overlayed over a video in Qt. I want to change the color of the transparent image only on clicks of button. Can some one tell me how to do this?
Thank You.
This can be done in many ways. I suggest to use QPainter to create new image. If you set SourceIn composition mode, starting image's alpha channel will be applied to any drawing that you will do. You just need to fill image with desired color.
QPixmap source_image; // should be preserved in a class member variable
QRgb base_color; // desired image color
QPixmap new_image = source_image;
QPainter painter(&new_image);
painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
painter.fillRect(new_image.rect(), base_color);
painter.end();
ui->label->setPixmap(new_image); // showing result
Note that I use QPixmap instead of QImage because QPixmaps are more efficient to display (and possibly paint). If you for some reason still want to use QImage, this code will work with QImage without any changes (excluding the last line of course).
Source image:
Result:

Qt: the fastest merging and displaying of images

I'm looking for the fastest way of:
merging (it means making one image from couple of images, putting one on other with respect to their alpha values)
display images
in Qt. This is my solution:
//------------------------------------------------------------------------------------
QImage image1 (width, height, QImage::Format_ARGB32);
QImage image2 (width, height, QImage::Format_ARGB32);
QImage image3 (width, height, QImage::Format_ARGB32);
/*
some operations with images
*/
QPainter displayPainter (this);
displayPainter.drawImage (topLeft, image1, area);
displayPainter.drawImage (topLeft, image2, area);
displayPainter.drawImage (topLeft, image3, area);
//------------------------------------------------------------------------------------
If there exists anything better, faster? I found information, that QPixmap is better for displaying it on a screen, but this:
displayPainter.drawPixmap (.)
is slower then this:
displayPainter.drawImage (.).
------------------------------------------ EDIT ------------------------------------------
I want to add that I seen this question:
What is the most efficient way to display decoded video frames in Qt?
but in my case using QGLWidget is little bit complicated. I'm using necessitas and this is not stable with paintEvent in QGLWidget. With paintGL has no problem.
Regards,
I found solution to make my code more optimal. In my case, I deal with alpha blending of multiple images. I found in documentation,
that:
"Certain operations (such as image composition using alpha blending)
are faster using premultiplied ARGB32 than with plain ARGB32."
Using:
QImage image (width, height, QImage::Format_ARGB32_Premultiplied);
instead of:
QImage image (width, height, QImage::Format_ARGB32);
improved alpha blending making it 2 times faster!
Do you have any other ideas how to make it better?
You may consider the "Image Composition Example" code available in Qt examples. It seems to be what you are looking for ?

Painting without PaintEvent and QGraphicsItem s Management

The Scenario is I am getting Rects of Images over the socket and I need to draw it in a Scrollable Canvas. at the moment I am using a QGraphicsScene and drawing using QGraphicsPixmapItem but after few times when one pixmap overlaps another there is no need to keep the bottom one. and I dont know any simple way to find out the overlapped item and delete it. so its supposed to take huge memory if overlapping goes on like this.
there exists another way out. Make a QWidget and put it in a QScrollArea now draw the QWidget using a QPainter (outside paintEvent ?). If I draw it outside paintEvent I need to inherit the QWidget and make a custom one. pass it a Pixmap and let it draw in its own paintEvent by calling update()
Any critiques ? any other Straight forward solutions there ?

Optimized Line drawing in QT

I am new to QT. i am working on the Graphics.
i am using QWidget for drawing graphics(For drawing graphics in QWidget paint event). i need to draw background and foreground graphics. Background is fixed graphics. foregrounds i am drawing lines.
Each 100 millisecond i need to draw 20points. This drawing time is 8 sec. Total i need to draw 1600 points (total points represents the contentious line).
i am using QTimer to invoke this drawing in each 100ms. first few drawing drawn very fast. in the middle of the drawing it's become slow.
the problem is i need to draw all the foreground and background in each 100ms.
Please help me to fix the problem. if any one have sample code please provide. Thanks in advance.
Is there any way to draw only partial area ie. only particular modified region of the graphics?
QPainter-drawing can be very slow without hardware support. Using QGraphicsView won't help if all lines are visible, since it internally uses QPainter anyway.
If you just have to draw 20 new points (or lines) per update and per update background gets cleared so you have to render everything again, there are few things you could try:
1) Disable background autofill. See: QWidget::autoFillBackground
Add something like this to your widget init:
setAutoFillBackground(false);
setAttribute(Qt::WA_OpaquePaintEvent, true);
setAttribute(Qt::WA_NoSystemBackground, true);
Now on the first update render background and first lines. For next updates just skip rendering background and render only new lines.
2) Use double buffering. For example, create QImage of the size of your widget.
.h
private:
QImage m_targetImage;
.cpp
// constructor
m_targetImage = QImage(width(), height(), QImage::Format_ARGB32);
// paint event
// draw to image
QPainter p;
p.begin(&m_targetImage);
static bool firstUpdate = true;
if (firstUpdate)
{
// draw background)
p.drawImage(...);
firstUpdate = false;
}
// draw latest lines
p.drawLines(....);
p.end();
// draw image in widget paint
QPainter painter;
painter.begin(this);
painter.drawImage(0, 0, m_targetImage);
painter.end();
3) Use QGLWidget if possible. Inherit your widget from QGLWidget instead of QWidget. This method doesn't work on all platforms and speed increase might not be enough. Also using OpenGL brings all kind of new problems.

Resources