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:
QtWS25 Last Chance

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: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

                            12/15

                            23 Mar 2014, 12:52

                            • Login

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