在PDF中用光栅图像替换矢量图像

33

有没有一种简单(可脚本化)的方法将带有矢量图像的PDF转换为带有光栅图像的PDF?换句话说,我想生成一个PDF,其中包含完全相同(未光栅化)的文本,但每个矢量图像都被替换为光栅化版本。

我偶尔在我的Kindle上阅读技术文章的PDF,发现直接阅读PDF非常令人沮丧。幸运的是,亚马逊对PDF进行自动转换以适应Kindle格式的工作很好,大多数我尝试过的PDF的文本部分都可以重新排版。然而,虽然光栅图像似乎可以通过转换过程,但矢量图像却变得非常混乱。如果我能轻松地将PDF转换为所有矢量图像都被光栅化的PDF,那就太好了。

我对任何可能的解决方案都感兴趣,但最好是基于Linux或Windows的解决方案。


注意:这个问题最初是在 TeX 网站 上发布的,但那里的管理员建议我在这里提问。 - Michael Boyer
您可以将所有页面导出为图像,然后使用这些图像创建PDF。有许多应用程序可以实现此功能。我认为imagemagick和/或ghostscript的组合可以做到这一点。对于程序员,我已经撰写了一篇题为“<a href="http://www.gnostice.com/nl_article.asp?id=177&t=How_To_Rasterize_A_PDF_Document_In_NET">如何在.NET中栅格化PDF文档</a>”的文章,展示了如何使用我们的PDFOne .NET产品来完成此操作。 - BZ1
1
但我只想将 PDF 中的图像 / 图形转换为光栅图,而不是文本。 我没有看到使用 ImageMagick 完成这个任务的任何方法。 我会看一下 Ghostscript。 - Michael Boyer
1
@MichaelBoyer 除非你在寻求某个框架(例如.NET、JAVA、Windows、Linux)的解决方案,否则这个问题似乎更适合SuperUser网站而不是StackOverflow。 - Danny Varod
9个回答

19
我曾遇到类似的问题,使用 ImageMagick 的转换工具 (http://www.imagemagick.org/script/index.php) 解决了它。ImageMagick 工具在 Linux 上自带,并可在 Windows/Cygwin 或 OS X 上运行。

convert -density 300 largeVectorFileFromR.pdf out.pdf

-density 300 参数可控制分辨率(以 DPI 为单位)。

缺点:文本也会成为光栅图像,据我所知,Michael 不希望这样做。


4
用户遇到“未定义图像”的错误时,需要安装所需的Ghostscript依赖项“gs”。对于使用Homebrew的MacOS用户:brew install ghostscript - Mark Egge
这是适合我的解决方案。我还需要在Windows上安装Ghostscript。 - Mu-Tsun Tsai

13

在寻找一些解决方案的几天后,基于“从PDF文件中删除所有文本”和“如何将图片添加到现有的PDF文件中?”,我找到了一个(丑陋的)可编程解决方案:

gs -o /tmp/onlytxt.pdf -sDEVICE=pdfwrite -dFILTERVECTOR -dFILTERIMAGE $INPUT_FILE && \
gs -o /tmp/graphics.pdf -sDEVICE=pdfwrite -dFILTERTEXT $INPUT_FILE && \
convert -density $DPI -quality 100 /tmp/graphics.pdf /tmp/graphics.png && \
convert -density $DPI -quality 100 /tmp/graphics.png /tmp/graphics.pdf && \
pdftk /tmp/graphics.pdf stamp /tmp/onlytxt.pdf output $OUTPUT_FILE && \
rm /tmp/onlytxt.pdf /tmp/graphics.pdf /tmp/graphics.png

我们有三个变量:INPUT_FILE,OUTPUT_FILE和DPI。通过Ghostscript,我们将文本内容和图形内容分开,将图形图像转换为光栅图像(PNG),然后使用pdftk将两者合并。

我一直在成功地使用这种方法将巨大的矢量图像转换为科学论文中可用的格式。


对于较新版本的ImageMagick,默认情况下禁止对PDF执行此类操作,因此必须编辑“/etc/ImageMagick-7/policy.xml”(请参见此处)。 - Silmathoron
1
对于那些可能想要为多页PDF执行此操作的人,pdftk提供了一个等效的multistamp选项。 - Silmathoron

2
Enfocus的Pitstop Pro v2更新3可以做到这一点。它有一个名为“栅格化页面内容,保留文本”的操作,效果非常好。它是Adobe Acrobat的插件,因此需要一些额外的安装步骤,但也可作为服务器解决方案使用。

3
欢迎来到stackoverflow。上面的帖子可能已经回答了问题,但稍微解释一下可能有助于其他程序员理解它的工作原理。 - Nagama Inamdar

1
这有点复杂,但您要求任何可能的解决方案。此外,此解决方案无法自动化。
1)使用Inkscape打开具有矢量图像的pdf。然后使用选择工具(F1)选择整个图像。
2)如果矢量图像由多个svg图形组成,请按Ctrl + G(对象-->组)。
3)剪切分组的svg图像Ctrl + x。
4)打开一个新的InkScape窗口Ctrl + n并粘贴图像Ctrl + v。
5)选择文件-->导出位图(Shift + Ctrl + e),也许您想增加dpi。
6)返回第一个InkScape窗口,文件-->导入(Ctrl + i)并选择先前导出的位图。
7)将位图放置在svg图像所在的位置。
保存pdf文件,矢量图像将被位图图像替换。

