Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gradient banding when rendering SVG to PNG #867

Closed
kimmobrunfeldt opened this issue Jul 6, 2017 · 6 comments
Closed

Gradient banding when rendering SVG to PNG #867

kimmobrunfeldt opened this issue Jul 6, 2017 · 6 comments

Comments

@kimmobrunfeldt
Copy link

Thanks for this amazing lib! It has helped me a ton.

I'm rendering an SVG which has a quite long linear gradient. I can see a bit weird gradient banding in the rendered PNG file. It looks different compared to rendering the same SVG with Illustrator or Sketch. My end goal is to print a poster out of an SVG, but the gradient in the print is distracting. Do you have an idea why sharp renders the PNG differently compared to e.g. Sketch? Is this because of bit depth? I didn't find a way to control the bit depth from sharp API.

I crafted a test repository which can be used to render the example: https://github.com/kimmobrunfeldt/sharp-svg-render-test. Please note that this is a specifically crafted example, and overly long gradient.

Below there are a few closeup screenshots of rendered gradients. These contain only part of the whole image, to not upload 4096px height images here.

Rendered with sharp library, using the example code linked above Filesize 35KB.
test-sharp
Original: https://s3-eu-west-1.amazonaws.com/alvarcarto/sharp-svg-render-test/test-sharp.png

Rendered with Sketch This is definitely the best one and something I'd want to strive for. Filesize 889KB.
test-sketch-from-svg
Original: https://s3-eu-west-1.amazonaws.com/alvarcarto/sharp-svg-render-test/test-sketch-from-svg.png

Illustrator export PNG-8, 256 colors, dither 100%. Filesize 11KB
test-illustrator-8
Original: https://s3-eu-west-1.amazonaws.com/alvarcarto/sharp-svg-render-test/test-illustrator-8.png

Illustrator export PNG-24. Filesize 19KB
test-illustrator-24
Original: https://s3-eu-west-1.amazonaws.com/alvarcarto/sharp-svg-render-test/test-illustrator-24.png

@kimmobrunfeldt
Copy link
Author

When looking into the exports even more closely. Sketch seems to add noise/grain/dither on top of the gradient which makes it smoother. Illustrator seems to export the most expected result, but sharp (or librsvg) renders a strange looking banding pattern. It doesn't seem to be evenly distributed.

@kimmobrunfeldt
Copy link
Author

kimmobrunfeldt commented Jul 6, 2017

If I got this right, this happens because:

The SVG has height of 4096px, has a 5px black border and a vertical linear gradient filling the whole are inside. The gradient has height of 4096px - 10px = 4086px and color changes from #232323 to #FFFFFF. In RGB colors, this means (32, 32, 32) -> (255, 255, 255). PNG32 gives us 8 bits per color channel, meaning 256 different steps per channel. Alpha channel doesn't help here since we can only have 256 different shades of gray.

So the gradient has 223 different shades available (from 32 to 255). If those are spread evenly to the whole height of the gradient, it means we'd have ~18px high stripe per shade of gray.

but, it still doesn't explain the different looking gradient pattern when rendering with sharp.

@lovell lovell added the triage label Jul 6, 2017
@lovell
Copy link
Owner

lovell commented Jul 13, 2017

@kimmobrunfeldt I've yet to make time to investigate this properly but will do so soon.

@lovell
Copy link
Owner

lovell commented Jul 14, 2017

I've been able to reproduce this locally with the pre-built libvips that ships with sharp v0.18.2.

It does however appear to work, without the banding, using the latest libvips master code and I believe https://github.com/jcupitt/libvips/issues/688 was the underlying problem.

This upstream fix will be picked up for the v0.19.x line of sharp. Thanks for reporting!

@kimmobrunfeldt
Copy link
Author

@lovell That's great news! Thanks for reporting. I'm eagerly waiting to test.

Meanwhile we fixed this by manually creating a dithered gradient and embedded it into the SVG.

@lovell
Copy link
Owner

lovell commented Jan 12, 2018

v0.19.0 now available.

@lovell lovell closed this as completed Jan 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants