linebender / resvg

An SVG rendering library.
Apache License 2.0
2.84k stars 229 forks source link

High memory usage when use image href data uri base64 #780

Closed ducan-ne closed 5 months ago

ducan-ne commented 5 months ago

As mentioned by title, my process memory usage come from 100mb to 450mb after rendering the svg. CleanShot 2024-06-16 at 05 27 46@2x

I'm not sure this issue is from the binding (wasm) site ore the resvg itself. But it is likely to from resvg because as I tried two js bindings (resvg-js + svg2png-wasm) have the same issue.

I couldn't myself verify if it running well in rust or not because I don't know any about Rust 🥲 My reproducible script if nodejs is fine to you: https://gist.github.com/ducan-ne/88c1f4ce047b6cf2883f3b7c0138818f

RazrFalcon commented 5 months ago

I can confirm that resvg allocates up to 268MB rendering this file. But your JPEG embedded into SVG is 7362x3679. That's a lot. Downscale it a bit an the problem will go away.

ducan-ne commented 5 months ago

@RazrFalcon I'm curious the resolution is the root cause here? The file is 7362x3679 but only 432kb. I also passed w/h to image tag like this <image x="0" y="0" width="1200" height="630", assuming it should behave like resizing the image. This is quite hard (to me) because the image comes from a editor and they resize them to fit the container (use a big image), currently it I don't figure out any way to validate this have to same size as the container.. and prevent weird behavior

Hmm but let me try to downscale the image to fit the container, at least it seems to be a solution.

RazrFalcon commented 5 months ago

The file is 7362x3679 but only 432kb.

Compressed is 432kb, but decompressed is 7362x3679x4 (RGBA8888), which is 100MB already. And we need two of them: one for raw JPEG data and one for tiny_skia::Pixmap. This is because JPEG is RGB888 and we need RGBA8888.

We could potentially try decoding an already downscaled JPEG image, but for now the only solution is to have a smaller image.

I also passed w/h to image tag, assuming it should behave like resizing the image.

Sure, but we still have to decode the original image.

ducan-ne commented 5 months ago

I see, thanks for clarifying that. I will try to solve from my side now. Since it now seems appropriate after your explanation. Should I close the issue?

RazrFalcon commented 5 months ago

I have added #782 to address this issue in the future.