将PDF转换为干净的SVG?

129

我正在尝试将PDF转换为SVG。然而,我目前使用的工具会针对每个文字片段中的每个字母创建一条路径,这意味着如果我更改源文件中的文本,则会出现丑陋的效果。

我想知道最干净的PDF到SVG转换器是什么,希望它不会为不需要路径的文本区域创建路径。我们知道,PDF和SVG非常相似,因此我认为有一些很好的转换器可用。


24
PDF和SVG在某种程度上相似,因为它们都是基于矢量的格式。但我认为这就是它们之间的比较结束的地方了。 - Frank Rem
1
我想它们都使用了很多文本的绝对定位。 - 700 Software
9个回答

101

你可以仅使用命令行而不打开GUI来使用Inkscape。试试这个:

inkscape \
  --without-gui \
  --file=input.pdf \
  --export-plain-svg=output.svg 

要获取所有命令行选项的完整列表,请运行inkscape --help


这个可以帮我去掉文本中的空格。 - MaxNoe
2
@MaxNoe:这很有可能——但是这是该特定PDF文件内部构造的“属性”。关于识别和提取PDF中的“文本”时可能遇到的一些困难的解释,请参见我在GitHub上手工编码的PDF文件(带嵌入式注释)。(在文本编辑器和PDF查看器中打开它们,并从文件中复制粘贴文本。) - Kurt Pfeifle
是的,我认为这与tex渲染空格的方式有关,就像是盒子一样。 - MaxNoe
6
在 Inkscape 1.0.1(或更高版本)中,命令应该是inkscape --export-type="svg" input.pdf - Mr.Epic Fail
1
然而,我发现pdf2svg(请参见pierre的答案)比inkscape产生更好的结果。 - Mr.Epic Fail
显示剩余2条评论

87

4
Inkscape表现不太好,因为它也会将文本转换为路径。我还发现它们经常会丢失字体数据,但似乎无法近似于良好安装的字体。如果SVG不能,那PDF是如何显示它的呢? - DanRedux
3
我想要这个的原因是因为我想使用PHP编辑文本。虽然我可以直接使用PDF进行编辑,但是PDF不容易嵌入HTML中,而SVG可以。也许我会坚持使用PDF,在编辑完值后将其转换为JPG。 - DanRedux
10
据我所知,在Inkscape中,你可以关闭“字体文本转路径”的转换。在Inkscape命令行中,你需要添加--export-text-to-path来启用此转换。请注意不改变原意,使翻译通俗易懂。 - Kurt Pfeifle
我的PDF文件中字体看起来很棒,但是当我导出为SVG格式时,它们看起来非常丑陋。有没有什么办法可以修复这个问题?我使用的命令是:inkscape -l out.svg in.pdf - remus
2
或许很明显,但Illustrator可以将PDF转换为SVG。我来这里下载了Inkscape,然后意识到我有Illustrator。http://en.wikipedia.org/wiki/Wikipedia:Graphics_Lab/Resources/PDF_conversion_to_SVG/Adobe_Illustrator - E. Sundin
显示剩余2条评论

25

我目前正在使用PDFBox,它对图形输出有很好的支持。它支持提取矢量笔画并管理字体。有一些很好的工具可以尝试它(例如,PDFReader将显示为Java Graphics2D)。

没有简单的方式可以将所有PDF转换为SVG - 它取决于用于创建PDF的策略和工具。一些文本被转换为矢量并且不能轻易地重建 - 您必须安装矢量字体并查找它们。

更新: 我现在已经将其开发成一个PDF2SVG包,不再使用Batik:

已经测试了多种PDF。它生成的SVG输出由以下内容组成:

  • 每个字符作为一个<svg:text>
  • 路径作为<svg:path>
  • 图像作为<svg:image>

以后的版本(希望如此)将把字符转换为运行文本,将路径转换为更高级别的图形对象

更新: 我们现在可以从SVG字符中重新创建运行文本。我们还将图表转换为特定领域的XML(例如化学光谱)。请参见https://bitbucket.org/petermr/svg2xml-dev。它仍处于Alpha测试阶段,但进展很快。任何人都可以加入其中!

