RazrFalcon / resvg

An SVG rendering library.
Mozilla Public License 2.0
2.75k stars 221 forks source link

Control over image fetching #521

Open kornelski opened 2 years ago

kornelski commented 2 years ago

I'd like to have more control over fetching and decoding of images referenced in SVG files, in order to use existing decoders that I have, and to enforce size and memory usage constraints.

Would you be interested in a PR that makes image decoding "pluggable"? I image it could be something like an ImageDecoder trait and the library could allow user to configure their own implementation.

RazrFalcon commented 2 years ago

Sure, but can you clarify the use case? I mean, raster images are relatively rare in SVG. Therefore you're optimizing for an edge case.

Despite how it may look, I'm trying my best to simplify resvg. This is one of the reasons resvg is pure Rust. So I don't really see a benefit from using custom raster image decoders, since they will only increase the complexity even more. Especially if you account building resvg as a C library. Linking would become a nightmare.

But again, as long as you will be able to introduce this feature with minimal changes - it might be ok. I have to see the code first.

PS: just in case, "pluggable" rendering is out of scope. resvg already had 4 backends and it's just not worth it. Or even technically possible, to begin with. Luckily, one can easy write their own "renderer" on top of usvg, as many do.

yisibl commented 2 years ago

@RazrFalcon We have a very wide range of use cases. For example, we use SVG for our ad templates, which contain a large number of images of products that are bitmaps.

So, in resvg-js v2.1.0, we forked resvg and made some adjustments to image loading to load <image> that contain http URLs. It would be nice if resvg could support this natively.
@kornelski Are your needs and ideas similar to ours?

load image URL Demo

kornelski commented 2 years ago

Performance is not my primary concern. The changes I'd like to make are:

RazrFalcon commented 2 years ago

Ok, seems reasonable. Looking forward for a patch.

Some notes.

support for color profiles

This is a big one. CSS Color 4 technically requires color spaces, but since I'm against using system libraries (well, only macos has a good Color Management to begin with) one will have to write it in Rust. And hopefully it wouldn't be me. A decent port of littlecms/skcms would be a good start.

hardening against files that are too expensive to process

Well, you definitely have to disable filters first then. I thought about limiting RAM usage, but haven't had time to look into it.

support for remote URLs

This is technically supported already via ImageHrefResolver. Or you need something else?

code size reduction

Understandable, but png/jpeg/gif support is already just a fraction of resvg. Text is your main enemy.

Also note, that emojis support would require png decoding too. No idea when it would become available thought. Everything is interconnected in SVG.

TOGoS commented 9 months ago

Hey there. I, too, would like to use resvg to render SVGs that reference images by HTTP URL. e.g.

    <image x="0" y="0" width="32" height="32"
        style="image-rendering: optimizeSpeed"
        xlink:href="http://picture-files.nuke24.net/uri-res/raw/urn:bitprint:YA2TPCRUBEYF7NIXHXIBGF53O6J3JVRL.GDZQQXJDMHLFAG3CVREVYIE7KVJQBHWR6AZSFAY/TOGoS-Vital_2230-background-1.png"/>

Currently resvg reports that URL "is not a path to an image".

I wonder if it would make sense for this feature to be in resvg itself, maybe behind an option, or if anyone is maintaining something like a "resvg++" fork (I don't suppose yours is open-source, @kornelski?) with such a capability. In my case they are SVGs that I created myself, so I'm not too worried about any security issues.

RazrFalcon commented 9 months ago

This issue a bit outdated. You already can handle URLs. See crates/resvg/examples/custom_href_resolver.rs. You would have to download your image in the resolve_string closure.

If you're using resvg CLI, then no, it's not possible. And I'm not sure would ever be possible. I assume even the simplest file downloading crate would be quite a heavy dependency.