2013-02-15 27 views
11

私はPythonを使用してSVG画像からPDF画像を生成しようとしています。私はCairoSVGsvglibの両方を試しました。問題は、どちらの場合でも、生成されたPDFに埋め込みCSSスタイルが適用されていないことです。埋め込みCSSを使用したSVGをPythonでPDFに変換

<?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の画像が黒い長方形としてレンダリングされます。

は、ここで黒の境界線と青い四角形を描画する必要があり、単純なSVGファイルです。 svglibを使用すると、矩形に適用されるストロークやスタイルがないので、表示されません。誰でも、CSSスタイルを持つSVG をPythonのPDF画像に変換する方法を知っていますか?

+1

私はこれまでのところ、私が思いついた最高のSVGをレンダリングするphantomjsを使用して、やや複雑なセットアップで、D3の視覚化のためのサムネイルを作成する必要があります。 phantomjsは実際のWebkitブラウザであるため、SVGはブラウザのバージョンとまったく同じようにレンダリングされます(phantompyモジュールがありますが、私の環境ではsegfaultingしており、理由を調べる時間がありません)。 –

+3

CairoSVGのドキュメントでは、CairoSVGはlxmlを使用してSVGファイルを解析し、tinycssとcssselectを使用してタグのstyle属性に含まれていないCSSを適用することができます。これらのパッケージが利用できない場合、CSSはスタイル属性でのみサポートされます。 tinycssパッケージとcssselectパッケージをインストールすると、問題が解決する可能性があります。こちらの依存関係のセクションを参照してください:http://cairosvg.org/user_documentation/ – MonkeyWrench

+0

@MonkeyWrench:それはあなたがそれを答えて賞金を集めることができるように気を付ければ、これまでのところ最高のヒントです。 –

答えて

8

documentationによると、

CairoSVGは、SVGファイルを解析するためにlxmlのを使用し、tinycssプラスcssselectすることができますタグのスタイル属性に含まれていないCSSを適用します。これらのパッケージが利用できない場合、CSSはスタイル属性でのみサポートされます。

を始めるために、私はその後、私は、次の内容でimage.svgを作成し

$ pip3 install cairosvg lxml tinycss cssselect 

、すべての依存関係をインストール:

<?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 image.svg -o image.pdf 
cairosvg

を実行

そして確かに、それは青い再ctangle。

blue

+1

例は、すべてのチェックをクレジットを与えました。いい仕事、あなたの恩恵を集める。 :-) –

+1

これはうまくいった。しばらく離れていた。将来的にはより良くなる。 – MonkeyWrench

+0

解決策をよりよく理解する - PhantomJSを使用するのに比べて、このアプローチの利点は何ですか? – pir

1

代わりにstyle属性を使用してみましたか?

<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の両方によって正しくレンダリングされます。しかし、私はWebページ上でレンダリングされたSVGイメージを変換しようとしています。個々の要素にスタイル属性を適用することは現実的ではありません。これは私の状況では機能しませんが、これは有用な情報です。ほんとありがと! – jrothenbuhler

1

PhantomJSを使用することをおすすめします。

基本的には、Javascriptで駆動されるヘッドレスWebKitです。

rasterize.jsスクリプトを参照してください。

座標を取得し、そのセクションを画像としてエクスポート(ラスタライズ)することができます。次に、画像を埋め込むことによって、基本的に任意のPDFジェネレータを使用することができます。また、別のスクリプトを使用してPhantomJSでPDFファイルを生成することもできます。 (@MonkeyWrenchからの助けを借りて、彼は答えを投稿していないからです。)

+0

'rasterize.js'はPDFを生成することができ、外部ジェネレータは不要です。 –

関連する問題