PDA

View Full Version : How to paint an image with transparent background?



Nicho
10th December 2013, 03:47
Hi,
I am a newbie for QT.And I want to know the usual way to paint an image with transparent background by using QPainter.
eg. to paint a line on the transparent background.

Santosh Reddy
10th December 2013, 05:50
I want to know the usual way to paint an image with transparent background by using QPainter.
Background being transparent or opaque does not change the way to use QPainter. Draw the same way as if the background was opaque.

Refer DrawLine (http://qt-project.org/doc/qt-5.1/qtgui/qpainter.html#drawLine)
Refer Basic Drawing Example (http://qt-project.org/doc/qt-5.1/qtwidgets/painting-basicdrawing.html)

Nicho
10th December 2013, 06:47
Santosh Reddy,
Thank you for your reply.
I am not sure whether the way I want to implement my application is reasonable. Here I will try to explain it.Hope your advice.
I will build a viewlayer tree.For each viewlayer in the tree, I set a cache which is a QImage that I will draw all the items of the current viewlayer on.
Then at last, I render the images one by one on the root viewlayer's cache image which will be painted on the widget finally.
Based on that thought, I need to draw each image of the viewlayer as transparent.
But before I have made a test by creating a QImage and draw a line on it, like below:


void MyWidget::paintEvent ( QPaintEvent * event )
{
QImage a( width(), height(), QImage::Format_ARGB32_Premultiplied );
QPainter p;
p.begin( &a );
p.drawLine(...);
p.end();
p.begin( this );
p.drawImage( 0, 0, a );
p.end();
}

But, while resizing the widget, the image shown is muddledness.
So what shall I do?


Background being transparent or opaque does not change the way to use QPainter. Draw the same way as if the background was opaque.

Refer DrawLine (http://qt-project.org/doc/qt-5.1/qtgui/qpainter.html#drawLine)
Refer Basic Drawing Example (http://qt-project.org/doc/qt-5.1/qtwidgets/painting-basicdrawing.html)

Santosh Reddy
10th December 2013, 09:07
I don't think QImage cache will help you, draw directly on the widget instead.

Anyway if you want to go with QImage, then first fill the QImage background with transparent color, (a.fill(Qt::transparent);)

Nicho
10th December 2013, 09:24
Will there be a performance issue when to draw directly on the widget?
Because during each repainting procedure, all the things need to be re-calculated and re-drawn.

QPixmap/QBitmap/QImage which one will be better, or they are the same in my situation?



I don't think QImage cache will help you, draw directly on the widget instead.

Anyway if you want to go with QImage, then first fill the QImage background with transparent color, (a.fill(Qt::transparent);)

Santosh Reddy
10th December 2013, 10:14
Will there be a performance issue when to draw directly on the widget?
Because during each repainting procedure, all the things need to be re-calculated and re-drawn.
Do all the needed calculations in other than paintEvent() function, and paint (repaint) in the paintEvent() function. (Note there will no real performance improvement un-less calculations are done in a worker thread, but wait mostly calculations when wisely done can be included in paintEvent() it self.) Again it depends on how CPU intensive are the calculations.


QPixmap/QBitmap/QImage which one will be better, or they are the same in my situation?

Qt provides four classes for handling image data: QImage, QPixmap, QBitmap and QPicture. QImage is designed and optimized for I/O, and for direct pixel access and manipulation, while QPixmap is designed and optimized for showing images on screen. QBitmap is only a convenience class that inherits QPixmap, ensuring a depth of 1. Finally, the QPicture class is a paint device that records and replays QPainter commands.
If want to store the images as cache then QPixmap will be better option.

Nicho
10th December 2013, 10:23
Do all the needed calculations in other than paintEvent() function, and paint (repaint) in the paintEvent() function.


Yes, what I want to do with the cache is to gain that goal.So I want to draw all the things on the image before, and if nothing changed, but the paintEvent() is called , I just draw the image again.
And also, if only some viewlayer is changed, it's not needed to re-calculate the items on the other viewlayers, so I want the image cache.


If want to store the images as cache then QPixmap will be better option.

Also need to fill the QPixmap's background with transparent color firstly?

Santosh Reddy
10th December 2013, 10:31
Yes, what I want to do with the cache is to gain that goal.So I want to draw all the things on the image before, and if nothing changed, but the paintEvent() is called , I just draw the image again.
And also, if only some viewlayer is changed, it's not needed to re-calculate the items on the other viewlayers, so I want the image cache.
Sounds fair, give it a try (If you are interesrted I will recommend to measure the performance improvement because of cache)


Also need to fill the QPixmap's background with transparent color firstly?
Yes.

Nicho
10th December 2013, 13:31
Sounds fair, give it a try (If you are interesrted I will recommend to measure the performance improvement because of cache)


Yes.

But as you tell me the initialization is required, I have no enough confidence on that. I will try.