Конвертировать PDF в SVG
Я хочу конвертировать PDF в SVG, пожалуйста, предложите несколько библиотек / исполняемых файлов, которые смогут сделать это эффективно. Я написал свою собственную программу Java с использованием библиотек apache PDFBox и Batik -
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 в текстовом редакторе. он включает в себя каждый символ в исходном документе в своем собственном блоке, даже если свойства шрифта символов одинаковы. Например, слово "привет" будет отображаться в виде 6 различных текстовых блоков. Есть ли способ исправить вышеуказанный код? или, пожалуйста, предложите другое решение, которое будет работать более эффективно.
8 ответов
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() является синхронным и возвращается только после завершения процесса (хотя я не уверен в этом на 100%), так что после этого вы сможете просто прочитать "out.svg". В любом случае, поиск в Google "java system call" даст больше информации о том, как правильно выполнить эту часть.
Взгляните на 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/
pdftocairo
можно использовать для преобразования PDF в SVG. pdfcairo
является частью poppler-utils.
Например, чтобы преобразовать вторую страницу PDF-файла, можно запустить следующую команду.
pdftocairo -svg -f 1 -l 1 input.pdf
У меня возникли проблемы с предложенным
inkscape
,
pdf2svg
,
pdftocairo
, а также не предложенные
convert
а также
mutool
при попытке конвертировать большие и сложные PDF-файлы, такие как некоторые топографические карты из Геологической службы США. Иногда они давали сбой, иногда создавали сильно раздутые файлы. Единственным инструментом преобразования PDF в SVG, который смог правильно обработать их все для моего использования, был вариантаdvisvgm . Использовать его очень просто:
dvisvgm --pdf --output=file.svg file.pdf
Он имеет различные дополнительные параметры для обработки преобразования элементов, а также для оптимизации. Полученные файлы могут быть при необходимости сжаты с помощью svgcleaner без потери качества восприятия.
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
Inkscape не работает с-l
вариант больше нет. Он сказал: «Не удается открыть файл: /out.svg (не существует)». Полная форма этой опции находится на странице руководства как--export-plain-svg
и работает, но показывает предупреждение об устаревании. Мне удалось исправить и обновить команду с помощью-o
опция в Inkscape 1.1.2-3ubuntu4:
inkscape in.pdf -o out.svg
почему бы вам не попробовать использовать Spire.PDF для .NET? У него также есть бесплатная версия , и с помощью метода, который он предоставляет, любой может конвертировать PDF-файлы в изображения SVG, следуя приведенному ниже коду:
using Spire.Pdf;
namespace PDF_Page_to_SVG
{
class Program
{
static void Main(string[] args)
{
PdfDocument doc = new PdfDocument();
doc.LoadFromFile("Test.pdf");
doc.SaveToFile("Result.svg", 0, 0, FileFormat.SVG);
}
}
}
inkscape
( @jbeard4
) для меня создал svgs без текста вообще, но я смог заставить его работать, перейдя на postscript в качестве посредника с помощью ghostscript.
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 не поддерживает stdin / stdout, поэтому легко доступны
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).