Why Qt ALWAYS draw my SVG image BLURRED and UGLY?
-
In a project I need to draw the following SVG Image:
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M10.5 0.75C10.6055 0.75 10.7031 0.769531 10.793 0.808594C10.8828 0.847656 10.9609 0.902344 11.0273 0.972656C11.0977 1.03906 11.1523 1.11719 11.1914 1.20703C11.2305 1.29687 11.25 1.39453 11.25 1.5V11.25H2.0918L0.75 9.90234V1.5C0.75 1.39453 0.769531 1.29687 0.808594 1.20703C0.847656 1.11719 0.900391 1.03906 0.966797 0.972656C1.03711 0.902344 1.11719 0.847656 1.20703 0.808594C1.29688 0.769531 1.39453 0.75 1.5 0.75H10.5ZM3 5.25H9V1.5H3V5.25ZM7.5 8.25H3.75V10.5H4.5V9H5.25V10.5H7.5V8.25ZM10.5 1.5H9.75V6H2.25V1.5H1.5V9.5918L2.40234 10.5H3V7.5H8.25V10.5H10.5V1.5Z" fill="#49539B"/> </svg>
As you can see, the source SVG image contains a width and height of 12 pixels, and is surrounded by a 12x12 viewbox. I need to draw this image inside a rectangular area of 12x12 pixels. However I'm UNABLE to draw it correctly. I played around all the properties I known, there is no way: My image is ALWAYS drawn in a BLURRED and UGLY way, whatever the configuration, as you can see below:
Here is the code I used to draw this image:
Image { x: 10 y: 200 width: 12 height: 12 source: "qrc:/icon_save.svg" sourceSize: Qt.size(12, 12) fillMode: Image.Tile//PreserveAspectFit //smooth: true smooth: false antialiasing: false //mipmap: false opacity: 1.0 //cache:false visible: true }
As you can see, I already tried to set the
sourceSize
to the matching size, to turn off any kind of smooth or antialiasing, to turn on mip-mapping, to try a fill mode which not resizes the image, even to disable the caching, but no way. So my question is pretty simple: Why, by the hell, Qt persists to draw my image in a so blurred and ugly way? How should I configure Qt to render a clear and precise image? -
@Markkyboy Thank you for your answer, and to took the time to test.
However on your screenshot, the small icon is also drawn blurred, and this is exactly the issue I face: I need to draw 12x12 svg icons inside several buttons, and they are always drawn blurred and ugly, whatever the configuration. For that reason I need to tweak each button images, one by one, until find an acceptable drawing (which is generally still not perfect), and I spend a crazy time to achieve that.
So, to reformulate my question: Is there a way to draw a small image in a not blurred and ugly way? What should I do to get a clear and precise image, even if drawn in a 12x12 pixels area? Or is it a Qt Quick limitation in relation to the svg format?
-
How would you like it to be rendered?
Your icon has too much detail to not be blurry at 12x12.SVG is not a magic tool managing to render any image with crisp sharp lines. That works when scaling up, scaling down is not as simple.
Stretching the reasonning to the absurb, would you expect this svg to render a clean 4x4 icon? What about a 1x1 icon?
-
@GrecKo said in Why Qt ALWAYS draw my SVG image BLURRED and UGLY?:
Your icon has too much detail to not be blurry at 12x12.
I'm not expecting Qt to operate a miracle, I just expect it to draw an image to an acceptable quality, or at least to allow me tweak the settings a bit to give me some latitude. For example, changing the
smooth
orantialiasing
properties doesn't change nothing at all on my rendering, which is a shame in a such case. I'm aware that an icon may rarely be drawn perfectly in a such resolution, but I think that the quality should at least be a little better.Actually I get this rendering:
What I expected is something like that (in the most perfect situation):
or at least something like that (Chrome/Figma rendering):
or like that (SVGMagic rendering):
I can guarantee that the size of all the above renderings is always 12x12 pixels. As you can see, all the above renderings are clearer and more precise than the Qt one, even if not perfect. So it's theoricaly possible to get a readable icon even with a so small resolution. I'm not interested to draw a 4x4 or even 1x1 icon size, I just need to show an acceptable icon to my users :-)
So my question remains: how can I improve the rendering of my SVG image? I would be very surprised if Qt didn't offer any options to improve this, right?
-
import QtQuick 2.12 import QtQuick.Window 2.12 Window { visible: true width: 100 height: 100 title: qsTr("SVG Rendering") Row { spacing: 5 Image { width: 12 height: 12 source: "qrc:/icon_save.svg" sourceSize: Qt.size(12, 12) fillMode: Image.Tile//PreserveAspectFit //smooth: true smooth: false antialiasing: false //mipmap: false opacity: 1.0 //cache:false visible: true } Image { width: 12 height: 12 source: "qrc:/icon_save.svg" sourceSize: Qt.size(width*4,height*4) fillMode: Image.PreserveAspectFit //smooth: true smooth: true antialiasing: false //mipmap: false opacity: 1.0 //cache:false visible: true } } }
Turn smooth on, scale image to larger size so it renders in a larger space. Use preserveaspectfit to reduce to 12*12. Looks significantly crisper on my machine (Ubunut 18.04).
-
@Markkyboy I can't see anything up close anymore either. Don't feel bad.
-
@jeanmilost you might be running into the same thing that I "banged my head against" (figuratively) earlier this year.
I, too, was shocked and dismayed at the SVG behavior I saw.
Look at my happy face screenshots shown here: https://github.com/219-design/qt-qml-project-template-with-ci/pull/6
If you are experiencing something like the "before" image shown at that link, and you want to instead see something like the "after" image, then my experience will be relevant to you.
The SVG is giving "indications" to Qt to use an image buffer of the size of 12 pixels by 12 pixels. So Qt is rendering the SVG into a 12x12 bitmap, and then stretching that minuscule bitmap into a larger size, which makes it look pixelated and terrible.
This has also been discussed on the bugtracker: https://bugreports.qt.io/browse/QTBUG-44863
The key to getting the scaling that you desire is to properly set
sourceSize
. Once you learn that, it isn't too hard to manage.I went through several iterations on an Image-wrapper QML element that I now use as a drop-in replacement for
Image
throughout my QML code. The latest iteration is: https://github.com/219-design/qt-qml-project-template-with-ci/pull/32 -
@GrecKo said in Why Qt ALWAYS draw my SVG image BLURRED and UGLY?:
Stretching the reasonning to the absurb, would you expect this svg to render a clean 4x4 icon? What about a 1x1 icon?
Huh. Ok. I agree with @GrecKo .
I thought the problem was to do with scaling up (in which case setting a fixed
sourceSize
would clearly work against you).If the problem is with scaling down, then my question would be:
- have you found any software (inkscape, perhaps?) that renders it crisply at 12x12?
If yes, and if you always want it displayed at exactly 12x12, then the path of least resistance is to export the crisp 12x12 version to a PNG and use that in the app.
-
There is some mention of a "90 DPI assumption" in the bug ticket https://bugreports.qt.io/browse/QTBUG-44863
@jeanmilost it might be worth subscribing to that ticket and possibly attaching your image.
-
There is one more thing to consider: Do you adjust your SVG drawing to the corner of the pixel or the center? This does make a difference in Qt. I can't remember which is best to achieve pixel accuracy. Have look at this link https://doc.qt.io/qt-5/coordsys.html to learn about how Qt renders lines.
-
Thank to all for the replies.
@KH-219Design said in Why Qt ALWAYS draw my SVG image BLURRED and UGLY?:
The key to getting the scaling that you desire is to properly set sourceSize. Once you learn that, it isn't too hard to manage.
Indeed configuring a higher source size (e.g 24x24 pixels) seems to improve notably the rendering quality, so I will play around that to find the best possible rendering for my image.
@KH-219Design said in Why Qt ALWAYS draw my SVG image BLURRED and UGLY?:
I thought the problem was to do with scaling up (in which case setting a fixed sourceSize would clearly work against you).
I however noticed that letting Qt choose the source size, either by not configuring the
sourceSize
property or by setting it toundefined
, as suggested in the documentation, doesn't work well for such small renderings, unfortunately.@KH-219Design said in Why Qt ALWAYS draw my SVG image BLURRED and UGLY?:
@jeanmilost it might be worth subscribing to that ticket and possibly attaching your image.
Ok I'll check that
@SimonSchroeder said in Why Qt ALWAYS draw my SVG image BLURRED and UGLY?:
Do you adjust your SVG drawing to the corner of the pixel or the center?
I sincerely don't know how to do that in qml. As I changed nothing about that, the rendering should be configured with the default values, but I don't know which they are. I assume that the pen is on the top and left corner of a pixel. Do you have information about how to configure that from an
Image
component in a qml file? -
@jeanmilost said in Why Qt ALWAYS draw my SVG image BLURRED and UGLY?:
@SimonSchroeder said in Why Qt ALWAYS draw my SVG image BLURRED and UGLY?:
Do you adjust your SVG drawing to the corner of the pixel or the center?
I sincerely don't know how to do that in qml. As I changed nothing about that, the rendering should be configured with the default values, but I don't know which they are. I assume that the pen is on the top and left corner of a pixel. Do you have information about how to configure that from an Image component in a qml file?
What I meant is if the original SVG drawing is done on the center of the pixel or its corner. The only easy way I know to adjust this is to change the SVG. Just open up the SVG in a suitable editor and shift everything by half a pixel down and right.