How to convert a SVG to a PNG with ImageMagick?

前端 未结 18 1824
一个人的身影
一个人的身影 2020-11-28 17:04

I have a SVG file that has a defined size of 16x16. When I use ImageMagick\'s convert program to convert it into a PNG, then I get a 16x16 pixel PNG which is way too small:<

相关标签:
18条回答
  • 2020-11-28 17:44

    If you are on MacOS X and having problems with Imagemagick's convert, you might try reinstalling it with RSVG lib. Using HomeBrew:

    brew remove imagemagick
    brew install imagemagick --with-librsvg
    

    Verify that it's delegating correctly:

    $ convert -version
    Version: ImageMagick 6.8.9-8 Q16 x86_64 2014-12-17 http://www.imagemagick.org
    Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
    Features: DPC Modules
    Delegates: bzlib cairo fontconfig freetype jng jpeg lcms ltdl lzma png rsvg tiff xml zlib
    

    It should display rsvg.

    0 讨论(0)
  • 2020-11-28 17:45

    I haven't been able to get good results from ImageMagick in this instance, but Inkscape does a nice job of it on Linux and Windows:

    inkscape -z -w 1024 -h 1024 input.svg -e output.png
    

    Edit (May 2020): Inkscape 1.0 users, please note that the command line arguments have changed:

    inkscape -w 1024 -h 1024 input.svg --export-filename output.png
    

    (on macOS, you may need to use --export-file instead of --export-filename).

    Here's the result of scaling a 16x16 SVG to a 200x200 PNG using this command:

    enter image description here

    enter image description here

    Just for reference, my Inkscape version (on Ubuntu 12.04) is:

    Inkscape 0.48.3.1 r9886 (Mar 29 2012)
    

    and on Windows 7, it is:

    Inkscape 0.48.4 r9939 (Dec 17 2012)
    
    0 讨论(0)
  • 2020-11-28 17:46

    Inkscape doesn't seem to work when svg units are not px (e.g. cm). I got a blank image. Maybe, it could be fixed by twiddling the dpi, but it was too troublesome.

    Svgexport is a node.js program and so not generally useful.

    Imagemagick's convert works ok with:

     ~$ convert -background none -size 1024x1024 infile.svg outfile.png
    

    If you use -resize, the image is fuzzy and the file is much larger.

    BEST

    ~$ rsvg  -w 1024 -h 1024 infile.svg  outfile.png
    

    It is fastest, has the fewest dependencies, and the output is about 30% smaller than convert. Install librsvg2-bin to get it. There does not appear to be a man page but you can type:

    ~$ rsvg --help
    

    to get some assistance. Simple is good.

    0 讨论(0)
  • 2020-11-28 17:46

    In ImageMagick, one gets a better SVG rendering if one uses Inkscape or RSVG with ImageMagick than its own internal MSVG/XML rendered. RSVG is a delegate that needs to be installed with ImageMagick. If Inkscape is installed on the system, ImageMagick will use it automatically. I use Inkscape in ImageMagick below.

    There is no "magic" parameter that will do what you want.

    But, one can compute very simply the exact density needed to render the output.

    Here is a small 50x50 button when rendered at the default density of 96:

    convert button.svg button1.png
    


    Suppose we want the output to be 500. The input is 50 at default density of 96 (older versions of Inkscape may be using 92). So you can compute the needed density in proportion to the ratios of the dimensions and the densities.

    512/50 = X/96
    X = 96*512/50 = 983
    


    convert -density 983 button.svg button2.png
    


    In ImageMagick 7, you can do the computation in-line as follows:

    magick -density "%[fx:96*512/50]" button.svg button3.png
    
    or
    
    in_size=50
    in_density=96
    out_size=512
    
    magick -density "%[fx:$in_density*$out_size/$in_size]" button.svg button3.png
    
    0 讨论(0)
  • 2020-11-28 17:47

    This is what worked for me

    find . -type f -name "*.svg" -exec bash -c 'rsvg-convert -h 1000  $0 > $0.png' {} \;
    rename 's/svg\.png/png/' *
    

    This will loop all the files in your current folder and sub folder and look for .svg files and will convert it to png with transparent background.

    Make sure you have installed the librsvg and rename util

    brew install librsvg
    brew install rename
    
    0 讨论(0)
  • 2020-11-28 17:48

    I've solved this issue through changing the width and height attributes of the <svg> tag to match my intended output size and then converting it using ImageMagick. Works like a charm.

    Here's my Python code, a function that will return the JPG file's content:

    import gzip, re, os
    from ynlib.files import ReadFromFile, WriteToFile
    from ynlib.system import Execute
    from xml.dom.minidom import parse, parseString
    
    
    def SVGToJPGInMemory(svgPath, newWidth, backgroundColor):
    
        tempPath = os.path.join(self.rootFolder, 'data')
        fileNameRoot = 'temp_' + str(image.getID())
    
        if svgPath.lower().endswith('svgz'):
            svg = gzip.open(svgPath, 'rb').read()
        else:
            svg = ReadFromFile(svgPath)
    
        xmldoc = parseString(svg)
    
        width = float(xmldoc.getElementsByTagName("svg")[0].attributes['width'].value.split('px')[0])
        height = float(xmldoc.getElementsByTagName("svg")[0].attributes['height'].value.split('px')[0])
    
        newHeight = int(newWidth / width * height) 
    
        xmldoc.getElementsByTagName("svg")[0].attributes['width'].value = '%spx' % newWidth
        xmldoc.getElementsByTagName("svg")[0].attributes['height'].value = '%spx' % newHeight
    
        WriteToFile(os.path.join(tempPath, fileNameRoot + '.svg'), xmldoc.toxml())
        Execute('convert -background "%s" %s %s' % (backgroundColor, os.path.join(tempPath, fileNameRoot + '.svg'), os.path.join(tempPath, fileNameRoot + '.jpg')))
    
        jpg = open(os.path.join(tempPath, fileNameRoot + '.jpg'), 'rb').read()
    
        os.remove(os.path.join(tempPath, fileNameRoot + '.jpg'))
        os.remove(os.path.join(tempPath, fileNameRoot + '.svg'))
    
        return jpg
    
    0 讨论(0)
提交回复
热议问题