Menu

SVG Vectorial format

2022-03-06
2022-03-10
  • Daniel Zvinca

    Daniel Zvinca - 2022-03-06

    Hi Angus,

    This is a lovely piece of software. I just found out about just by accident and I truly like it so far.

    I was looking into the SVG application, which compiled just fine, but I didn't figure how to use the vectorial scaling advantage when the loaded image is a SVG in TImage32Panel.

    Is it any way of preserving the vectorial format by drawing into a DC using GDIPlus ? (I know is ancient, but some PDF libraries are happy when is provided a EMF which can also store GDIPLUS records). If not, is it any place I can look to maybe start implementing it myself?

    Thanks!

     
  • Angus Johnson

    Angus Johnson - 2022-03-07

    HI Daniel.
    Thank you for your very encouraging feedback

    I was looking into the SVG application, which compiled just fine, but I didn't figure how to use the vectorial scaling advantage when the loaded image is a SVG in TImage32Panel.

    The idea is to scale the vector image before rendering it, and this is easily managed by setting the image's size before loading the image from file. This may seem strange since we're all so used to loading raster images using their fixed dimensions and then scaling after loading (using a resampling routine). But with vector images, define the optimal drawing dimensions before loading by presizing the image. The vectors then scale to your preferred size (while maintaining proportionality with the original image) and then these scaled vectors are rasterized. (IOW, once loaded and rasterized, either the image's height or width will likely be less than what you had specified.) Note: the TImage32 object itself only stores images as rasterized pixels.

    Is it any way of preserving the vectorial format by drawing into a DC using GDIPlus ?

    I'm afraid I'm not following. By drawing a vector image onto any surface, you have to rasterize that vector image (and lose all vector information). However, I suspect the intent of your question is how to best use vector images so they can be drawn without need for subsequent raster scaling (that degrades image quality). I hope my comment above adequately explains how to do that.

    ps: If you're wanting to store the vector information, then that's what SVG files are for 😁. And you can easily store these as resources.

     

    Last edit: Angus Johnson 2022-03-07
  • Daniel Zvinca

    Daniel Zvinca - 2022-03-07

    Hi Angus,

    Thank you so much for your detailed answer.

    While in the mean while I sort of figured where the vectorial part ends and where the rasterization starts, and the fact the Image32 does not store the primitives information but only the last rasterized stage after each Draw task, I am still wondering how to make use of the vectorial information of a SVG in the provided panel control, enhancing the precision while zooming in. Stretching the current rendered image while zooming (see svg application), while certainly faster is not sharp, this process can benefit from a total reload of the vectorial information of a SVG (slower) using the size of the virtual zoomed screen as soon as the user interaction ends.

    PDF zooming works like that in virtually any viewer, so I assume this is doable in your Panel control as well with a few tweaks.

    ====

    As for my gdiplus rendering question, I need to replicate any of your functions which "generate paths" with a computed precision with "storing drawing primitive" information followed by gdiplus (or pdf or whatever other vectorial engine) rendering instead of img32 rasterization method. This looks like a long shot, approachable, for sure, but not immediate. More than that, many of the direct raster buffer manipulation routines might not be reproduceable in other engines so I probably need to carefully think if this is an effort which worth the trouble. 🙂

    Nevertheless I am impressed how accurate most of the SVG instructions are rendered. In case you wonder where your engine is not accurate (or it just hangs) see the following two very large svg. One loads but it has some label inconsistencies, the other one just keeps on looping somewhere, I assume, because the loading task never ends.

    https://commons.m.wikimedia.org/wiki/File:Koppen-Geiger_Map_A_present.svg (doesnt load)
    https://commons.m.wikimedia.org/wiki/File:Location_map_San_Francisco_Bay_Area.svg (rounded blue background of labels is not rendered)

    Thanks again.

     
  • Angus Johnson

    Angus Johnson - 2022-03-07

    Stretching the current rendered image while zooming (see svg application), while certainly faster is not sharp,

    Indeed. That's because the stretching is done by pixel interpolation (resampling) rather than by vector scaling and re-rendering (ie rasterizing).

    this process can benefit from a total reload of the vectorial information of a SVG (slower)

    Actually, it may be quite a bit quicker because raster scaling isn't very fast (unless using a very inferior resampler - eg nearest neighbor). And the SVG doesn't need to be reloaded, just use the TSvgReader class in Img32.SVG.Reader.pas. That only needs to parse the SVG image once and TSvgReader will render any sized TImage32 any number of times. But if you're wanting to edit SVGs , rather than simply rendering part or all of an image, then TSvgReader isn't going to be much help. In that case you'd need to find another solution. Without too much effort, you could probably modify TSvgReader and limit drawing to only part of an image (eg when zooming in) but this isn't something I'd be rushing to do myself.

    Nevertheless I am impressed how accurate most of the SVG instructions are rendered. In case you wonder where your engine is not accurate (or it just hangs) see the following two very large svg.

    Well it doesn't actually hang, it was just taking a very long time to load and draw the image (about 20mins on my PC, though in debug mode so I could see what was happening.) It is a huge SVG (77MB!) with well over 100K image elements and does take a good minute or two to load in Chrome. But all the same I'm not sure why my renderer is so slow there. Mostly Image32's SVG reader is as fast or faster than other SVG readers (eg https://github.com/EtheaDev/SVGIconImageList/wiki/Choice-of-Factories).

    One loads but it has some label inconsistencies,

    The "label inconsistencies" arise because Image32's SVG reader doesn't read embedded PNG images (which is what those labels are).

    Cheers

     
  • Daniel Zvinca

    Daniel Zvinca - 2022-03-08

    Hi Angus,

    High quality zoom for SVG worked. Thanks for the SVG.Reader tip!

    I have just one extra question. Is it any way I can control the Text rendering of the SVG, to maybe use the mentioned cleartype for standard screen resolution? It looks quite pixelated for regular font and better for larger font.

    Thanks!

     
    • Angus Johnson

      Angus Johnson - 2022-03-10

      Hi again Daniel.
      Firstly, I'm happy to hear zooming is working for you. 👍

      Using ClearType inside TSvgReader isn't feasible. ClearType is only of (limited) value when drawing text over solid colors, typically a white background. In theory it can also be done over colored and even patterned backgrounds, but it's debatable if anyone would find the text any clearer. And I really can't envisage a way to do this in SVG in a time efficient manner, and one that would justify the considerable effort.

      ps: The challenge of rendering crisp text is finally becoming less of an issue now high resolution monitors are almost mainstream. (In a couple of years ClearType, and fonts with embedded low res. raster glyphs and font hinting will no longer be needed.)

       

      Last edit: Angus Johnson 2022-03-10