Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-109646

Insane / Madness millimeters to scene units (pixels) transformations when loading an SVG image via QGraphicsSVGItem

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P3: Somewhat important
    • None
    • 5.15, 6.4.1
    • None
    • Windows 10
    • All

    Description

      I use Qt Version: 5.15.4

      And i have an A3 sheet ( 420mm x 297mm ) in SVG format. Just a frame. When I load it to QGraphicsView->QGraphicsScene,

      from PySide import QtGui, QtCore, QtSvg
      
      scene = QtGui.QGraphicsScene()
      renderer = QtSvg.QSvgRenderer()
      data = '''<?xml version="1.0" encoding="UTF-8"?>
      <svg width="420mm" height="297mm" version="1.1" viewBox="0 0 420 297" xmlns="http://www.w3.org/2000/svg">
       <rect width="420" height="297" fill="#ffffff" stop-color="#000000" stroke="#f22b2b" stroke-width=".1"/>
      </svg>'''
      renderer.load(data.encode())
      svg = QtSvg.QGraphicsSvgItem()
      svg.setSharedRenderer(renderer)
      scene.addItem(svg)                
      svg.setPos(0,0)
      
      # This affects the picture but not the numbers in viewBoxF or boundingRect
      svg.renderer().setAspectRatioMode(QtCore.Qt.KeepAspectRatio)
      
      print(str(svg.renderer().viewBoxF()))
      print(str(svg.boundingRect()))

      I get the following data:

      svg.renderer().viewBoxF() PySide2.QtCore.QRectF(0.000000, 0.000000, 420.000000, 297.000000) svg.boundingRect() PySide2.QtCore.QRectF(0.000000, 0.000000, 1488.000000, 1052.000000) 

      I'm trying to determine how many pixels occupies one millimeter in Qt. Let's try together?

      1488/420 = 3.5428
      1052/297 = 3.5420

      What???

      How Qt does it happen that a millimeter horizontally differs from a millimeter diagonally? How does Qt manage to convert the image so crookedly...

      And yes, the sheet is depicted really crooked, but this can only be seen at high magnification ...

      This can be fixed by applying:
      setAspectRatioMode(QtCore.Qt.KeepAspectRatio)
      But it doesn't affect the numbers.

      Ok i add other SVG picture. Simple rect ( 30mm x 10mm ). And i get:

      svg.renderer().viewBoxF() PySide2.QtCore.QRectF(0.000000, 0.000000, 106.000000, 35.000000) svg.boundingRect() PySide2.QtCore.QRectF(0.000000, 0.000000, 30.000000, 10.000000) 

      Calcualte aspect ratio...

      106/30 = 3.5333
      30/10 = 3

      Wow! It's amazing! And here are completely different numbers.
      This is what happens each picture has its own individual AspectRatio???
      Moreover, each side has its own unique ...

      And now try to make some kind of QGraphicsScene in which it is implemented Snap to Grid feature...
      And you end up with something crooked and ugly. Because from the calculations it's not even clear how many pixels exactly should fit in one millimeter ...

      And the reason seems to me that when the SVG is converted, its size is rounded to the nearest integer. Notice the numbers: 1488.000000, 1052.000000

      Where does such accuracy come from? Why not 1488.5262, 1052.6543 for example?

      What to do with it? How to get accurate graphics in millimeters, not a deformed...

       
      Source code of SVG files:

      <?xml version="1.0" encoding="UTF-8"?> <svg width="420mm" height="297mm" version="1.1" viewBox="0 0 420 297" xmlns="http://www.w3.org/2000/svg"> <rect width="420" height="297" fill="#ffffff" stop-color="#000000" stroke="#f22b2b" stroke-width=".1"/> </svg>
      <?xml version="1.0" encoding="UTF-8"?> <svg width="30mm" height="10mm" version="1.1" viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg"> <rect width="30" height="10" fill="#ffffff" stop-color="#000000" stroke="#00ffbb" stroke-width=".1"/> </svg

       
      I think something in the Qt code rounds the sizes and this is basically logical if there are numbers like 200.0000000000001 , but then need to round numbers not to an integer, but, for example, to five decimal places.

      So that numbers like 123.432537675768
      are converted to 123.43254 and not 123.00000.

       

      Forum topic:

      https://forum.qt.io/topic/141706/insane-madness-qgraphicssvgitem-pixel-to-millimeter-transformations/3

       

      I'm not sure if this bug is only in Python, maybe it's repeatable through C++...

      Attachments

        1. pyside2167.py
          3 kB
          Friedemann Kleint
        2. qtbug109646.zip
          2 kB
          Friedemann Kleint
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            qt.team.graphics.and.multimedia Qt Graphics Team
            qtfc 123 789
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes