将pdf转换为svg

时间:2010-11-08 00:55:43

标签: pdf svg batik pdfbox

我想将PDF转换为SVG,请建议一些能够有效执行此操作的库/可执行文件。我使用apache PDFBox和Batik库编写了自己的java程序 -

PDDocument document = PDDocument.load( pdfFile );
DOMImplementation domImpl =
    GenericDOMImplementation.getDOMImplementation();

// Create an instance of org.w3c.dom.Document.
String svgNS = "http://www.w3.org/2000/svg";
Document svgDocument = domImpl.createDocument(svgNS, "svg", null);
SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(svgDocument);
ctx.setEmbeddedFontsOn(true);

// Ask the test to render into the SVG Graphics2D implementation.

    for(int i = 0 ; i < document.getNumberOfPages() ; i++){
        String svgFName = svgDir+"page"+i+".svg";
        (new File(svgFName)).createNewFile();
        // Create an instance of the SVG Generator.
        SVGGraphics2D svgGenerator = new SVGGraphics2D(ctx,false);
        Printable page  = document.getPrintable(i);
        page.print(svgGenerator, document.getPageFormat(i), i);
        svgGenerator.stream(svgFName);
    }

此解决方案效果很好,但生成的svg文件的大小很大。(比pdf大很多倍)。通过在文本编辑器中查看svg,我已经找到了问题所在。即使字符的字体属性相同,它也会将原始文档中的每个字符都包含在自己的块中。例如,单词hello将显示为6个不同的文本块。有没有办法修复上面的代码?或者请建议另一种可以更有效地工作的解决方案。

5 个答案:

答案 0 :(得分:55)

Inkscape也可用于将PDF转换为SVG。它实际上非常擅长这一点,虽然它生成的代码有点臃肿,但至少它似乎没有你在程序中遇到的特定问题。我认为将它直接集成到Java中是一项挑战,但是inkscape为这个功能提供了一个方便的命令行界面,因此访问它的最简单方法可能是通过系统调用。

要使用Inkscape的命令行界面将PDF转换为SVG,请使用:

inkscape -l out.svg in.pdf

然后您可以使用以下方式拨打电话:

Runtime.getRuntime().exec("inkscape -l out.svg in.pdf")

http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Runtime.html#exec%28java.lang.String%29

我认为exec()是同步的,只有在进程完成后才会返回(虽然我不是100%肯定),所以你应该在那之后只读“out.svg”。在任何情况下,谷歌搜索“java系统调用”将提供有关如何正确执行该部分的更多信息。

答案 1 :(得分:32)

看看pdf2svg

使用

pdf2svg <input.pdf> <output.svg> [<pdf page no. or "all" >]

使用all时,会在其中提供带%d的文件名(将被页码替换)。

pdf2svg input.pdf output_page%d.svg all

对于一些故障排除,请参阅: http://www.calcmaster.net/personal_projects/pdf2svg/

答案 2 :(得分:3)

public void saveToEs(NestedImages nestedImages) throws IOException { ObjectMapper Obj = new ObjectMapper(); final String images = Obj.writeValueAsString(nestedImages); final IndexRequest indexRequest = new IndexRequest("nestedimage") .source(images, XContentType.JSON); IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT); } 可用于将pdf转换为svg。 pdftocairo是poppler-utils的一部分。

例如,要转换pdf的第二页,可以运行以下命令。

pdfcairo

答案 3 :(得分:1)

pdftk 82page.pdf burst
sh to-svg.sh 

to-svg.sh

的内容
#!/bin/bash
FILES=burst/*
for f in $FILES
do
  inkscape -l "$f.svg" "$f"
done

答案 4 :(得分:0)

inkscape (@jbeard4) 为我制作了完全没有文字的 svg,但我能够通过使用 ghostscript 作为中介转至 postscript 使其工作。

for page in $(seq 1 `pdfinfo $1.pdf | awk '/^Pages:/ {print $2}'`)
do
    pdf2ps -dFirstPage=$page -dLastPage=$page -dNoOutputFonts $1.pdf $1_$page.ps
    inkscape -z -l $1_$page.svg $1_$page.ps
    rm $1_$page.ps
done

但是这有点麻烦,为了易于使用,必须使用 pdf2svg (@Koen.),因为它具有 all 标志,因此您不必'不需要循环。

但是pdf2svg 在 CentOS 8 上不可用,要安装它,您需要执行以下操作:

git clone https://github.com/dawbarton/pdf2svg.git && cd pdf2svg
#if you dont have development stuff specific to this project
sudo dnf config-manager --set-enabled powertools
sudo dnf install cairo-devel poppler-glib-devel
#git repo isn't quite ready to ./configure
touch README
autoreconf -f -i
./configure && make && sudo make install

它生成的 svgs 实际上看起来比上面的 ghostscript-inkscape 更好,字体看起来更好。

pdf2svg $1.pdf $1_%d.svg all

但是即使您没有sudo,该安装也有点太多了。最重要的是,pdf2svg 不支持标准输入/标准输出,因此现成的 pdftocairo (@SuperNova) 在这些方面发挥了作用,下面是“高级”使用的示例:

for page in $(seq 1 `pdfinfo $1.pdf | awk '/^Pages:/ {print $2}'`)
do
    cat $1.pdf | pdftocairo -svg -f $page -l $page - - | gzip -9 >$1_$page.svg.gz
done

产生与 pdf2svg 相同质量和大小(压缩前)的文件,虽然不是二进制相同的(甚至在视觉上,在两个输出之间跳跃一些字母的像素移位,但两者都不像inkscape那样看起来错误/糟糕) ).