sharp icon indicating copy to clipboard operation
sharp copied to clipboard

Inconsistent white border in different image sizes

Open danielwerg opened this issue 1 year ago • 5 comments

Question about an existing feature

What are you trying to achieve?

Consistent output without white border.

When you searched for similar issues, what did you find that might be related?

Nothing, not sure what to search for.

Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this question

await sharp(svgPath).resize(1000).png().toFile(pngPath);
await sharp(svgPath).resize(1200).png().toFile(pngPath);
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
  <path fill="white" d="M32 32h300v300H32Z" />
  <path d="M32 32h300l-172 54L332 332H32Z" />
</svg>

Please provide sample image(s) that help explain this question

1000x (no white border)

1000

1200x (white border)

1200

danielwerg avatar Nov 21 '23 05:11 danielwerg

Both these images appear to be rendered as-expected, both have a transparent background.

I suspect your question relates to the semi-transparent pixels around some of the edges in the 1200px PNG example.

The logic to calculate the "natural size" of an SVG is not entirely straightforward - see https://github.com/libvips/libvips/blob/35053f55e372bd3e687e987c2d68ea5cf62f85cd/libvips/foreign/svgload.c#L402 - and may result in scaling via cairo, which can introduce anti-aliasing at edges for some dimensions.

Given the viewBox in this SVG is relatively simple (e.g. no offset), providing explicit width and height attributes will help everything involved in its rendering to determine the natural size.

- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
+ <svg xmlns="http://www.w3.org/2000/svg" width="500" height="500">

lovell avatar Nov 21 '23 10:11 lovell

Thank you for pointing me to the right direction. Unfortunately neither replacing viewBox with width and height nor simply adding it along viewBox did not change output for 1200x.

danielwerg avatar Nov 21 '23 17:11 danielwerg

You could also try using shape-rendering to reduce anti-aliasing.

- <path d="M32 32h300l-172 54L332 332H32Z" />
+ <path d="M32 32h300l-172 54L332 332H32Z" shape-rendering="crispEdges" />

lovell avatar Nov 26 '23 15:11 lovell

Doesn't really work in my case, it only made border slightly more obvious and made diagonal lines ugly (as expected).

1200x

1200x

danielwerg avatar Dec 03 '23 11:12 danielwerg

@danielwerg Were you able to make any progress with this?

lovell avatar May 16 '24 12:05 lovell

@lovell Nope, learned to accept it when I was still working on project that needed it.

danielwerg avatar May 18 '24 14:05 danielwerg

Thanks for the update, I'll close for now.

lovell avatar May 18 '24 15:05 lovell