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. SVG Rendering and Source Size:

SVG Rendering and Source Size:

Scheduled Pinned Locked Moved QML and Qt Quick
15 Posts 3 Posters 9.2k 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
    Sil20
    wrote on 21 Mar 2014, 15:11 last edited by
    #1

    Hi I have troubles rendering SVG file correctely when scale is set in parent items.
    I saw maybe I should use sourcesize property but coud not figure how to use it.
    Here a sample of code that illustrat the issu. Any svg file can be used. I do not want to set "smooth:true" because of performance issue (I am rendering interface on 11 full HD screens...

    is there any leads ?

    @Rectangle
    {

    width: 800
    height: 800
    Rectangle
    {
        width: 100
        height: 100
        //Graphic
        Image {
            id: iImageFrame
            x: 16; y: 42
            source: "##.svg"
        }
    }
    Rectangle
    {
        x:150
        width: 100
        height: 100
        scale: 1.2
        //Graphic
        Image {
            x: 16; y: 42
            source: "##.svg"
            sourceSize.width: width
            sourceSize.height: height
        }
    }
    Rectangle
    {
        x:300
        width: 100
        height: 100
        scale: 0.8
        //Graphic
        Image {
            x: 16; y: 42
            source: "###.svg"
            sourceSize.width: width
            sourceSize.height: height
        }
    }
    

    }@

    1 Reply Last reply
    0
    • O Offline
      O Offline
      onek24
      wrote on 21 Mar 2014, 15:27 last edited by
      #2

      Hey,

      what exactly is the issue? Does it even display the .svg? If yes; does it scale it wrong?

      1 Reply Last reply
      0
      • S Offline
        S Offline
        Sil20
        wrote on 21 Mar 2014, 15:39 last edited by
        #3

        The scale is correct, But juste like mentionned in other posts, it is ugly, Big pixels, or aliasing issues.
        Even is scale is lower than 1 there are big aliasing issues.

        The svg is a vectorial format so I guess Qt is rendering a bitmap matrix and then apply the scale on it,

        Maybe there is a way to render the SVG correctely?

        1 Reply Last reply
        0
        • S Offline
          S Offline
          Sil20
          wrote on 21 Mar 2014, 15:42 last edited by
          #4

          I tried this :

          • it changes the scale differently in x and in Y
          • it moves the svg picture, I would expecte no modification in size not position of the svg file

          @ Rectangle
          {
          x:181
          y: 18
          width: 100
          height: 100
          border.color: "#ca1f1f"
          scale: 1.2
          //Graphic
          Image {
          x: 16; y: 42
          source: "##.svg"
          sourceSize.height:height/scale
          sourceSize.width: width/scale
          scale:1/parent.scale
          }
          }@

          1 Reply Last reply
          0
          • X Offline
            X Offline
            Xander84
            wrote on 21 Mar 2014, 19:16 last edited by
            #5

            I would say just don't scale the image then!?
            I used some custom SVG files in my latest QML app and it works great, just scale the sourceSize and don't use the scale property, that will of course re-render the SVG but unless it is a very complex SVG it should be fine even for animations.
            I think the default scale property is applied after the SVG is rasterized so it will ge "messy" even with antialiasing enabled (you know thee is an antialiasing property int he Item object, right?).

            In your last post you scale the parent rectangle of the Image, that will off course also scale the Image itself. in a real app i would just never use scale unless for some animations which end with scale:1 ... in most cases at least :)

            1 Reply Last reply
            0
            • S Offline
              S Offline
              Sil20
              wrote on 22 Mar 2014, 08:33 last edited by
              #6

              Hi,
              The thing is my Application must render real size object, on *any screen *configuration:
              10cm square must be 10cm.

              So according to the screen hardware I must scale every thing.
              And I have ~2000 objet to render, so I cannot manage this for every instance of images

              The example above is to illustrate my situation in a simplified way.

              So I thought of several leads:

              • Trigger a re-rasterisation, but how ?
              • find a way in the image instantiation using sourcesize, but how ?

              Does any one hase some advice?
              It is realla a shame that vectorial picture format can only be used as Bitmap...

              1 Reply Last reply
              0
              • S Offline
                S Offline
                Sil20
                wrote on 22 Mar 2014, 10:46 last edited by
                #7

                I found somethind interesting, in the following coe dpiratio is a global scale factor.
                Putting the following code inside EVERY instance of Image QML item seems to work.
                But This should be available inside the QT C++ code; It would be really more effectiv.

                THow I do not see yet how to do this and manage the global scale factor automaticcaly. Maybe by multiplying all parent object scale factor together or something alike.

                @onSourceChanged: recomputesmoothness();
                onStatusChanged: recomputesmoothness();
                function recomputesmoothness()
                {
                if (status == Image.Ready)
                {
                if(typeof(dpiRatio)==='undefined'){return;}
                var lw=width
                var lh=height
                sourceSize.width=widthdpiRatio
                sourceSize.height=height
                dpiRatio
                width=lw
                height=lh
                }
                }@

                Here is the complete Example code easy to test and see the results. A svg file is required
                @Rectangle
                {
                property real dpiRatio:1.2
                property real sourcesizeratio:1.2
                property bool imageswitch:false

                property string imagesource:"Images/"+(imageswitch?"fond_orange_haut.svg":"Base.svg")
                width: 800
                height: 800
                
                
                focus: true
                Keys.onPressed: {
                        console.log(event.key)
                        switch (event.key)
                        {
                        case Qt.Key_Return:
                                dpiRatio = 1.0;
                                sourcesizeratio=1.0
                                break;
                
                        case Qt.Key_Plus:
                            dpiRatio += 0.1;
                            break;
                        case Qt.Key_Minus:
                            dpiRatio -= 0.1;
                            break;
                        case Qt.Key_PageUp:
                            sourcesizeratio += 0.1;
                             break;
                        case Qt.Key_PageDown:
                            sourcesizeratio -= 0.1;
                            break;
                        case Qt.Key_End:
                            imageswitch=!imageswitch
                            break;
                
                
                
                        default :
                            return;
                        }
                }
                Text {
                    id: text1
                    x: 38
                    y: 240
                    width: 71
                    height: 34
                    text: "imagesource: "+imagesource + "\nscale Factor:"+dpiRatio+"\nsourcesizeratio: "+sourcesizeratio
                    verticalAlignment: Text.AlignVCenter
                    horizontalAlignment: Text.AlignLeft
                    font.pixelSize: 12
                }
                
                //---------------------------------------------------
                Rectangle
                {
                
                    width: 100
                    height: 100
                    border.color: "#000000"
                    Rectangle
                    {
                        anchors.centerIn: parent
                        width: 100
                        height: 100
                        border.color: "#000000"
                        //Graphic
                        Image {
                            id: iImage1
                            x: 16; y: 42
                            source: imagesource
                        }
                    }
                }
                //-----------------------------------------------------------
                Rectangle
                {
                    x:181
                    y: 0
                    width: 100
                    height: 100
                    border.color: "#ca1f1f"
                    transformOrigin: Item.TopLeft
                    scale: dpiRatio
                
                    Text{
                        x: 0
                        y: 8
                        width: 100
                        height: 13
                        text: "Imge2 SourceSize:"+image2.sourceSize.width+" "+image2.sourceSize.height+
                               "\nImge2Size:      "+image2.width+""+image2.height
                               z: 2
                    }
                
                    //Graphic
                    Rectangle
                    {
                        anchors.centerIn: parent
                        width: 100
                        height: 100
                        border.color: "#ca1f1f"
                        //Graphic
                        Image {
                            id:image2
                            x: 16; y: 42
                            source: imagesource
                
                            onSourceChanged: recomputesmoothness();
                            onStatusChanged: recomputesmoothness();
                            function recomputesmoothness()
                            {
                                if (status == Image.Ready)
                                {
                                    if(typeof(dpiRatio)==='undefined'){return;}
                                    var lw=width
                                    var lh=height
                                    sourceSize.width=width*dpiRatio
                                    sourceSize.height=height*dpiRatio
                                    width=lw
                                    height=lh
                                }
                            }
                        }
                    }
                }
                
                //-----------------------------------------------------------
                Rectangle
                {
                    x:454
                    y: 0
                    width: 100
                    height: 100
                    border.color: "#16b70a"
                    scale: dpiRatio
                    transformOrigin: Item.TopLeft
                    Rectangle
                    {
                        anchors.centerIn: parent
                        width: 100
                        height: 100
                        border.color: "#16b70a"
                        //Graphic
                        Image {
                            x: 16; y: 42
                            source: imagesource
                        }
                    }
                }
                

                }@

                1 Reply Last reply
                0
                • X Offline
                  X Offline
                  Xander84
                  wrote on 22 Mar 2014, 13:15 last edited by
                  #8

                  first Qt has real vector graphics, but if you know the technical aspects every SVG image has to be rasterized at some point because your monitor needs a raster image to display! so every program who wants to display vector images has to rasterize an image before you can see it :)

                  second actually I use a similar solution in my QML app, I have global properties to multiply a DPI factor to every size I use in QML Items, no matter if it is a Rectangle or Image or just a spacing in a ListView.. because than I can scale my app as a whole and the user can even zoom in or out the complete view as he wishes.
                  I think a feature like this is missing from QML as of now or I just didn't find a better solution but in my opinion that works great for most apps and is perfect for SVG images, text and every default QML view.

                  Also if you know android development, the XML layouts used in android use a similar concept with the device independent pixel (DIP or DP) suffix for sizes, e.g. 5dp or 42dp and 12sp for font sizes.. I simply created global properties with a factor to accomplish a very similar effect so that in QML it looks like 5dp or 42dp and 12*sp and because that are real global properties if the value changes every item that uses that factor will be rescaled with the automatic property binding. :)
                  So I never (!) use the scale property anywhere other than for animations, I hope that insight helps you a little.

                  maybe I write a blog post about it when i get some time, my app is almost finished if you want I could share some screenshots in different resolutions that you see what i mean?

                  android references:
                  http://developer.android.com/guide/practices/screens_support.html
                  http://developer.android.com/training/multiscreen/screendensities.html

                  as you may know in QML every size is absolute pixels only, so you have to apply a factor or something to archive the same effect if you want the same size on every device, no matter f desktop computer or a mobile device, because mobiles devices in general have a very high DPI count and if you leave the values in absolute pixels everything will be very small with higher DPI values :/

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    Sil20
                    wrote on 22 Mar 2014, 20:17 last edited by
                    #9

                    Thanks for the input.
                    I know vectorial format must be rasterize, but I would have prefered it was rasterized correctely, or at least easy to configure....

                    I will dig into the Declarative image source code, maybe there I could add a "Property real dpiRatio" so just adding this property trigger the mechanisme described above.

                    If someone already did such thing it will be appreciated.

                    1 Reply Last reply
                    0
                    • X Offline
                      X Offline
                      Xander84
                      wrote on 22 Mar 2014, 21:20 last edited by
                      #10

                      an easy solution would be if you just use the Screen.pixelDensity property (The number of physical pixels per millimeter), are you aware of that? if you just want your image to be 10cm on any device and not really scaleable that would be the easist way I guess.

                      If you also want it scalable you add a custom scale property and multiply that by Screen.pixelDensity!?

                      @
                      property real zoomFactor: 1.0
                      property real zoom: Screen.pixelDensity * zoomFactor

                      Image {
                      source: "..."
                      sourceSize.width: 100*zoom // because 100mm size
                      }
                      @
                      if the image is quadratic it should be fine just to set the width, the height will be scaled by QML automatically, but if you want set both :D
                      if you now change the zoomFactor property it will trigger a re-rasterization of the SVG so it should look as best as it gets.

                      maybe that is to easy for you or what is the problem with this approach?

                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        Sil20
                        wrote on 23 Mar 2014, 10:57 last edited by
                        #11

                        Hi,
                        On the project we are on QtQuick 1.1 and I do not think we have the Screen.pixelDensity feature, but that is interesting.

                        Is this available on QtQuick 2.0 ? does this works well?
                        How does "Screen.pixelDensity" get the Dpi?

                        1 Reply Last reply
                        0
                        • X Offline
                          X Offline
                          Xander84
                          wrote on 23 Mar 2014, 12:52 last edited by
                          #12

                          hey don't ask me I am no Qt developer. :D
                          if you check the doc http://qt-project.org/doc/qt-5/qml-qtquick-window-screen.html#pixelDensity-prop (since Qt 5.2 so that property is pretty new)

                          but what I can tell you is how you may be able to use the same value with older versions of Qt, I don't use the pixelDensity property myself, but have a custom C++ class that does the trick with the "QScreen class":http://qt-project.org/doc/qt-5.0/qtgui/qscreen.html (look at all the dots per inch stuff).

                          In my project I use it like this:
                          @
                          QScreen *screen = qApp->primaryScreen(); // global app pointer
                          real dipScaleFactor = screen->physicalDotsPerInch() / screen->devicePixelRatio() / m_dipNorm;
                          @
                          m_dipNorm is the value I use to normalize the scale factor, if you've read the android stuff that is always 160 DPI on android for example, of course you can use whatever value you like (e.g. 72 or 96 DPI for desktop computers).
                          I just came up with that, so if you use 96 as the "norm" that means on a screen with 96 DPI 1 pixel is 1 pixel in size and if you have a a screen with highter DPI the pixel size will be larger so that the physical size will be identical on all screens not matter the size or resolution.

                          usually you have larger values like 10 pixel so if you write 10*dp it is exactly 10 pixels on my computer (with 96 DPI) but may be 31 pixels on a smartphone with 300 DPI you know what I mean?

                          if you want to use the same value as Screen.pixelDensity you can convert the inch to millimeter (that is what the QML Screen object does):
                          @
                          qreal QQuickScreenAttached::pixelDensity() const
                          {
                          if (!m_screen)
                          return 0.0;
                          return m_screen->physicalDotsPerInch() / 25.4;
                          }
                          @
                          that replaces the "logicalPixelDensity" property, see the changelog:
                          - Screen type gained a pixelDensity property, deprecating logicalPixelDensity,
                          as logicalPixelDensity is less portable across some mobile platforms.

                          1 Reply Last reply
                          0
                          • S Offline
                            S Offline
                            Sil20
                            wrote on 23 Mar 2014, 16:26 last edited by
                            #13

                            So far I am following the lead of making a MyImae component.
                            But there is a side effect:

                            • When the source image changed
                            • The status changed to 0 then to Image.Ready
                            • But the width and height are not yet the new ones !!!
                            • SO every time I replace an image source using a different size it messes everything up.

                            If I set a timer I see that width and height are correct some times after Image.Ready.
                            How can I get the NEW dimensions of the loaded source if not using StatusChanged and Image.Ready?

                            This is the code to detect the width and height wrong values:
                            @
                            MyImageTest.qml
                            Image{
                            onSourceChanged: recomputesmoothness();
                            onStatusChanged: recomputesmoothness();
                            function recomputesmoothness()
                            {
                            if (status == Image.Ready)
                            {
                            console.log(width,height)
                            }
                            }
                            }@

                            This is the code I would like to use:
                            @MyImage.qml
                            Image{
                            onSourceChanged: recomputesmoothness();
                            onStatusChanged: recomputesmoothness();
                            function recomputesmoothness()
                            {
                            if (status == Image.Ready)
                            {
                            if(typeof(dpiRatio)==='undefined'){return;}
                            var lw=width
                            var lh=height
                            sourceSize.width=widthdpiRatio
                            sourceSize.height=height
                            dpiRatio
                            width=lw
                            height=lh
                            }
                            }
                            }@

                            1 Reply Last reply
                            0
                            • X Offline
                              X Offline
                              Xander84
                              wrote on 23 Mar 2014, 16:50 last edited by
                              #14

                              if you just want the size if the Item you might just use onHeightChanged and onWidthChanged signals, or maybe onSourceSizeChanged your have to play around a little maybe.

                              1 Reply Last reply
                              0
                              • S Offline
                                S Offline
                                Sil20
                                wrote on 23 Mar 2014, 18:02 last edited by
                                #15

                                Yes I thaught of that but so far I did not find anythingelse than the "recomputesmoothness" function and it modify the properties sourceSize.W&H and he width end eight propertie. so it is likely to engender loops...

                                • Modifiyng sourceSize.width automatically modify width :(
                                • Modifiyng sourceSize.height automatically modify height :(
                                • That is why I reset width and height to their original values in this function...

                                But you are right, I will try to dig into onSourceSizeChanged....

                                1 Reply Last reply
                                0

                                2/15

                                21 Mar 2014, 15:27

                                topic:navigator.unread, 13
                                • Login

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