linebender / resvg

An SVG rendering library.
Apache License 2.0
2.85k stars 228 forks source link

Alpha gradient colors have color banding #748

Closed jamesWalker55 closed 7 months ago

jamesWalker55 commented 7 months ago

I am trying to render the following SVG:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 39 1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
    <g id="tcp_custom_recinput_fade">
        <rect x="0" y="-0" width="39" height="1" style="fill:url(#_Linear1);"/>
    </g>
    <defs>
        <linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(39,0,0,1,0,0.5)">
            <stop offset="0" style="stop-color:#2d2d2d;stop-opacity:0"/>
            <stop offset="1" style="stop-color:#2d2d2d;stop-opacity:1"/>
        </linearGradient>
    </defs>
</svg>

image

When rendering this to a PNG at a resolution of 16x3, resvg produces the following output:

tcp_custom_recinput_fade

When put over a solid #2D2D2D background, it causes some slight color banding:

image

When I inspect the image, it seems the colors in the gradient differ significantly from #2D2D2D:

image

Comparing it to the output I get from Affinity Designer, there is no color banding in its output:

tcp_custom_recinput_fade

RazrFalcon commented 7 months ago

SVG doesn't require dither, therefore we do not apply it either.

jamesWalker55 commented 7 months ago

Sorry, I didn't mean dithering. The gradient is from #2d2d2d at 0 opacity to #2d2d2d at 1 opacity, so I'm not sure dithering is related

RazrFalcon commented 7 months ago

This is an expected behaviour: #677

You can try it yourself here: https://fiddle.skia.org/c/67cc2e6de7e644c8dd7402f86b1a1a68

jamesWalker55 commented 7 months ago

I've tried recreating my setup (gray gradient on a gray background) on that site as follows: https://fiddle.skia.org/c/dfac4678c2c74d0ba855b199005591b0

Then I downloaded the images to an image editor for inspecting:

image

With increased contrast:

image

Interestingly, only the CPU version has color bands, the GPU version has no banding at all.

Since resvg uses CPU for rendering, I guess this is expected behaviour? I still wonder if there's any way to get rid of that banding with resvg. Please feel free to close this issue if this is not planned.

RazrFalcon commented 7 months ago

If you will figure it out - feel free to send a patch. I have no idea how to solve it.