更新。(@Tim Kelty)我们继续致力于PDF2SVG以及下游工具的开发,包括(有限的)Java OCR和高级图形原语(箭头、框等)的创建。请参考https://bitbucket.org/petermr/imageanalysishttps://bitbucket.org/petermr/diagramanalyzerhttps://bitbucket.org/petermr/normahttps://bitbucket.org/petermr/ami-core。这是一个资助项目,旨在从科学文献中获取一亿条事实(contentmine.org),其中大部分为PDF。


那段代码已经从Bitbucket移动到其他地方了吗? - Thomas W
1
它已经发生了很大的变化。请参见https://github.com/petermr/ami3 - peter.murray.rust

23

这个话题已经相当老了,但是我找到了一个方便解决问题的解决方案:

http://www.cityinthesky.co.uk/opensource/pdf2svg/

它提供了一个工具,pdf2png,一旦安装完成,在命令行中可以完美地完成工作。 我至今测试了无可挑剔的结果,包括位图。

修改:我的错误,这个工具也将字母转换为路径,因此它不能解决最初的问题。 但是它仍然做得很好,并且对于任何不打算修改svg文件中的代码的人都可能有用,所以我会保留这篇文章。


3
在Ubuntu上,您可以使用以下命令安装它:$ sudo apt-get install pdf2svg - tvw
2
虽然它将字母转换为路径,但结果非常好。为了进行一些修改,我过去通常直接使用编辑器直接编辑SVG文件。如果您使用inkscape打开并保存为inkscape SVG格式,则代码看起来更好,并且您可以获得对象ID,以便轻松查找要更改的实体。 - tvw
2
您可以使用brew install pdf2svg在Mac上安装它。 - Colas

10

以下是我最终使用的过程。我主要使用的工具是Inkscape,它可以良好地转换文本。

  • 使用带JavaScript的Adobe Acrobat Pro操作将PDF页面拆分成单独的文件
  • 使用Windows命令提示符运行Inkscape Portable 0.48.5进行转换为SVG
  • 通过使用Windows命令提示符和Windows PowerShell手动编辑特定的SVG XML属性,解决了我遇到的一些问题

拆分页面:Adobe Acrobat Pro with JavaScript

使用Adobe Acrobat Pro操作(以前称为批处理)创建自定义操作,将PDF页面拆分成单独的文件。或者您也可以使用GhostScript拆分PDF。

使用Acrobat JavaScript操作拆分页面

/* Extract Pages to Folder */

var re = /.*\/|\.pdf$/ig;
var filename = this.path.replace(re,"");

{
    for ( var i = 0;  i < this.numPages; i++ )
    this.extractPages
     ({
        nStart: i,
        nEnd: i,
        cPath : filename + "_s" + ("000000" + (i+1)).slice (-3) + ".pdf"
    });
};

PDF转SVG转换:使用Windows CMD批处理文件和Inkscape

使用Windows cmd创建批处理文件来循环遍历一个文件夹中的所有PDF文件,并将它们转换为SVG格式。

将PDF转换为SVG的批处理文件位于当前文件夹中

:: ===== SETUP =====
@echo off
CLS
echo Starting SVG conversion...
echo.

:: setup working directory (if different)
REM set "_work_dir=%~dp0"
set "_work_dir=%CD%"

:: setup counter
set "count=1"

:: setup file search and save string
set "_work_x1=pdf"
set "_work_x2=svg"
set "_work_file_str=*.%_work_x1%"

:: setup inkscape commands
set "_inkscape_path=D:\InkscapePortable\App\Inkscape\"
set "_inkscape_cmd=%_inkscape_path%inkscape.exe"

:: ===== FIND FILES IN WORKING DIRECTORY =====
:: Output from DIR last element is single  carriage return character. 
:: Carriage return characters are directly removed after percent expansion, 
:: but not with delayed expansion.

pushd "%_work_dir%"
FOR /f "tokens=*" %%A IN ('DIR /A:-D /O:N /B %_work_file_str%') DO (
    CALL :subroutine "%%A"
)
popd

:: ===== CONVERT PDF TO SVG WITH INKSCAPE =====

