1

我在使用以下代码将一些 SVG 渲染为 PNG 数据时遇到了一些问题。使用 StringIO 编写器是因为图像最终旨在用作 HTTP 响应的主体。

结果是正确尺寸的 PNG,但它是完全透明的。

import rsvg
import cairo
import StringIO

def render_svg_to_png(svg_data):
    # Render
    svg = rsvg.Handle()
    svg.write(buffer=svg_data)

    img = cairo.ImageSurface(cairo.FORMAT_ARGB32,
                             svg.props.width,
                             svg.props.height)
    ctx = cairo.Context(img)
    svg.render_cairo(ctx)

    # Write to StringIO
    png_io = StringIO.StringIO()
    img.write_to_png(png_io)
    img.finish()

    return png_io.getvalue()

被渲染的 SVG 数据如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:cc="http://creativecommons.org/ns#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    version="1.1"
    width="40"
    height="40"
    id="svg2">
    <defs
        id="defs4">
        <linearGradient
        id="linearGradient3769">
        <stop
            id="stop3771"
            style="stop-color:#ffffff;stop-opacity:1"
            offset="0" />
        <stop
            id="stop3773"
            style="stop-color:#000000;stop-opacity:1"
            offset="1" />
        </linearGradient>
        <radialGradient
        cx="13.895907"
        cy="15.277355"
        r="19.6875"
        fx="13.895907"
        fy="15.277355"
        id="radialGradient3775"
        xlink:href="#linearGradient3769"
        gradientUnits="userSpaceOnUse"
        gradientTransform="matrix(0.96746783,-0.96746783,0.95701248,0.95701249,-12.884457,12.690532)" />
    </defs>
    <metadata
        id="metadata7">
        <rdf:RDF>
        <cc:Work
            rdf:about="">
            <dc:format>image/svg+xml</dc:format>
            <dc:type
            rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
            <dc:title></dc:title>
        </cc:Work>
        </rdf:RDF>
    </metadata>
    <g
        transform="translate(0,-1012.3622)"
        id="layer1">
        <path
            d="m 39.375,19.776785 a 19.6875,19.6875 0 1 1 -39.375,0 19.6875,19.6875 0 1 1 39.375,0 z"
            transform="matrix(1.015873,0,0,1.015873,0,1012.2715)"
            id="path2991"
            style="fill:url(#radialGradient3775);fill-opacity:1;fill-rule:nonzero;stroke:none" />
    </g>
</svg>
4

1 回答 1

1

在这里对我来说没问题:

import rsvg
import cairo
import StringIO

def render_svg_to_png(svg_data):
    # Render
    svg = rsvg.Handle(data=svg_data)
    img = cairo.ImageSurface(cairo.FORMAT_ARGB32, 
      svg.props.width, 
      svg.props.height)
    ctx = cairo.Context(img)
    svg.render_cairo(ctx)

    # Write to StringIO
    png_io = StringIO.StringIO()
    img.write_to_png(png_io)

    return png_io.getvalue()

svg_data = open('test.svg', 'r').read()
print render_svg_to_png(svg_data)

通过将输出重定向到.png文件来运行它,并确认它在图像查看程序中正常运行。

于 2013-03-10T02:35:05.610 回答