如何以原始格式从PDF中提取图片

10
我正在使用命令“pdfimages -j bar.pdf /tmp/image”从PDF中提取图像。我的目标是以它们被添加时的原始状态获取它们。因此,如果它是 .tif 文件,则希望得到 .tif 文件;如果是 jpg 文件,则希望得到 .jpg 文件。但我提取出来的所有图像都是 .ppm 格式。
是否可能获得这些图像的原始格式,或者 .ppm 是我的唯一选择?
更新:我想要这样做的主要目的是检查文档中包含的所有图像的 DPI 或检查它们是否为矢量图形。
6个回答

10
首先,在 PDF 中被称为“图像”的东西,从定义上来说总是光栅图像。不存在所谓的“矢量图像”。即使原始文件包含矢量图形并转换为 PDF,转换程序也可以决定将其作为光栅图像包含在内。如果你提取它,你将得到的不是矢量图形,而是光栅图像。PDF 中保留的光栅图像不能通过pdfimages进行提取。
其次,你不需要使用 pdfimages 提取图像。只要您使用当前版本(v0.20.2 之后)的 Poppler fork 的 pdfimages,就可以使用 -list 参数获取特定范围 PDF 页面上所有图像的列表:
"pdfimages -list -f 7 -l 8 ct-magazin-14-2012.pdf
第7页 序号 类型 宽度 高度 颜色 压缩 每像素位数 编码方式 插值方式 对象ID -------------------------------------------------------- 0 图像 581 838 RGB 3 8 JPEG 否 39 0 1 图像 4 4 RGB 3 8 图像 否 40 0 2 图像 314 332 RGB 3 8 JPX 否 44 0 3 图像 358 430 RGB 3 8 JPX 否 45 0 4 图像 4 4 RGB 3 8 图像 否 46 0 5 图像 4 4 RGB 3 8 图像 否 47 0 6 图像 4 6 RGB 3 8 图像 否 48 0 7 图像 596 462 RGB 3 8 JPX 否 49 0 8 图像 4 6 RGB 3 8 图像 否 50 0 9 图像 4 4 RGB 3 8 图像 否 51 0 10 图像 8 10 RGB 3 8 图像 否 41 0 11 图像 6 6 RGB 3 8 图像 否 42 0 12 图像 113 27 RGB 3 8 JPX 否 43 0 13 图像 582 839 灰度 1 8 JPEG 否 2080 0 14 图像 344 364 灰度 1 8 JPX 否 2079 0" < p > 注意:这个版本的pdfimages是从Poppler中获取的(来自XPDF的版本尚未支持此新功能)。

正如您所看到的,这列出了图像的相应宽度和高度。然而,这还不能(现在)给你任何有关DPI的线索。如果将大型光栅图像挤压到PDF页面上的小空间中,则DPI值将非常高。(这也是plinth对自己答案的评论所强调的内容...)

为了计算DPI,您必须测量图像在页面上显示时的宽度/高度(您可以使用Acrobat / Reader中的工具之一来完成),然后使用上面输出的相应信息来计算DPI。


更新

pdfimages的最新版本现在在额外的列中直接显示了所包含图像的实际分辨率(DPI)。获得这些信息是问题的最初目标:

  pdfimages -list -f 6 -l 7 example.pdf
  page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
  --------------------------------------------------------------------------------------------
     6     0 图像    1901  1901  rgb     3   8  image  no       632  0  1818  1818  468K 4.4%
     6     1 图像    1901  1901  rgb     3   8  image  no       645  0  1818  1818  521K 4.9%

新的输出格式还显示了每个图像的相应水平和垂直分辨率('x-ppi''y-ppi')。它还给出了以存储空间为单位的图像实际大小('size')和它们的压缩比('ratio')。

感谢@Eric提供的更新提示,指出了pdfimages的这些新功能。


7
您无法通过查看PDF中的图像可靠地知道源图像文件格式。例如,TIFF图像可以使用(从我头顶上)无、RLE、CCITT(几种变体)、LZW、Flate、Jpeg进行压缩。如果PDF中的图像使用DCT(jpeg)进行压缩,您如何确定源是TIFF还是Jpeg?如果它使用Flate进行压缩,您如何区分TIFF和PNG?此外,生成PDF的软件决定了压缩方式,因此我可以将Flate压缩的TIFF图像转换为使用JPEG2000或CCITT压缩的图像,并将其压缩为jpeg图像,将其缩小为8位调色板图像并使用Flate进行压缩。

简而言之,您无法知道。


我获取原始文件的目的是为了能够检查上传的所有图像的DPI,以确保最低300 DPI。当我使用Imagick的identifyImage(http://php.net/manual/en/imagick.identifyimage.php)时,它不提供图像的分辨率,只提供宽度/高度。 - Ben
3
PDF图像本身并没有分辨率。 图像由具有宽度和高度的2D样本集定义。有效的分辨率取决于特定图像在任何给定页面上的放置方式以及该页面向用户呈现的方式。因此,我可以将一个96x96的图像放置在一个一英寸的正方形中,使其达到96 dpi,或者我可以把它放在一个2英寸的正方形中,这样它就是48 dpi。 - plinth
我正在尝试编程确定图像的分辨率是否足够高,以便准确打印。您是说如果不知道图像在文档中的布局,就无法做到这一点吗?也就是说,我不能仅检查图像本身。 - Ben
2
您可以获取图像的尺寸,并根据其预期打印大小进行猜测。 - plinth
确实,您无法知道在将图像插入PDF之前它的格式是什么,但是您可以检查PDF文件来了解用于存储文档内部图像的格式——这就是Kurt Pfeifle在他的答案中解释的内容,也可能是这个问题的关键。 - Diogo Kollross

2
我同意plinth的说法,你可能无法确定原始图像格式。但是ppm不是你唯一的输出选项。
Pdfimages会读取PDF文件,扫描一个或多个页面,并为每个图像写入一个PPM、PBM或JPEG文件,图像根号nnn.xxx,其中nnn是图像编号,xxx是图像类型(.ppm、.pbm、.jpg)。

http://linux.die.net/man/1/pdfimages

此外,您当然可以使用 ImageMagick的转换 来更改格式。

将 PPM 转换为 PNG 还是 JPEG? - Kiquenet

1
我正在添加另一个答案,涉及原问题的“更新”:“我的主要目标是检查文档中包含的所有图像的DPI,或者检查它们是否为矢量图形。” 您可以使用Ghostscript有选择地删除(或保留)每个页面上的文本、像素图像和矢量图形区域。关键是相应地应用新的CLI参数-dFILTERIMAGE、-dFILTERTEXT和/或-dFILTERVECTOR。该方法的详细信息在此处描述;答案包含可视化结果的屏幕截图:如何从PDF中删除所有图像?顶部行,从左至右:去除所有“文本”;去除所有“图片”;去除所有“矢量图”。底部行,从左至右:仅保留“文本”;仅保留“图片”;仅保留“矢量图”。
顶部行,从左至右:去除所有“文本”;去除所有“图片”;去除所有“矢量图”。底部行,从左至右:仅保留“文本”;仅保留“图片”;仅保留“矢量图。”

0
你需要获取图像XObject(其中包含原始图像的宽度和高度),然后获取实际显示的尺寸,然后就可以计算出来了。

0
对于那些仍然疑惑的人,pdfimages -all 是现代解决方案:

-all:以其本机格式编写 JPEG、JPEG2000、JBIG2 和 CCITT 图像。CMYK 文件将被编写为 TIFF 文件。所有其他图像将被编写为 PNG 文件。这相当于指定选项 -png -tiff -j -jp2 -jbig2 -ccitt。


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