PDA

View Full Version : PNG file is not rendered properly when using as texture for QBrush



skeletor
22nd September 2010, 21:30
Hi all,

I would like to add a rectangle with a textured brush pattern to a QGraphicsScene. However, the rendering is not working out for some reason.

Here's the code where I add the rectangle to the scene.



QPixmap pixmap = QPixmap(":/images/TexturePattern.png");
QBrush brush = QBrush(QPixmap(pixmap));

mainRect = new QGraphicsRectItem(0,0,960,1300);
mainRect->setBrush(brush);
mainRect->setPen(QPen(QBrush(QColor("Gray")), 3));
mainRect->setVisible(true);
addItem(mainRect);


Here's a piece of the resulting image:
5220

I substituted my image into the Painting example Basic Shapes, (substituted texturePattern.png for Brick.png) and it seems to render just fine:
5221

Other than their using a Widget and I'm using a QGraphicsScene, I can't seem to find any difference in the code. Does anyone know why?

Thanks in advance.

wysota
22nd September 2010, 21:55
Do you do any scaling of the scene/item/view?

skeletor
22nd September 2010, 22:02
Yes, the QGraphicsView is scaled using a matrix.

wysota
22nd September 2010, 22:11
That's why your brush gets distorted - it's being scaled as well.

skeletor
22nd September 2010, 22:32
I am scaling the view by the same factor in x and y. I would expect that this would do the same to the brush, so there should be no distortions; But it appears not to be the case.

Could you suggest a way to counter the scaling on the brush, or to compensate the scaling on the pixmap so that it does not get distorted?

wysota
22nd September 2010, 22:37
I think that if you have dotted pattern on the pixmap, you will alwys get distortions if the effective scaling factor is different than 1:1. You can apply the pattern after scaling the item but it requires a bit of calculations and code writing. You'd have to reverse the scaling factor in the painting routine of the item so that you fill its area as it weren't scaled while maintaining the scale of the item itself.

skeletor
23rd September 2010, 08:13
Thanks for your ideas, but I'd rather not take that approach.

I was expecting that Qt would have this support built in somehow; if not, it seems like a bug (or pretty big limitation) to me. They should probably have mentioned this kind of limitation in the documentation for QBrush, to save me wasting so much time trying to figure out why my simple pattern wouldn't render!

I'll try to design a texture without little dots, or go with a solid fill.

wysota
23rd September 2010, 08:28
if not, it seems like a bug (or pretty big limitation) to me.
Blame God, this is a law of physics. If what you are experiencing is what I think it is (because the image you posted is quite small and I can't see the details).


They should probably have mentioned this kind of limitation in the documentation for QBrush, to save me wasting so much time trying to figure out why my simple pattern wouldn't render!
Actually you should know on your own that 1 divided by a number larger than 1 is less than 1 and "less than 0" often means "0" in computer science. This is not caused by Qt, this is caused by the fact that you scale the image. You will have the same effect if you take some graphics application and do a similar scaling there (especially if you use fast scaling algorithm).

skeletor
25th September 2010, 05:08
Thanks for clarifying. I thought you meant that only images with little dots would not be scaled properly. which seemed to match with my testing where other PNG images were being scaled down nicely. Now I understand what you meant, and can see that this file was quite small to start with, compared to others that I was working with.

I tried creating a larger version (e.g. 8 times larger), and it is scaling down better than before and is recognizable, but still gets noticeably distorted. I will just have to try to avoid using dots, which seem to be more distorted after the scaling than the other images I am working with. Or to use your other suggested coding approach.

wysota
25th September 2010, 08:54
Did you tell the view to use smooth scaling transformations (it's a render hint)? It might help a bit.

skeletor
28th September 2010, 00:15
Thank you wysota. This has solved my problem and really improved the rendering of the pattern in the brush. :D

1. Increase the original PNG file so that the pattern can physically be scaled down by the view.
2. Improve the rendering done by the view by calling setRenderHint(QPainter::SmoothPixmapTransform, true);