:subroutine
echo.
IF NOT [%1]==[] (

    echo %count%:%1
    set /A count+=1

    start "" /D "%_work_dir%" /W "%_inkscape_cmd%" --without-gui --file="%~n1.%_work_x1%" --export-dpi=300 --export-plain-svg="%~n1.%_work_x2%"

) ELSE (
    echo End of output
)
echo.

GOTO :eof

:: ===== INKSCAPE REFERENCE =====

:: print inkscape help
REM "%_inkscape_cmd%" --help > "%~dp0\inkscape_help.txt"
REM "%_inkscape_cmd%" --verb-list > "%~dp0\inkscape_verb_list.txt"

清理属性:Windows Cmd 和 PowerShell

我知道手动强制编辑SVG或XML标签或属性不是最佳实践,因为可能会有变化,应该使用XML解析器。 但是,我遇到了一个简单的问题,其中一个图形的描边宽度非常小,另一个图形的字体系列被错误识别,因此我基本上修改了以前的Windows Cmd批处理脚本,进行了简单的查找和替换。 唯一的更改是搜索字符串定义和更改调用PowerShell命令。 PowerShell命令将执行查找和替换,并将修改后的文件保存为添加后缀的文件。 如果需要执行其他一些次要的清理操作,则可以使用其他一些引用来解析或修改结果SVG文件。

手动查找和替换SVG XML数据的修改

:: setup file search and save string
set "_work_x1=svg"
set "_work_x2=svg"
set "_work_s2=_mod"
set "_work_file_str=*.%_work_x1%"

powershell -Command "(Get-Content '%~n1.%_work_x1%') | ForEach-Object {$_ -replace 'stroke-width:0.06', 'stroke-width:1'} | ForEach-Object {$_ -replace 'font-family:Times Roman','font-family:Times New Roman'} | Set-Content '%~n1%_work_s2%.%_work_x2%'"

希望这能对某些人有所帮助。

参考资料

Adobe Acrobat Pro动作和JavaScript分页参考

GhostScript分页参考

Inkscape命令行参考:PDF到SVG的转换

Windows Cmd批处理脚本参考

XML标记/属性替换研究


谢谢。我修改了你的命令行,使用 for /l %i in (1,1,58) Do @%inkscape% --pdf-page %i ... 将页面分离并直接将它们转换为 SVG。 - Mayra Delgado

9
如果DVI转SVG是一种选择,您还可以使用dvisvgm将DVI文件转换为SVG文件。这对于LaTeX公式非常有效(使用选项--no-fonts):
dvisvgm --no-fonts input.dvi -o output.svg

还有pdf2svg,它使用poppler和Cairo将pdf转换为SVG。当我尝试这个时,在inkscape中呈现的SVG非常完美。


1
我有一个PDF文件,其中包含一些来自skak包(象棋棋子)的LaTeX符号。这个特定的文件在Inkscape中处理得不好,因为符号变成了Arial字母... 我已经用pdf2svg得到了正确的结果。 - LRMAAX
对于Windows系统,这里有一组已编译的二进制工具:Poppler for Windows - Paolo Gibellini

7
将PDF的每一页转换为自己的SVG文件的Bash脚本。
#!/bin/bash
#
#  Make one PDF per page using PDF toolkit.
#  Convert this PDF to SVG using inkscape
#

inputPdf=$1

pageCnt=$(pdftk $inputPdf dump_data | grep NumberOfPages | cut -d " " -f 2)

for i in $(seq 1 $pageCnt); do
    echo "converting page $i..."
    pdftk ${inputPdf} cat $i output ${inputPdf%%.*}_${i}.pdf
    inkscape --without-gui "--file=${inputPdf%%.*}_${i}.pdf" "--export-plain-svg=${inputPdf%%.*}_${i}.svg"
done

要生成png文件,请使用--export-png等命令。

1

1

我发现 xfig 做得非常好:

pstoedit -f fig foo.pdf foo.fig
xfig foo.fig

export to svg

它的表现比inkscape好得多。实际上可能是pdtoedit做到了这一点。


链接:pstoedit xfig - arniebradfo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接