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 ?
Related
I have a 4 channel png image with 8x8 Pixels that is loaded by a QImage. The QImage is then scaled by a factor of 200, so the image will have a new resolution of 1600x1600, each original pixel having a size of 200x200. But when this image is added to a QLabel through the means of a QPixmap and shown on screen, the drawn pixels will have slightly different sizes.
I've taken screenshots with Gimp and looked at the painted image more closely. It seems that every other pixel is slightly bigger than it should be, 201 instead of 200 pixels wide for example. The very last pixel in a row will then be smaller to compensate, so that the entire image has the correct size in the end.
This does not happen for all scaling factors, 100 is fine for example and so are factors that are a power of 2, such as 256.
My original approach was using a QGraphicsView and a QGraphicsPixmapItem in which case I scaled the GraphicsItem instead of the image. The effect was the same.
What effect am I seeing here? And what, if anything, can be done about it?
The code to reproduce this issue is very straightforward
int scale = 200;
image = QImage("some image file");
QPixmap pixmap = QPixmap::fromImage(image.scaled(image.size() * scale));
some_label->setPixmap(pixmap);
Turns out the easiest solution to my problem is to use QOpenGLWidget in the QGraphicsView:
setViewport(new QOpenGLWidget);
This single line in the constructor will result in much higher precision when scaling an image with the caveat of adding OpenGL as a dependency.
Another gotcha with this approach is that calling setViewport invalidates many of the settings done on a QGraphicsView. So if the view is set up in a UI file, as in my case, make sure to call other setters after calling setViewport.
I could not find a better solution that would work without OpenGL, short of writing my own rasterizer of course.
I have a QImage and a QPainter that paints on this image. After painting I tried to insert this QImage to QTextDocument with QTextCursor's insertImage method :
QImage image(width ,height,QImage::Format_RGB32);
QPainter paint;
paint.begin(&image);
paint.drawText(25,25,someText);
paint.end();
QTextCursor cursor(doc);
cursor.movePosition(QTextCursor::End);
cursor.insertImage(image);
But after doing this what I got is a text with a low resolution or a line width saggy pixels like in this image :
!(http://imgim.com/4698inciz7774617.png)line image
I tried setting QTextDocument's layout's paint device but it gave an error because of null pointer, this is most probably because of the document does not have a layout
I tried setting render hints of painter but it does not work too.
I inserted some html before the image in the document but they are good in terms of resolution, also there are no problem in flat lines.
When I show this document in a QTextEdit it seems fine, but when this is in a pdf file in a preview or something something goes wrong.
My printer is defined like that in preview :
QPrinter printer(QPrinter::HighResolution);
QPrinter highprinter(QPrinter::ScreenResolution);
printer.setPaperSize(QPrinter::A4);
And I call QTextDocument's print method for printing.
Do you have any solutions for this?
thanks
Saggy pixels can be eliminated somehow with : QPainter::setRenderHint(QPainter::Antialiasing, true); however it seems it does not eliminate saggy pixels in letters very much.
Other way of eliminating saggy pixels fully is creating a document with large pixel sizes (resolution) and increasing size of the image.After that we can increase font point size and line widths it prevents aliasing as I saw in my trials.
//increasing line width when drawing line
paint.setPen(QPen(Qt::gray,20, Qt::SolidLine, Qt::RoundCap, Qt::MiterJoin));
//increasing font's point size when using text
qFont2.setPointSize(100);
paint.setFont(qFont2);
However increasing font point size does not prevent aliasing when the image's pixel size (resolution) remains same
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:
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.
I am able to paint a pixmap by using QPainter::drawPixmap, but I am having trouble with the sizing. The pixmap is being drawn onto many different scenes. Some of the scenes are very large, and some are very small. This results in the pixmap drawn being either looking very large or very small, depending on the size of the scene (or viewport, whatever its called). I need the pixmap to look the same size everytime, regardless of the dimensions of the scene it is being placed into.
Basically, I want it to work similar to drawPoint, where you can specify the length and width of the point in pixels, so the point looks the same size every time.
The following line of code is inside my paint function of the QGraphicsItem I subclassed:
painter_p->drawPixmap( pos(), MYPIXMAP );
with pos() returning the QPointF I need to draw the pixmap at.
Can't you use QGraphicsPixmapItem? It'd do exactly what you want.