saveSvgAsPng icon indicating copy to clipboard operation
saveSvgAsPng copied to clipboard

SVG to PNG not render images in Safari browser

Open saulacher opened this issue 6 years ago • 6 comments

Hi, i have a problem with downloading svg as png in Safari. In Chrome works fine but in Safari sometimes (not every time) images in svg not rendering in final png.

https://jsfiddle.net/fvkjyLw4/

correct png (Chrome) image (2)

wrong png (Safari) image-2

saulacher avatar Jun 02 '19 18:06 saulacher

I am also able to reproduce this issue, both in my own codebase and the example from @saulacher above.

Safari: 12.1.1 (14607.2.6.1.1) macOS: 10.14.5 (18F132)

It almost always happens on the first download. Successive downloads often yield the full svg as expected, but not always.

ryanfitzer avatar Jul 08 '19 18:07 ryanfitzer

I experience the same problem but with tspan in text

BartvanS avatar Jul 23 '19 09:07 BartvanS

Looking into this more, I see that Safari makes a new request for all linked assets. Here's a screenshot of the example shared by @saulacher (with the downloaded result showing in the upper right corner).

Before clicking the "Save" button, I cleared all network requests from the log. As you can see, the 3 jpgs are requested again. My sense is that these resources are not yet downloaded when the png is created and therefore, do not show in the result.

Screenshot 2019-08-15 16 54 12

But when I click the "Save" button a second time, the 3 jpgs are not requested again and the png shows as expected.

This aligns with my own case. The parts that don't show initially are <text> elements that use webfonts. The webfonts are requested on the first click of "Save", but don't show. It takes another click to download the png in order to get the <text> elements to show in the png.

When I switch out the webfonts for a system font (Helvetica), the <text> elements show on the first png download.

Not yet sure what the solution is, but wanted to post my progress in the hopes it helps move this closer to a solution.

ryanfitzer avatar Aug 16 '19 00:08 ryanfitzer

Update: Looks like Chrome also makes requests, but some are pulled from cache. Still confused...

ryanfitzer avatar Aug 16 '19 00:08 ryanfitzer

I've narrowed it down to this line. From what I can find elsewhere, Safari has issues rendering linked assets when the canvas element is first drawn.

In the source, just after the line I linked to, if you run document.body.appendChild() on both canvas and src (which is an image with the svg dataURI as its src), you'll find that in Safari 12, the src image renders the fonts, but the canvas doesn't. Running saveSvgAsPng a second time shows the fonts/images rending correctly.

While it's not ideal, I've found a workaround. To force the PNG to be generated twice, but dowloaded only once, I first running svgAsPngUri and saveSvgAsPng in the returned promise's .then(). I've forked the example @saulacher posted as an example: https://jsfiddle.net/2hpok9uj/. This works in Safari. But as I said, it's not ideal.

ryanfitzer avatar Aug 19 '19 21:08 ryanfitzer

It looks like it might be a bug in WebKit. You can file an issue here.

ligaz avatar Aug 20 '19 05:08 ligaz