2013-02-15 12 views
11

Python kullanarak bir SVG görüntüsünden PDF görüntüsü oluşturmaya çalışıyorum. Hem CairoSVG hem de svglib'u denedim. Sorun, her iki durumda da oluşturulan PDF'lerin uygulanan gömülü CSS stillerinden hiçbirine sahip olmamasıdır.Gömülü CSS ile SVG'yi Python'da PDF'ye dönüştürme

<?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 kullanarak bu SVG bir PDF oluşturma, PDF görüntü siyah bir dikdörtgen olarak oluşturulur:

İşte siyah kenarlı mavi dikdörtgen oluşturması gerektiğini basit bir SVG dosyasıdır. Svglib kullanarak, dikdörtgene uygulanacak vuruş veya stil yoktur, bu nedenle görünür değildir. Bir SVG 'u CSS stilleri ile Python'da bir PDF görüntüsüne dönüştürmenin bir yolu olduğunun farkında mısınız?

+1

Ben daha geldi iyi SVG oluşturabilmek için phantomjs kullanarak biraz dolambaçlı kurulumdur, D3 görsellikler için küçük resimler yapmak zorunda. Phantomjs gerçek bir webkit tarayıcısı olduğundan, SVG tam olarak tarayıcı sürümünde oluşturulmuştur (bir phantompy modülü var ama çevremde segfaultrasyon var ve nedenini araştırmak için zamanım yok). –

+3

CairoSVG belgelerine şu notu ekledi: CairoSVG, SVG dosyasını ayrıştırmak için lxml'yi ve etiketlerin stil özniteliğine dahil olmayan CSS'yi uygulamak içinse cssselect'i kullanabilir. Bu paketler mevcut değilse, CSS yalnızca stil özelliklerinde desteklenecektir. Tinycss ve cssselect paketlerini kurarsanız, probleminizi çözebilir. Bağımlılıklar bölümüne buradan ulaşabilirsiniz: http://cairosvg.org/user_documentation/ – MonkeyWrench

+0

@MonkeyWrench: Eğer şu ana kadarki en iyi ipucu, eğer bir cevap verebiliyorsanız ve ödül toplayabiliyorsanız. –

cevap

8

documentation göre,

CairoSVG SVG dosyasını ve tinycss artı cssselect ayrıştırmak için LXML kullanabilirsiniz

Etiketlerin stil özelliklerine dahil olmayan CSS'yi uygulamak. Bu paketler mevcut değilse, CSS yalnızca stil özelliklerinde desteklenecektir.

$ pip3 install cairosvg lxml tinycss cssselect 

Sonra aşağıdaki içeriği ile image.svg oluşturulan, bütün bağımlılıkları yüklü, Başlamak için: Nihayet

<?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> 

, ben cairosvg

$ cairosvg image.svg -o image.pdf 
infaz

Ve tabi ki, mavi bir re ctangle.

blue

+1

Örneğin, kredi verdi, her şey kontrol eder. İyi iş, ödülünü topla. :-) –

+1

Memnun kalmadı. Bir süredir uzaktayım. Gelecekte daha iyi kalsın. – MonkeyWrench

+0

Sadece çözümü daha iyi anlamak için - PhantomJS'yi kullanmaya kıyasla bu yaklaşımın yararı nedir? – pir

1

Bunun yerine stil özelliğini kullanmayı denediniz mi?

<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> 

Zaten sahip gibi sonuçta aynı, ama belki CairoSVG HTML'nize stil öğeleri atlıyor.

+0

Bu biçimlendirme, hem CairoSVG hem de svglib tarafından doğru şekilde oluşturuluyor. Ancak, bir web sayfasında SVG görüntüleri dönüştürmek çalışıyorum. Her bir öğeye stil özniteliklerini uygulamak pratik değildir. Bu durum benim durumum için işe yaramasa da, bu yararlı bir bilgidir. Yani teşekkürler! – jrothenbuhler

1

PhantomJS kullanmanızı öneririz.

Temel olarak, Javascript tarafından yönetilen başsız bir WebKittir.

rasterize.js kod dosyasına bakın.

Koordinatları alabilir ve bu bölümü görüntü olarak dışa aktarabilirsiniz (rasterleştirebilirsiniz). Daha sonra, görüntüyü yerleştirerek temel olarak herhangi bir PDF oluşturucuyu kullanabilirsiniz. Alternatif olarak, PhantomJS ile PDF dosyasını oluşturmak için başka bir komut dosyası kullanabilirsiniz. (O bir yanıt sonrası etmediği @MonkeyWrench yardımıyla,.)

+0

'rasterize.js', harici üreteçlere gerek kalmadan PDF'ler oluşturabilir. –