Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Properly scaling SVG Images

Properly scaling SVG Images

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qmlsvgscaling
7 Posts 5 Posters 13.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    swegmann
    wrote on 12 Mar 2015, 10:31 last edited by A Former User
    #1

    I try to instantiate an SVG image scaled by factor 2 like this:

    Image {
        scale: 2.0
        source: "myImage.svg"
    }
    

    The issue with this version is that it looks like the image is first rendered and then scaled. Even using

    smooth: true
    

    or

    antialiasing: true
    

    didn't solve the problem at all. The only way I found for generically scalling my SVG files was the following work around:

    Image {
        // the following line causes a binding loop
        sourceSize.width: 2*width
        source: "myImage.svg"
    }
    

    This really produces the expected result but of course also prints a warning about a binding loop for sourceSize. I would prefer not to use a previously scaled image since I use the same image in different scalings in various places of the application. Also I would prefer if needn't give an explicit sourceSize.width since at that place in the QML the actual source is dynamic and the images can have different dimensions.

    Is there a nicer way to solve this problem?

    1 Reply Last reply
    1
    • ? Offline
      ? Offline
      A Former User
      wrote on 12 Mar 2015, 13:03 last edited by
      #2

      Hi swegmann!

      The following code is more an ugly trick than a solution, but at least it does what it's supposed to do and you get rid of the binding loop:

          Image {
              source: "file:///home/pw/Downloads/SVG_logo.svg"
              sourceSize: Qt.size( img.sourceSize.width*2, img.sourceSize.height*2 )
              Image {
                  id: img
                  source: parent.source
                  width: 0
                  height: 0
              }
          }
      
      K N 2 Replies Last reply 6 Mar 2020, 21:50
      2
      • S Offline
        S Offline
        swegmann
        wrote on 13 Mar 2015, 09:09 last edited by
        #3

        Hi Wieland

        Well, it's not beautiful, but it does the job ;-) Thanks for your help!

        1 Reply Last reply
        0
        • M Offline
          M Offline
          mcallegari79
          wrote on 15 Mar 2015, 14:22 last edited by
          #4

          See here: https://bugreports.qt.io/browse/QTBUG-44863

          SVG scaling is quite confusing and hackish in QML.
          Basically what you need to set is the "target" size and not the "source" size...hence the confusion.

          S 1 Reply Last reply 16 Mar 2015, 14:37
          0
          • M mcallegari79
            15 Mar 2015, 14:22

            See here: https://bugreports.qt.io/browse/QTBUG-44863

            SVG scaling is quite confusing and hackish in QML.
            Basically what you need to set is the "target" size and not the "source" size...hence the confusion.

            S Offline
            S Offline
            swegmann
            wrote on 16 Mar 2015, 14:37 last edited by
            #5

            @mcallegari79 I'm a little confused by your remark. Do you mean there actually is a property called 'targetSize'? Because I couldn't find such a property neither in Image nor in Item. Or do you mean the property 'sourceSize' should be called 'targetSize'? Because I thought, I understood how that part worked. But I didn't know how to properly get the "original" size of the SVG, multipling this by my scaling factor and applying this to sourceSize. And as it currently looks there is no nicer way than what @Wieland has shown.

            1 Reply Last reply
            0
            • ? A Former User
              12 Mar 2015, 13:03

              Hi swegmann!

              The following code is more an ugly trick than a solution, but at least it does what it's supposed to do and you get rid of the binding loop:

                  Image {
                      source: "file:///home/pw/Downloads/SVG_logo.svg"
                      sourceSize: Qt.size( img.sourceSize.width*2, img.sourceSize.height*2 )
                      Image {
                          id: img
                          source: parent.source
                          width: 0
                          height: 0
                      }
                  }
              
              K Offline
              K Offline
              KH-219Design
              wrote on 6 Mar 2020, 21:50 last edited by
              #6

              @A-Former-User said in Properly scaling SVG Images:

              Hi swegmann!

              The following code is more an ugly trick than a solution, but at least it does what it's supposed to do and you get rid of the binding loop:

                  Image {
                      source: "file:///home/pw/Downloads/SVG_logo.svg"
                      sourceSize: Qt.size( img.sourceSize.width*2, img.sourceSize.height*2 )
                      Image {
                          id: img
                          source: parent.source
                          width: 0
                          height: 0
                      }
                  }
              

              (Funny. When I clicked "reply" the forum wanted to caution me that this thread is quite old. And yet... I arrived here because I still needed to learn the sourceSize hack this many years later.)

              The code snippet above demonstrating how to fix SVG blur using sourceSize is great.

              I'm surely not the first to notice, but you can also then go "one small step further" and make a reusable custom element that will be well-behaved for scaling factors other than "2". Indeed, it should be generalized/reusable for an SVG of any size (any "native" or "starting" size) and any target size or any stretch-due-to-anchoring.

              It would look like this:

              import QtQuick 2.12
              import QtQuick.Controls 2.12
              
              Image {
                // Thanks to this hack, qml can now only DOWN-SCALE/SHRINK the SVG, which won't cause blurriness/pixelation
                sourceSize: Qt.size(
                              // first "trick" qml that the SVG is larger than we EVER NEED
                              Math.max(hiddenImg.sourceSize.width, 250),
                              // change 250 to a per-project "biggest icon in project" value
                              Math.max(hiddenImg.sourceSize.height, 250))
              
                Image {
                  id: hiddenImg
                  source: parent.source
                  width: 0
                  height: 0
                }
              }
              
              

              You can build-and-run a full working sample here. (It can also be launched simply with qmlscene).

              www.219design.com
              Software | Electrical | Mechanical | Product Design

              1 Reply Last reply
              1
              • ? A Former User
                12 Mar 2015, 13:03

                Hi swegmann!

                The following code is more an ugly trick than a solution, but at least it does what it's supposed to do and you get rid of the binding loop:

                    Image {
                        source: "file:///home/pw/Downloads/SVG_logo.svg"
                        sourceSize: Qt.size( img.sourceSize.width*2, img.sourceSize.height*2 )
                        Image {
                            id: img
                            source: parent.source
                            width: 0
                            height: 0
                        }
                    }
                
                N Offline
                N Offline
                nicwainwright
                wrote on 29 Nov 2023, 16:33 last edited by
                #7

                Solution works! We personally just made a custom component that takes desired height, divides that into width to maintain aspect ratio, and is easy to expose a bunch of times without all this boiler plate.

                Of note, the width/height set is essential, because without it, changing the source during runtime (say if a target image needed to switch from a nondirectional to right) causes an additional instance of the image to spawn. See image below

                // Need to include this as shown in original post
                width: 0
                height: 0
                

                Otherwise we get the huge version that clips out. Note: I set onSourceChanged to set color to red, so we have an idea of what the original one is and which is the artifact.
                ffe182c3-bcdd-4dc3-83ed-98f6c53aeaca-image.png

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved