PDA

View Full Version : Zooming a qimage on a QGraphicsItem



paolom
22nd June 2010, 11:59
Zooming a qimage
Hi,

I've a graphicsItem with a qimage.

I need zooming this item but i want maintain the original size of the qimage.

I use the QTransform scale.

It's ok.

Now, I need to use the smooth transformation when I zoomIn the item.

I think it's impossible with QTransform. I try with many way, but I can't do it.

Does anybody know a way to make this?

PS. I need to use the QTransform() cause this Item can have a child items, and in this mode I can resize all.

aamer4yu
22nd June 2010, 12:21
May be you can used QStyleOptionGraphicsItem::levelOfDetail and render your item accordingly...

paolom
22nd June 2010, 13:43
May be you can used QStyleOptionGraphicsItem::levelOfDetail and render your item accordingly...

Yes, but I need to draw the QImage of the item with the Qt::SmoothTrasformation. The renderHint of the painter doesn't make the correct smoothing.

Any ideas?

high_flyer
22nd June 2010, 14:35
Are you scaling the QImage directly,or do you scale your graphics view object which holds your QImage (which I guess is a QPixmap at that point already)?

paolom
22nd June 2010, 14:41
Are you scaling the QImage directly,or do you scale your graphics view object which holds your QImage (which I guess is a QPixmap at that point already)?

No. the QGraphicsItem contains a QImage. The bounding rect of the item is the rect of the QImage.

I can't use a QGraphicsPixmapItem cause I use this object in a thread.

I can't use a QPixmap on the GUI ( from a conversion to QImage) cause the time to convert is too much for me.

My item as a number of child items. I can zoom the image and its children with the transform. and It's very easy! But in this mode I can't smooth the qimage on high resolution cause the size of the qimage is always the same.

I hope that you can understand my bad english.

Waiting for you reply

high_flyer
22nd June 2010, 14:52
the QGraphicsItem contains a QImage.
This is something I don't quite understand, since QImage is not a visible object.
Can you show the relevant code of the QImage integration,and its painting?

paolom
22nd June 2010, 14:55
This is something I don't quite understand, since QImage is not a visible object.
Can you show the relevant code of the QImage integration,and its painting?




void ImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED ( option )
Q_UNUSED ( widget )

// Draw the image

painter->drawImage(_rect,_qImage); // _qImage is a member of the class
}

QRectF ImageItem::boundingRect() const
{
return QRectF(_rect); // _rect is the rect of the QImage
}

high_flyer
22nd June 2010, 15:03
I see.
I think the problem has to do with the fact, that _rect does not change, and QGraphics View just scales what ever is already drawn.
So if the original QImage is drawn in factor X,and later you scale your item x2 for example, it will just stretch the small QImage.
Thats because the size of the item has not changed. (scaling in the scene doesn't change the size of the items)
You have to scale your image when you scale your item, and force the item to redraw,this will probably give you what you want.

paolom
22nd June 2010, 15:09
I see.
I think the problem has to do with the fact, that _rect does not change, and QGraphics View just scales what ever is already drawn.
So if the original QImage is drawn in factor X,and later you scale your item x2 for example, it will just stretch the small QImage.
Thats because the size of the item has not changed. (scaling in the scene doesn't change the size of the items)
You have to scale your image when you scale your item, and force the item to redraw,this will probably give you what you want.

Yes, in fact my problem is this!!

To scale an Item and It's children I use the QTransform.

With the QTransform my item ( so the QImage ) will scaled without smoothing cause the scale transform doesn't change the size of the qimage.

The advantage of the use of the QTransform is that it scale the children ( text item or line item ) automatically.

If I don't use the QTransform to scale my item and I scale the QImage manually ( with the scaled function ) I obtain the item with the smoothing image, but in this mode the children doesn't scale !!!
I need to scale him manually !!!

My question is: is it possible to use the QTransform whit an Item with QImage and obtain in some way the smoothing ???

I hope now it's all more clear.

Thanks

high_flyer
22nd June 2010, 15:18
The Graphics View scaling is only a "view effect",it doesn't change the sizes of the items, it only calculates (behind the scenes) how to draw them in any given factor.
You have to resize your QImage manually if you want the QImage to be correctly drawn.
What you can do for that would be to use the various mapToScene() mapFromScene() etc, to get the real pixel size of the rect, and give that rect to the painter.
Again, you will have to force the redraw of your QImage with the new rect for that, every time you scale, at least when you scale to a larger factor.

high_flyer
22nd June 2010, 15:20
It just occurred to me, that you can do something else:
You can draw your QImage in its largest possible size, then it will always look correct, unless you scale it beyond its real size.

paolom
22nd June 2010, 15:21
It just occurred to me, that you can do something else:
You can draw your QImage in its largest possible size, then it will always look correct, unless you scale it beyond its real size.

It's a solution, but the occupation in RAM is very high !

high_flyer
22nd June 2010, 15:25
Then just use the larges possible image that your screen can show.
If its not a BMP, it should not be larger the 500KB in average, and any modern PC can handle it.

If its not an option for you, then you have to do what I wrote before.

paolom
22nd June 2010, 23:06
I obtain a solution with this code. Do you think is it a possible good solution for my goal?



QVariant ImageItem::itemChange(GraphicsItemChange change, const QVariant &value)
{
if(ItemTransformHasChanged == change && parentItem() )
{
QTransform trans = transform();
QRectF rect = trans.mapRect(boundingRect());

if ( rect.size() != _rect.size() )
{
// getOriginalQImage(false,false) return the original size QImage

_qImage = getOriginalQImage(false,false).scaled(rect.size(). toSize(),
Qt::KeepAspectRatio,
Qt::SmoothTransformation);
}

}

return QGraphicsItem::itemChange(change,value);
}

void ImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED ( option )
Q_UNUSED ( widget )

// Draw the image

painter->drawImage(_rect,_qImage); // _qImage is a member of the class
}

QRectF ImageItem::boundingRect() const
{
return QRectF(_rect); // _rect is the rect of the QImage
}

high_flyer
23rd June 2010, 08:47
Its hard for me to say if it is good, since I don't know what the application restrictions are.
But it looks ok, and if it works for you, then great!