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:
Forum Updated to NodeBB v4.3 + New Features

SVG Rendering and Source Size:

Scheduled Pinned Locked Moved QML and Qt Quick
15 Posts 3 Posters 9.7k Views 1 Watching
  • 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 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 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 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 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 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 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 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 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 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 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

                      • Login

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