Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Image Conversion: SVG to PNG

by kcott (Archbishop)
on Apr 23, 2017 at 08:12 UTC ( [id://1188664]=perlquestion: print w/replies, xml ) Need Help??

kcott has asked for the wisdom of the Perl Monks concerning the following question:

I'm generating some fairly basic SVG files and will want to convert them to PNG format. Each SVG file will be used to create a number of PNG files of different sizes (it's only a size change; aspect ratio, colours, etc. all remaining the same). I'd also like the solution to be as portable as possible (at least working on *nix and MSWin platforms). I've included my investigations so far, my questions are at the end.

Here's the test SVG file, test.svg, that I've been playing with and referenced in various examples below:

I had the ImageMagick® convert utility available, so I tried that first. This seemed to work fine; I tested at two reduced sizes:

$ convert test.svg -resize 16x16 test016.png $ convert test.svg -resize 32x32 test032.png

However, when I looked into installing the Image::Magick module for use in my scripts, I was amazed to find only failures (UNKNOWN: 1276; FAIL: 412) in the "CPAN Testers Matrix: PerlMagick 6.89-1". I followed the links to the previous five releases, thinking maybe there was some problem with just 6.89-1; unfortunately, all were exactly the same except for 6.86 which had just one PASS amongst hundreds of failures. I don't know if that's some sort of reporting error. I chose not to follow that path any further.

I had previously, successfully installed GD, so I decided to look into that further. I browsed the GD::Convert, GD::SVG and SVG modules. While this looked like it might work (after a fashion), it didn't seem particularly straightforward and even the documentation says:

"GD::SVG may provide a short-term solution while scripts are re-written to enable more direct output of SVG."

There were also too many caveats for my liking, so I abandoned this avenue also.

SVG has a small section on converting to PNG. It mentions Image::Magick and also Image::LibRSVG. I hadn't heard of this other module before and decided to try it. It installed without any fuss and usage was totally uncomplicated:

$ perl -wMstrict -MImage::LibRSVG -e 'Image::LibRSVG::->new()->convert +AtSize("test.svg", "test016.png", 16, 16)' $ perl -wMstrict -MImage::LibRSVG -e 'Image::LibRSVG::->new()->convert +AtSize("test.svg", "test032.png", 32, 32)'

Not only that, but it produced PNG files that were substantially smaller than those produced by convert (without any noticable degradation of image quality; in fact, the 16x16 one looked a little crisper). I had renamed the files I produced earlier (*.png to *_via_convert.png), here's a size comparison:

-rw-r--r-- 1 ken staff 678 Apr 23 13:03 test.svg -rw-r--r-- 1 ken staff 124 Apr 23 14:01 test016.png -rw-r--r-- 1 ken staff 316 Apr 23 13:10 test016_via_convert.png -rw-r--r-- 1 ken staff 186 Apr 23 13:57 test032.png -rw-r--r-- 1 ken staff 415 Apr 23 13:11 test032_via_convert.png

My only concerns with Image::LibRSVG are its age (no update in 11 years) and no successful builds on MSWin. The age may not be a huge issue: SVG has been stable for many years and, as an interface to the librsvg library, it may rely on that library being current, especially if its API hasn't changed. I randomly checked many failures on "CPAN Testers Matrix: Image-LibRSVG 0.07": all (going back to Perl 5.10) were UNKNOWNs, and all failed due to the librsvg library not being found — this may not be a problem either.

So, after all that, I have these questions:

  • Has anyone successfully installed Image::LibRSVG on an MSWin platform? If so, were there any major hurdles to overcome? [A Super Search for Image::LibRSVG produces no results.]
  • Does anyone have any suggestions for other modules which I could try for this conversion task?

— Ken

Replies are listed 'Best First'.
Re: Image Conversion: SVG to PNG
by syphilis (Archbishop) on Apr 23, 2017 at 09:44 UTC
    Has anyone successfully installed Image::LibRSVG on an MSWin platform?

    I just have - and it builds ok, and passes its 27 tests.

    Native Win32 LibRSVG libraries (both 32-bit and 64-bit) are available via MSYS2 pacman - and these are what I used.
    During the compilation phase there are a number of warnings about the presence of deprecated symbols (in LibRSVG.xs) such as g_type_init, rsvg_pixbuf_from_file_at_size, rsvg_pixbuf_from_file_at_zoom, rsvg_pixbuf_from_file_at_zoom_with_max, and maybe some others as well.
    Apart from that, the build proceeds fine, but the module initially wouldn't load for me because of incompatibilities between the libstdc++-6.dll that gets loaded (by perl at startup) and the libstdc++-6.dll that glib requires (which is located inside MSYS2 - and won't get loaded because libstdc++-6.dll has already been loaded).

    The MSYS2 glib libraries are built using (I think) mingw64 ports of gcc-5.4.0. If your Windows perl was built using gcc-5.4.0 (and mine wasn't) then it will probably all work without any need to do the hurdling (with two twists and pyke) that I need to do.
    Basically - I just rename the dlls to something unique, and alter the glib dlls to load the renamed versions. (It's the only way I know of getting around the problem.)

    If you want a ppm package just let me know and I'll upload one - or, if you need help building Image::LibRSVG from source on Windows, just sing out.
    (I'll probably create and upload PPM packages for this module anyway, now that I've built it.)

    Update: PPM packages for Image-LibRSVG-0.07 have now been added to sisyphusion repo.
    Well ... that filled in the evening quite effectively.
    (If anyone testing this PPM package finds a problem, please let me know.)

    Cheers,
    Rob

      G'day Rob,

      Many thanks for testing the Image::LibRSVG installation and providing such detailed feedback.

      I'll wait for other replies but, in the absence of any better ideas, and given the PNG files Image::LibRSVG produces are well under half the size of those from convert, I'll probably go with this module.

      Thanks also for offers of help with a PPM package and Windows build. My current, day-to-day OS is Mac OS X — which is where I'll do the initial development — but, when written, the code will also be used on a Windows platform: that's some way off at this stage.

      — Ken

        Thanks also for offers of help with a PPM package and Windows build

        A little extra FYI:
        I ran a "ppm install" of Image-LibRSVG on "strawberry-perl-ld 5.24.0.1 #1 Wed May 11 11:19:43 2016 x64" (MSWin32-x64-multi-thread-ld) and ran your one-liners on the first svg file that came to hand.
        The generated png files look fine to me.

        Cheers,
        Rob

      If you want a ppm package just let me know and I'll upload one - or, if you need help building Image::LibRSVG from source on Windows, just sing out. (I'll probably create and upload PPM packages for this module anyway, now that I've built it.)

      But but but http://www.sisyphusion.tk/ppm/Image-Magick.ppd

      :P

Re: Image Conversion: SVG to PNG
by haukex (Archbishop) on Apr 23, 2017 at 09:47 UTC

    I would recommend ImageMagick, I've always had good experiences with it. It's been a while since I did this last, so most of this is IIRC: PerlMagick is "different" in that installing it from CPAN is probably not the way to go. Under Windows, the installer should install the modules for you, and under *NIX, use the system's package manager to install it into the system Perl, or follow the instructions for building from source (ImageMagick, PerlMagick). On Debian-based systems, one easy way to install all the build dependencies is sudo apt-get build-dep perlmagick.

      G'day haukex,

      Thanks for your feedback, links and recommendations.

      Yes, it certainly seems like "CPAN is probably not the way to go". I'm using Mac OS X, so don't have apt-get/yum/rpm/whatever; however, the "ImageMagick: Perl Installation" seems straightforward enough (I'm certainly no stranger to the tar-configure-make incantation). My MSWin requirement is for additional deployment.

      At this point, I'm strongly leaning towards Image::LibRSVG, mainly because of the substantial file size saving. I'll keep ImageMagick in mind as a backup alternative.

      — Ken

Re: Image Conversion: SVG to PNG
by Corion (Patriarch) on Apr 24, 2017 at 08:37 UTC

    I don't use a module, but I also don't have hard-core conversion requirements.

    I invoke Inkscape from the command line as

    my $cmd = qq{"$inkscape" -D "--export-png=$tempfile" --export-text +-to-path --without-gui "$source"};

    This is somewhat slow as I have to relaunch the Inkscape process often, but after I moved to make respectively Decision::Depends, that is only needed when the input SVGs actually changed.

    If you're already battling with ImageMagick, using something else might be a way to keep more of your sanity.

      Inkscape has good quality output, so if you only need to generate the graphics at build or configuration time, this is a good solution. Unfortunately it doesn't quite scale up for interactive CGI use!

        Iirc inkscape.exe is just a py2exe python program -- shouldnt take much code to daemonize it 💩

      G'day Corion,

      I did, in fact, look at Inkscape only a few days ago. This was more out of curiousity than anything else, as I don't actually need a tool to generate the SVG. I was put off by some of the issues with Mac OS X: none insurmountable but sufficiently annoying (for me, at any rate) that I didn't investigate further. I wasn't aware of the command line and export facilities: thanks for pointing those out — maybe I'll take another look.

      Actually, curiousity grabbed me again. I did a little more investigating (in the middle of replying) and found the manpage. It would appear that the first command line from my OP:

      $ convert test.svg -resize 16x16 test016.png

      could be written, using Inkscape, as:

      $ inkscape -z -e test016.png -w 16 -h 16 test.svg

      That seems fairly painless. It's also completely untested as I haven't installed Inkscape. Having to "relaunch the Inkscape process often" is a concern.

      No, I'm not battling anything at this point. I'm really just at the requirements analysis stage and searching for the best tools. My sanity, at least for now, remains intact; but thankyou for your concern. :-)

      — Ken

Re: Image Conversion: SVG to PNG
by RonW (Parson) on Apr 24, 2017 at 21:47 UTC

    Try using the -quality option for convert.

    Since the PNG standard uses lossless compression, the -quality option instead controls compression level and the type of filtering, as described in the documentation.

      G'day RonW,

      Thanks for pointing out the -quality option and providing the link.

      I had initially just looked at the manpage from the command line (i.e. man convert). That's incredibly terse. Literally hundreds of options with no more than a handful of words about each. Here's the entry for -quality:

      -quality value JPEG/MIFF/PNG compression level

      On the other hand, the online documentation has an entire screenful of information about -quality. I had a quick glance through, the other options also appear to have a similar plethora of information. That's handy to know: often, the online versions are just a copy of the command line ones.

      — Ken

        With many projects, the "man page" is treated as "quick reference" documentation, so often focus on "reminding" the experienced user what the various options are. Unfortunately, this results in man pages that are minimally helpful to new users (of the tool in question). In this case, it's even more confusing because the -quality option actually affects more than 1 option to the underlying algorithms (which options being dependent on the algorithm in question).

Re: Image Conversion: SVG to PNG
by Anonymous Monk on Apr 23, 2017 at 08:37 UTC

      Thanks for the heads-up regarding convert.exe. I don't work with images that often but have used convert (i.e. the *nix version) from time to time for ad hoc format conversions and occasional resizing. It would be handy, even if only used infrequently, to have that functionality available on a Windows platform also.

      It looks like I'll probably go with Image::LibRSVG, but thanks anyway for the ImageMagick links.

      — Ken

Re: Image Conversion: SVG to PNG
by vrk (Chaplain) on Apr 24, 2017 at 08:26 UTC

    Thanks for asking this question! At $work many years ago, I faced this same issue and ended up writing my own, half-finished graphics abstraction layer. The layer allows plotting certain types of planar graphs with a GD backend and a separate SVG backend -- the latter is another bespoke module, because there wasn't anything suitable in CPAN back then... Our code sadly isn't suitable for CPAN, because it solves a very narrow problem and we don't have the resources to polish and maintain it as an external product.

    It's a bit sad that things haven't moved on and rasterising SVGs in Perl is still on such a shaky ground. We ruled out Image::LibRSVG back in 2008 due to code quality concerns and compilation problems on Windows. I didn't know about GD::SVG, though.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1188664]
Approved by marto
Front-paged by Athanasius
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (5)
As of 2024-04-23 20:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found