1
非常复杂且工作量大。我正在寻找更自动化的版本,并认为这样的脚本应该存在于某个地方。 - data
是的,我明白你需要一种可编写脚本的方式。但是在11个月没有得到任何答案之后,我想至少分享一种可能的方法。 - Martin Grohmann
我明白 OP 想要自动化处理,但感谢您分享这个答案 - 我发现它对于只有一个问题图像的情况是一个有用的建议。 - Mike M

1

这里有一种解决问题的方法:

步骤1:使用在线PDF转HTML转换器,例如此处提供的转换器:

http://www.idrsolutions.com/online-pdf-to-html5-converter/

这个工具将PDF转换为一组图像和文本叠加层。向量图像应在此时转换为光栅图像。 第二步:将HTML+图像转换回PDF:

http://pdfcrowd.com/#convert_by_upload+with_options

生成的PDF将使所有矢量图像变成光栅化图像,而所有文本仍将保留为文本,因此您可以选择、复制等操作。

对我来说,问题在于对于许多PDF文件,pdf2html 无法正确解析PDF文件,因此效率低下。 - data
另一个问题是图中的文本应该与图的其余部分一起光栅化;例如,考虑图表轴上的标签。这个解决方案(pdf2html)将该文本保留为文本,因此生成的光栅化图形不完整。 - Michael Boyer
此外,不清楚如何处理包含多页的PDF文件。 - Michael Boyer
pdf2html基于xpdf,因此比一些更近期的PDF库功能较弱。我建议您下载(或尝试答案中链接的在线版本)JPedal PDF-to-HTML转换器。它允许为多个页面生成单个HTML文件。另外,您能否在问题中附上一个样本PDF?我经常使用PDF,可能能够提供一些帮助。(与上述网站无关联。) - Hari

1
使用https://jwilk.net/software/pdf2djvu转换器将pdf转换为djvu格式。取消勾选“抗锯齿字体、矢量图像等”,可以显著减小文件大小并提高文档加载速度。

0

Inkscape 是最好的解决方案,我快速制作了这个不太优化的批处理文件,可以完全实现这一点,并且您可以使用它并更改选项。ImageMagick 转换、gs 或 pdftoimages 不如 Inkscape 好用,它们要么不导出图层,要么导出但质量很差:

#!/bin/bash
#set -xev
ORIGINAL_FOLDER=`pwd` 
JPEGS=`mktemp -d`
unzip "$1" -d "$JPEGS"
cd "$JPEGS"
# expang the pdf in pdf pages
pdftk combined_to_do.pdf burst output pg_%04d.pdf
#1) print the pdf's to pngs as they are seen with alpha, layers, transparency etc, this cannot be done by ImageMacick convert or pdftoimages
ls ./pg*.pdf | xargs -L1 -I {}  inkscape {} -z --export-dpi=300 --export-area-drawing --export-png={}.png
#2) Second change to jpgs
rm *.pdf
ls ./p*.png | xargs -L1 -I {} convert {}  -quality 100 -density 300  {}.jpg
#3) This to make a pdf file out of every jpg image without loss of either resolution or quality:
ls -1 ./*jpg | xargs -L1 -I {} img2pdf {} -o {}.pdf
#4) This to concatenate the pdfpages into one:
pdftk *.jpg.pdf cat output combined.pdf
#5) And last I add an OCRed text layer that doesn't change the quality of the scan in the pdfs so they can be searchable:
pypdfocr combined.pdf
cp "$JPEGS/combined_ocr.pdf" "$ORIGINAL_FOLDER/$1_ocr.pdf"
cp "$JPEGS/combined.pdf" "$ORIGINAL_FOLDER/$1.pdf"

0

基于Civ Lins solution,我得出了这个:

#!/usr/bin/env sh
gs -o /tmp/onlytxt.pdf -sDEVICE=pdfwrite -dFILTERVECTOR -dFILTERIMAGE $1 && \
gs -o /tmp/graphics.pdf -sDEVICE=pdfimage24 -dFILTERTEXT -r600 -dDownScaleFactor=6 $1 && \
pdftk /tmp/graphics.pdf multistamp /tmp/onlytxt.pdf output $2 && \
rm /tmp/onlytxt.pdf /tmp/graphics.pdf

(与之前的解决方案相比,它处理多页PDF并使用gs直接呈现光栅化图像,而不需要通过convert进行绕路。)

0

我使用了以下内容:

gswin32c -o "%2" -dFirstPage=1 -dLastPage=1 -sDEVICE=pngalpha -r72x72 -dUseCropBox -dFitPage "%1" -dBATCH -dNOPAUSE

其中%1是输入文件,%2是输出。这可与LaTeX一起使用,生成的PNG具有与原始PDF相同的宽高比和页面大小,因此图像的相对位置不会改变。

请注意,在Linux中,您可能需要使用gs而不是gswin32c

您还可以设置页面范围,然后将页面打印回PDF。缺点是文本也被光栅化了。


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