rsvg doesn't render linked images

后端 未结 4 680
野的像风
野的像风 2020-12-11 17:43

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:

相关标签:
4条回答
  • 2020-12-11 18:20

    The answer was to process the links to start with file:/// and be a full absolute path.

    0 讨论(0)
  • 2020-12-11 18:29

    There are many factors which must be satisfied for LibRsvg to allow an image resource to be loaded. As of v2.40 these include:

    • the image must have an xlink:href attribute
    • that attribute must contain a full, valid URI
    • the scheme can be data:// or file://
    • file:// paths must be absolute
    • file:// 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 all file:// images will be denied.

    rsvg-convert < input.svg > output.png  # images denied
    
    rsvg-convert -o output.png input.svg  # images allowed
    

    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

    #define G_ENABLE_DEBUG
    

    to config.h in the source and recompile.

    0 讨论(0)
  • 2020-12-11 18:37

    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.

    0 讨论(0)
  • 2020-12-11 18:45

    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:

    brew install --build-from-source librsvg
    

    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:

    wget https://download.gnome.org/sources/librsvg/2.40/librsvg-2.40.13.tar.xz
    tar jxvf librsvg-2.40.13.tar.xz
    cd librsvg-2.40.13
    

    I edited the _rsvg_handle_allow_load function in rsvg-base.c in this directory to bypass the path loading restrictions by adding this code around line 2275:

    2275
    2276     goto allow; // Just try and load it!
    2277     
    

    I also needed to edit the rsvg_cairo_surface_new_from_href function in rsvg-image.c and stop it loading using mime types - just replace the function like this:

    55     if (mime_type) {
    56         // loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, error);     // This doesn't work on my mac
    57         loader = gdk_pixbuf_loader_new (); // This works
    58     } else {
    59         loader = gdk_pixbuf_loader_new ();
    60     }
    

    I needed to use these slightly modified commands to compile and install the modified library:

    make clean
    make install gdk_pixbuf_binarydir=/usr/local/Cellar/librsvg/2.40.13/lib/gdk-pixbuf-2.0/2.10.0/loaders gdk_pixbuf_moduledir=/usr/local/Cellar/librsvg/2.40.13/lib/gdk-pixbuf-2.0/2.10.0/loaders
    

    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:

    rsvg-convert test.svg -o test.png
    

    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:

    convert test.svg test.png
    

    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.

    0 讨论(0)
提交回复
热议问题