Log in

View Full Version : svg to png without banding?


smok3
7th August 2017, 00:59
I would like to convert svg image like this (https://paste.debian.net/plain/980178) (simple circular gradient) to some 8bpc png without banding, any tricks?

Tryed so far:
- exporting large resolution out of inkscape and downsizeing (fails)
- various imagemagick command lines: convert -density 600 -scale 1920x1200 in.svg out.png (fails)
- same as above command with various -depth switches, that should dither on resize (fails)

Phanton_13
7th August 2017, 03:27
The banding is a multifactor isue, for example that image in my computer:

minimun to no banding:
- Inkscape
- Gimp, svg or png export from Inkscape

clearly visible banding:
- built in windows viewer suing a png export from both Gimp and Inkscape

The reality is that the cause of the banding can be related to various reasons:

- bad image conversion
- color space management support in both app and/or in hardware
- display calibration
- display hardware
- color depth
- the image

In the case with the image that you uploaded the banding have 3 reasons one is "color space management" and the others are "the image" & "color depth" as it only uses 48 unique color in 8bpc, in that case the only solution is to use dithering to hide the banding.

This is somewhat related: https://askubuntu.com/questions/80695/how-do-i-convert-a-svg-to-a-png-using-dithering-for-gradients

PD. One posible solution is to render the svg in 16bpc and the convert it to 8bpc+dither, regrettably I don't know how to render the svg in 16bpc, but the color conversion with dither can be done in imagemagick.

smok3
7th August 2017, 07:18
What I haven't test is manually writen image/ gradient (will test), thanks for hints.
edit: It is interesting how poor rasterization tools are in general, just getting kicked by new and new blocks, for example right now I can't seem to figure out how to resize svg with different aspect and keep original stroke widths (fixed by setting vector-effect="non-scaling-stroke", photoshop cc has no clue about that thought).

LoRd_MuldeR
9th August 2017, 21:23
Try rendering the SVG with Chrome/Iron. Seems to give the "smoothest" result for me.

smok3
10th August 2017, 22:52
@LoRd_MuldeR; That is interesting, any tricks to save this rasterized (like png)?

LoRd_MuldeR
11th August 2017, 12:10
@LoRd_MuldeR; That is interesting, any tricks to save this rasterized (like png)?

Not that I'm aware. But, of course, you can always press "Print" and paste the result into your favorite image editor...

raffriff42
11th August 2017, 22:18
With such a shallow gradient, you are bound to get banding by the limitations of 8-bit images, unless the SVG is intelligently dithered somehow. I tried to do this in ImageMagick but was not successful.

It seems Illustrator has the option to save SVGs with rasterized, dithered gradients to avoid this problem; Adobe probably has a good reason for doing so, even through the result is not a true vector drawing any more (bloated file size, not resolution independent)

GiMP and Photoshop do nice dithering on gradients that they generate themselves; Photoshop's are a little nicer. This is because the program knows the correct color at every point to high precision. So, I suggest the following: in Inkscape, set the area where you want a gradient to a single color. Then in GiMP or Photoshop, select that color and add a gradient fill.

smok3
14th August 2017, 17:01
@raffriff42

this.svg
<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<svg width="1920" height="1080" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="Gradient1">
<stop class="stop1" offset="0%"/>
<stop class="stop3" offset="100%"/>
</linearGradient>

<style type="text/css"><![CDATA[
#rect1 { fill: url(#Gradient1); }
.stop1 { stop-color: #222222; }
.stop3 { stop-color: #555555; }
]]></style>
</defs>

<rect id="rect1" x="0" y="0" rx="0" ry="0" width="100%" height="100%"/>

</svg>
renders almost perfectly in chrome, silly in firefox and doesn't open correctly in inkscape (black rectangle). Well of corse one could do entire thing in bitmap world, but it's kinda silly if you compare 1MB png with <1kB svg.

patul
15th August 2017, 02:11
Have you try phantomjs (http://phantomjs.org)? It has svg rendering capability since it uses WebKit, however I don't know whether it's good enough for your requirement.

It's lightweight (17MB only), just download and extract it then find rasterize.js in example folder and issue following command.

phantomjs rasterize.js this.svg this.png

Edit:
Another way is to use IMG tag to render the svg in an HTML file, then open the html file using Chrome, you'll have access to "Copy Image" on the context menu (right click) to copy the rendered image to the clipboard, then you can paste the clipboard into your preferred image editor.

<img src="this.svg" style="height: 100%; width: 100%; margin-top: 0; margin-left: 0">

Ref:
here (https://superuser.com/questions/134679/command-line-application-for-converting-svg-to-png-on-mac-os-x/1036841#1036841)

poisondeathray
15th August 2017, 02:48
renders almost perfectly in chrome , silly in firefox

Looks the same in chrome (60.0.3112.101) and firefox (54.0.1) on Windows

raffriff42
15th August 2017, 04:09
Chrome looks pretty good because it does dithering -- only with hardware acceleration off (on my machine anyway)

smok3
15th August 2017, 17:18
Edit:
Another way is to use IMG tag to render the svg in an HTML file, then open the html file using Chrome, you'll have access to "Copy Image" on the context menu (right click) to copy the rendered image to the clipboard, then you can paste the clipboard into your preferred image editor.

<img src="this.svg" style="height: 100%; width: 100%; margin-top: 0; margin-left: 0">

Ref:
here (https://superuser.com/questions/134679/command-line-application-for-converting-svg-to-png-on-mac-os-x/1036841#1036841)

Nice one.