2013-02-15 27 views
11

我试图从使用Python的SVG图像生成PDF图像。我试过CairoSVGsvglib。问题是,在这两种情况下,生成的PDF都没有应用任何嵌入的CSS样式。将嵌入式CSS的SVG转换为Python中的PDF

这里是一个应该呈现蓝色的长方形黑色的边框一个简单的SVG文件:

<?xml version="1.0" standalone="no"?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg width="200" height="200" version="1.1" xmlns="http://www.w3.org/2000/svg"> 
    <defs> 
    <style type="text/css"><![CDATA[ 
     rect { 
     fill: #1f77b4; 
     stroke: black; 
     stroke-width: 1; 
     shape-rendering: crispEdges; 
     } 
    ]]></style> 
    </defs> 
    <rect x="50" y="50" width="100" height="100"></rect> 
</svg> 

渲染时使用CairoSVG这个SVG的PDF,PDF格式的图像呈现为黑色矩形。使用svglib,没有笔画或样式应用于矩形,因此不可见。有没有人知道一种方法将SVG 与CSS样式转换为Python中的PDF图像?

+1

我必须做出对D3可视化缩略图,到目前为止,我想出最好是使用phantomjs呈现SVG有点令人费解的设置。由于phantomjs是一个真正的webkit浏览器,所以SVG的渲染与浏览器版本完全相同(有一个幻影模块,但它在我的环境中存在缺陷,我没有时间调查原因)。 – 2013-07-22 15:37:32

+3

的CairoSVG文档中有这样一个字条:CairoSVG可以使用LXML解析SVG文件,tinycss加cssselect申请不包括在标签的样式属性CSS。如果这些软件包不可用,CSS将只在样式属性中受支持。如果你安装tinycss和cssselect软件包,它可能会解决你的问题。看到这里的依赖关系部分:http://cairosvg.org/user_documentation/ – MonkeyWrench 2013-07-26 19:16:26

+0

@MonkeyWrench:这是迄今为止最好的提示,如果你关心你可以做出答案并收集奖金。 – 2013-07-28 00:46:58

回答

8

(从@MonkeyWrench的帮助,因为他并没有张贴一个答案。)

按照documentation

CairoSVG可以使用LXML解析SVG文件,tinycss加cssselect应用未包含在标签样式属性中的CSS。如果这些软件包不可用,CSS将只在样式属性中受支持。

要开始,我安装了所有的依赖关系,

$ pip3 install cairosvg lxml tinycss cssselect 

然后创建image.svg具有以下内容:

<?xml version="1.0" standalone="no"?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg width="200" height="200" version="1.1" xmlns="http://www.w3.org/2000/svg"> 
    <defs> 
    <style type="text/css"><![CDATA[ 
     rect { 
     fill: #1f77b4; 
     stroke: black; 
     stroke-width: 1; 
     shape-rendering: crispEdges; 
     } 
    ]]></style> 
    </defs> 
    <rect x="50" y="50" width="100" height="100"></rect> 
</svg> 

最后,我执行cairosvg

$ cairosvg image.svg -o image.pdf 

果然,这是一个蓝色的ctangle。

blue

+1

有例子,给了功劳,一切都检查。干得不错,收集你的赏金。 :-) – 2013-07-29 00:42:12

+1

很高兴它解决了。已经离开了一段时间。更好地保持未来。 – MonkeyWrench 2013-09-05 23:08:29

+0

只是为了更好地理解解决方案 - 与使用PhantomJS相比,此方法的好处是什么? – pir 2015-03-21 19:52:27

1

您是否尝试过使用样式属性?

<svg xmlns="http://www.w3.org/2000/svg" version="1.1"> 
    <rect x="50" y="20" width="100" height="100" 
    style="fill:#1f77b4;stroke:black;stroke-width:1;shape-rendering: crispEdges;" 
    stroke-opacity:0.9"/> 
</svg> 

它最终和你已经是一样了,但也许CairoSVG跳过HTML中的样式元素。

+0

这个标记由CairoSVG和svglib正确显示。但是,我试图将SVG图像转换为在网页上呈现。将样式属性应用于每个单独的元素是不实际的。即使这不适合我的情况,这是有用的信息。那谢谢啦! – jrothenbuhler 2013-02-21 17:54:25

1

我建议使用PhantomJS

基本上它是一个无头WebKit,由Javascript驱动。

查看rasterize.js脚本。

您可以抓取坐标并将该部分导出(栅格化)为图像。然后,通过嵌入图像,您可以基本上使用任何PDF生成器。或者,您可以使用其他脚本来使用PhantomJS生成PDF文件。

+0

'rasterize.js'可以生成PDF,不需要外部生成器。 – 2013-07-24 04:47:43