[python] Python에서 SVG를 PNG로 변환

파이썬에서 svg를 로 어떻게 변환 png합니까? svg의 인스턴스 에을 저장하고 StringIO있습니다. pyCairo 라이브러리를 사용해야합니까? 코드를 어떻게 작성합니까?



답변

대답은 ” pyrsvg “- 파이썬은 바인딩 librsvg .

그것을 제공 하는 Ubuntu python-rsvg 패키지가 있습니다. 소스 코드가 “gnome-python-desktop”Gnome 프로젝트 GIT 저장소에 포함 된 것처럼 보이기 때문에 Google에서 이름을 검색하는 것은 좋지 않습니다.

SVG를 cairo 표면에 렌더링하고 디스크에 쓰는 미니멀 한 “hello world”를 만들었습니다.

import cairo
import rsvg

img = cairo.ImageSurface(cairo.FORMAT_ARGB32, 640,480)

ctx = cairo.Context(img)

## handle = rsvg.Handle(<svg filename>)
# or, for in memory SVG data:
handle= rsvg.Handle(None, str(<svg data>))

handle.render_cairo(ctx)

img.write_to_png("svg.png")

업데이트 : 2014 년 현재 Fedora Linux 배포에 필요한 패키지는 gnome-python2-rsvg. 위의 스 니펫 목록은 그대로 작동합니다.


답변

다음은 cairosvg를 사용하여 수행 한 작업입니다 .

from cairosvg import svg2png

svg_code = """
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <circle cx="12" cy="12" r="10"/>
        <line x1="12" y1="8" x2="12" y2="12"/>
        <line x1="12" y1="16" x2="12" y2="16"/>
    </svg>
"""

svg2png(bytestring=svg_code,write_to='output.png')

그리고 그것은 매력처럼 작동합니다!

더보기 : cairosvg 문서


답변

Inkscape를 설치하고 명령 줄로 호출합니다.

${INKSCAPE_PATH} -z -f ${source_svg} -w ${width} -j -e ${dest_png}

매개 변수 만 사용하여 특정 직사각형 영역을 스냅 할 수도 있습니다 ( -j예 : 좌표 “0 : 125 : 451 : 217”).

${INKSCAPE_PATH} -z -f ${source_svg} -w ${width} -j -a ${coordinates} -e ${dest_png}

SVG 파일에서 하나의 개체 만 표시하려면 SVG -i에서 설정 한 개체 ID로 매개 변수 를 지정할 수 있습니다 . 다른 모든 것을 숨 깁니다.

${INKSCAPE_PATH} -z -f ${source_svg} -w ${width} -i ${object} -j -a ${coordinates} -e ${dest_png}


답변

저는 Wand-py (ImageMagick 주변의 Wand 래퍼 구현)를 사용하여 꽤 고급 SVG를 가져오고 지금까지 훌륭한 결과를 보았습니다! 이것이 필요한 모든 코드입니다.

    with wand.image.Image( blob=svg_file.read(), format="svg" ) as image:
        png_image = image.make_blob("png")

나는 오늘 이것을 방금 발견했으며 이러한 질문의 대부분이 답변 된 지 오래 되었기 때문에이 답변을 가로 지르는 다른 사람에게 공유 할 가치가 있다고 느꼈습니다.

참고 : 기술적으로 테스트에서 ImageMagick의 형식 매개 변수를 실제로 전달할 필요조차 없다는 사실을 알게되었으므로 with wand.image.Image( blob=svg_file.read() ) as image:실제로 필요한 모든 것이 었습니다.

편집 : qris가 시도한 편집에서 투명한 배경을 가진 SVG와 함께 ImageMagick을 사용할 수있는 몇 가지 유용한 코드가 있습니다.

from wand.api import library
import wand.color
import wand.image

with wand.image.Image() as image:
    with wand.color.Color('transparent') as background_color:
        library.MagickSetBackgroundColor(image.wand,
                                         background_color.resource)
    image.read(blob=svg_file.read(), format="svg")
    png_image = image.make_blob("png32")

with open(output_filename, "wb") as out:
    out.write(png_image)


답변

이것을 시도하십시오 : http://cairosvg.org/

사이트 내용 :

CairoSVG는 순수한 파이썬으로 작성되었으며 Pycairo에만 의존합니다. Python 2.6 및 2.7에서 작동하는 것으로 알려져 있습니다.

2016 년 11 월 25 일 업데이트 :

2.0.0은 새로운 주요 버전이며 변경 로그에는 다음이 포함됩니다.

  • Python 2 지원 중단

답변

방금 찾은 또 다른 솔루션 스케일링 된 SVG를 QImage로 렌더링하는 방법은 무엇입니까?

from PySide.QtSvg import *
from PySide.QtGui import *


def convertSvgToPng(svgFilepath,pngFilepath,width):
    r=QSvgRenderer(svgFilepath)
    height=r.defaultSize().height()*width/r.defaultSize().width()
    i=QImage(width,height,QImage.Format_ARGB32)
    p=QPainter(i)
    r.render(p)
    i.save(pngFilepath)
    p.end()

PySide는 Windows의 바이너리 패키지에서 쉽게 설치할 수 있습니다 (그리고 다른 용도로도 사용하므로 쉽게 사용할 수 있습니다).

그러나 Wikimedia에서 국가 국기를 변환 할 때 몇 가지 문제를 발견 했으므로 아마도 가장 강력한 svg 파서 / 렌더러가 아닐 것입니다.


답변

jsbueno의 답변에 대한 약간의 확장 :

#!/usr/bin/env python

import cairo
import rsvg
from xml.dom import minidom


def convert_svg_to_png(svg_file, output_file):
    # Get the svg files content
    with open(svg_file) as f:
        svg_data = f.read()

    # Get the width / height inside of the SVG
    doc = minidom.parse(svg_file)
    width = int([path.getAttribute('width') for path
                 in doc.getElementsByTagName('svg')][0])
    height = int([path.getAttribute('height') for path
                  in doc.getElementsByTagName('svg')][0])
    doc.unlink()

    # create the png
    img = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
    ctx = cairo.Context(img)
    handler = rsvg.Handle(None, str(svg_data))
    handler.render_cairo(ctx)
    img.write_to_png(output_file)

if __name__ == '__main__':
    from argparse import ArgumentParser

    parser = ArgumentParser()

    parser.add_argument("-f", "--file", dest="svg_file",
                        help="SVG input file", metavar="FILE")
    parser.add_argument("-o", "--output", dest="output", default="svg.png",
                        help="PNG output file", metavar="FILE")
    args = parser.parse_args()

    convert_svg_to_png(args.svg_file, args.output)