I use the python rsvg
bindings to render an svg image into cairo and save to file, which mostly works. But if the svg file contains a linked image, like so:
<image href="static/usrimgs/tmpDtIKpx.png" x="10" y="10" width="600px" height="400px"></image>
the image doesn't show up in the final file (the rest of the svg renders just fine). The relative path is correct based on where the script is running, but I'm guessing there's some problem with the fact that it would normally be a relative URL, not a relative filepath. How do I get around this?
The answer was to process the links to start with
file:///
and be a full absolute path.There are many factors which must be satisfied for LibRsvg to allow an image resource to be loaded. As of v2.40 these include:
xlink:href
attributedata://
orfile://
file://
paths must be absolutefile://
paths must be in or below the path of the SVG source file (after any symlinks have been dereferenced)Note that if input is passed to
rsvg-convert
via stdin, then no paths count as subdirectories of the input file and allfile://
images will be denied.The code governing image URL resolution can be found in the LibRsvg source in
rsvg-base.c
, function_rsvg_handle_allow_load
.To add a debugging notification to rsvg-convert when image loading fails, one can append
to
config.h
in the source and recompile.I wanted to get librsvg image rendering working on my Mac to speed up SVG rendering. Ian Mackinnon's great answer has all the ingredients but implementing a change to the library is tricky. These steps made librsvg correctly render linked images with relative paths. I hope this saves someone some time.
First, I installed librsvg using:
At the time of writing, this installs version 2.40.13 and the necessary libraries to build it. I then downloaded and extracted the source archive into my home directory:
I edited the
_rsvg_handle_allow_load
function inrsvg-base.c
in this directory to bypass the path loading restrictions by adding this code around line 2275:I also needed to edit the
rsvg_cairo_surface_new_from_href
function inrsvg-image.c
and stop it loading using mime types - just replace the function like this:I needed to use these slightly modified commands to compile and install the modified library:
Depending on your system, you might need to add sudo to the above commands.
Once this was done, I could render relative SVG links using the
rsvg-convert
command line tool that is installed with librsvg:I was also able to use ImageMagick to convert SVGs with relative image links to PNG files if I installed it after installing librsvg in this way:
This will let you test rsvg function and performance - I found it was 2-3x faster than Inkscape for my application. I recommend changing the code more intelligently if you use this in a production environment.
It seems that, if the file you are including is not on the same path or under the path of the SVG file you want to convert, it will not find it. I regard this as a bug.