resvg icon indicating copy to clipboard operation
resvg copied to clipboard

Separate options for rendered SVG size and total image canvas size

Open ahmetsait opened this issue 1 year ago • 3 comments

Currently we are able to provide render size via --width and --height options but there is no way to produce a padded png from a non-padded svg. My use case revolves around generating a bunch of website favicons from an svg file. At first I tried to create another padded svg file which references the original file with <use xlink:href="favicon.svg#id" /> to avoid duplication but turns out external file references are not supported yet. Then I tried to see if it's possible to somehow specify render and final image sizes separately but looks like it's also not possible currently.

Feature Request Introduce --render-width and --render-height to specify what size the svg will be rendered. If the render size is smaller then image size, it is centered. If the render size is bigger, it is centered but also cropped.

We can think about introducing a --scale-mode=(scale,fill,stretch,none) option later on if necessary.

ahmetsait avatar Sep 27 '24 19:09 ahmetsait

The problem with this feature is that everyone want a slightly different behavior and it would be somewhat hard to handle all cases.

Will see.

RazrFalcon avatar Sep 28 '24 05:09 RazrFalcon

Thinking about this a bit more, I think the following CLI options would satisfy everyone's needs:

  • New options --canvas-width and --canvas-height: Determines output image canvas size. Falls back to the old aspect ratio preserving canvas size if not present.
  • New options -x & -y: Combined with the already existing --width and --height options, determines where in the image canvas the SVG contents will be placed - a.k.a. render area (conceptually similar to glViewport). -x and -y defaults to 0. If --width and --height options are not present they continue to be calculated from width, height and viewBox properties of <svg> just like before.
  • New option --scale-mode=<fit|fill|stretch|none>: Determines how will the SVG contents rendered inside render area.
    • fit: Fit inside render area preserving aspect ratio. This should be the default as it's how resvg currently behaves.
    • fill: Fill render area preserving aspect ratio. Works similar to desktop wallpaper "fill" setting.
    • stretch: Stretch to render area discarding aspect ratio. Works similar to desktop wallpaper "stretch" setting.
    • none: No scaling is done and SVG contents are centered inside render area.
  • New option: --clip[=x,y,w,h] makes anything outside of the given area visually clipped (conceptually similar to glScissor). No clipping takes place if this option is missing so parts that are outside the render area but inside image canvas will be visible. If --clip is used without x,y,w,h arguments then the clip area is assumed to be the same as render area.

What do you think? I don't know how hard it is to implement --scale-mode=stretch, I added it for the sake of completeness so feel free to ignore it.

Btw resvg is already pretty awesome as is so thanks for this great piece of software. I would love to help out with PRs but I'm no Rust programmer... yet.

ahmetsait avatar Oct 01 '24 17:10 ahmetsait

What do you think?

Hard to say without trying. Maybe someone would be interested in sending a PR.

RazrFalcon avatar Oct 01 '24 17:10 RazrFalcon