如何确定嵌入在PDF文档中的图像分辨率(DPI)?

14

我有一个包含图片的PDF文档

现在我想知道这些图片的分辨率。

第一步应该是以某种方式将图片从PDF文档中取出。但是如何操作呢?

使用Cocoa提供的工具是否可以实现?


我不能保证,但我认为PDF可以包含具有不同分辨率的图像,因此“PDF文档的分辨率”并没有明确定义。 - JWWalker
哦,亲爱的。我希望你是错的。我会为此创建一个新问题。谢谢。 - Daniel
7个回答

16

针对你之前的问题,可以参考下面这个答案:

基本上,你现在可以使用Poppler的pdfimages命令行工具中的(新的)-list参数(但它不适用于XPDF的版本 pdfimages!)。

它会报告出现在特定页面上的每个图像的尺寸

(你也可以用它从PDF中提取图像:pdfimages -png -f 3 -l 5 some.pdf prefix---将从PDF文件中提取所有图像作为PNG,从第f一页3开始,到最后一页l5结束,使用每个图像的文件名前缀prefix---。但这个问题似乎不是你问题的主要关注点...)

示例:

pdfimages -list -f 1 -l 3 /Users/kurtpfeifle/Downloads/ct-magazin-14-2012.pdf
page num type width height color comp bpc enc interp object ID --------------------------------------------------------------------- 1 0 image 1247 1738 rgb 3 8 jpx no 3053 0 2 1 image 582 839 gray 1 8 jpeg no 2080 0 2 2 image 344 364 gray 1 8 jpx no 2079 0 3 3 image 581 838 rgb 3 8 jpeg no 7 0 3 4 image 1088 776 rgb 3 8 jpx no 8 0 3 5 image 6 6 rgb 3 8 image no 9 0 3 6 image 8 6 rgb 3 8 image no 10 0 3 7 image 4 6 rgb 3 8 image no 11 0 3 8 image 212 106 rgb 3 8 jpx no 12 0 3 9 image 150 68 rgb 3 8 jpx no 13 0 3 10 image 6 6 rgb 3 8 image no 14 0 3 11 image 4 4 rgb 3 8 image no 15 0

它并没有直接报告DPI分辨率——但是从“width”和“height”维度可以轻松计算出来:您用英寸尺在屏幕上测量图片的宽度,然后将“宽度像素”除以测量到的尺寸...

您会发现这很奇怪,因为结果取决于您当前的缩放级别?是的!

“分辨率”的概念始终取决于环境。所谓的“高分辨率”图片基本上总是有很多宽度和高度的像素。如果需要使用更高的缩放级别来显示或打印图片,则此方法可提供更好的质量(或“分辨率”)。


更新

与此同时,(Poppler的)pdfimages已经有了新版本:

$  pdfimages -version
  pdfimages version 0.33.0
  [....]

此报告还会显示嵌入图片的分辨率,以PPI(每英寸像素数)为单位,并在水平方向(x-ppi)和竖直方向(y-ppi)分别列出:

page num  type width height color comp bpc enc interp objectID x-ppi y-ppi size ratio
-------------------------------------------------------------------------------------
   1   0 image  1247  1738  rgb     3   8  jpx    no    3053 0   151   151  228K 3.6%
   2   1 image   582   839  gray    1   8  jpeg   no    2080 0    72    72  319B 0.1%
   2   2 image   344   364  gray    1   8  jpx    no    2079 0   150   150 4325B 3.5%
   3   3 image   581   838  rgb     3   8  jpeg   no       7 0    73    73 1980B 0.1%
   3   4 image  1088   776  rgb     3   8  jpx    no       8 0   150   151  106K 4.3%
   3   5 image     6     6  rgb     3   8  image  no       9 0   150   150  108B 100%
   3   6 image     8     6  rgb     3   8  image  no      10 0   150   150  158B 110%
   3   7 image     4     6  rgb     3   8  image  no      11 0   150   150   73B 101%
   3   8 image   212   106  rgb     3   8  jpx    no      12 0   150   150 2396B 3.6%
   3   9 image   150    68  rgb     3   8  jpx    no      13 0   150   150 1878B 6.1%
   3  10 image     6     6  rgb     3   8  image  no      14 0   150   150   81B  75%
   3  11 image     4     4  rgb     3   8  image  no      15 0   150   150   50B 104%

这个新特性首次出现在Poppler版本0.25(于2013年12月11日发布)。它还报告了嵌入图像的...

  • ...(文件)大小
  • ...(压缩)比率

...。

pdfimages -list的限制

也许我还应该让您意识到pdfimages实用程序的限制,并且举一个例子说明其输出报告并不完全正确。

一个例子是来自我的PDF 语法帮助初学者研究的 GitHub 存储库中的手工编码 PDF

我最初创建这个 PDF 是为了展示 Mozilla's PDF.js 渲染器的 Bug

下面是屏幕截图,左边是 PDF.js 中的显示,右边是由 Ghostscript 和 Adobe Reader 渲染时的正确效果:

 

(右键单击上面的每个图像。选择“在新选项卡中打开图像”以查看确切的差异...)


PDF 文件包含2x2像素的图像,仅嵌入一次(对象 ID 为 5 0),但是在页面上使用不同的设置多次显示该图像,每次都会放置图像...

  • ...在不同的位置,
  • ...以不同的比例缩放,
  • ...以不同的角度旋转,
  • ...甚至带有不同的倾斜

在这些极端情况下,pdfimages -list 在尝试确定此图像实例的某些分辨率时无法正常工作:

page num type width height color comp bpc enc interp objectID x-ppi y-ppi size ratio
------------------------------------------------------------------------------------
   1   0 image    2     2  rgb     3   8 image  no        5 0     4     4   13B 108%
   1   1 image    2     2  rgb     3   8 image  no        5 0     5     3   13B 108%
   1   2 image    2     2  rgb     3   8 image  no        5 0     3     5   13B 108%
   1   3 image    2     2  rgb     3   8 image  no        5 0     6     3   13B 108%
   1   4 image    2     2  rgb     3   8 image  no        5 0     3    10   13B 108%
   1   5 image    2     2  rgb     3   8 image  no        5 0     4 72000   13B 108%
   1   6 image    2     2  rgb     3   8 image  no        5 0     4     2   13B 108%
   1   7 image    2     2  rgb     3   8 image  no        5 0     2     4   13B 108%
   1   8 image    2     2  rgb     3   8 image  no        5 0 14401     1   13B 108%
   1   9 image    2     2  rgb     3   8 image  no        5 0     1     2   13B 108%
   1  10 image    2     2  rgb     3   8 image  no        5 0 0.950     4   13B 108%
   1  11 image    2     2  rgb     3   8 image  no        5 0     4 0.950   13B 108%
   1  12 image    2     2  rgb     3   8 image  no        5 0 0.950     4   13B 108%
   1  13 image    2     2  rgb     3   8 image  no        5 0     1     4   13B 108%
   1  14 image    2     2  rgb     3   8 image  no        5 0 0.950     4   13B 108%
   1  15 image    2     2  rgb     3   8 image  no        5 0 0.950     4   13B 108%
   1  16 image    2     2  rgb     3   8 image  no        5 0     4 0.950   13B 108%

pdfimages -list 命令在没有旋转和/或倾斜的情况下可以正确获取大多数值。如果图像被旋转或倾斜,那么不一致是很正常的:因为对于这种情况,您该如何可靠地定义 x-ppiy-ppi 值呢?这就解释了第5张图片完全错误的 72000 y-ppi 值和第8张图片错误的 14401 x-ppi 值。

正如您可以轻松看到的那样,pdfimages 对于确定其他图像属性相当聪明:

  1. 它正确地报告了所有显示的图像实例具有相同的对象 ID 5 0,表明该图像被嵌入一次,但在页面上显示多次。
  2. 它正确地报告了图像尺寸为 2x2 像素。

6
虽然使用 PDFDocument 是不可能的,但你可以使用 Quartz 中的 CGPDF* 工具。简单来说,你需要使用 CGPDFPageGetDictionary() 来获取图片所在页面的字典,然后从该字典中获取关于其 XObject 的信息(假设它没有被嵌入到流中)。即使这也不是很直接,你还需要查阅 PDF 标准以了解 XObject 可能的格式,并使用各种 CG* 程序来深入挖掘你需要的内容。
我应该补充说明一点,PDF 文档的默认 DPI(“用户单位”)为 72。此外,许多 PDF 中的图像是使用矢量图形创建的,因此它们实际上没有默认 DPI。

1
为将来记录,让我指出这个答案不完整且令人困惑。如果您想要了解所有内容,请阅读PDF规范,或者只需阅读Kurt Pfeifle的答案,以获取PDF文件中图像分辨率的方法(如果这确实是您想要的像素尺寸)。 - David van Driessche
@David_van_Driessche 最初的问题涉及到Cocoa --以及其中的API(2012年),而不是命令行实用程序。 此外,像素中的宽度和高度与分辨率不同。 pdfimages正在进行假设以获取ppi。(我认为它正如我所写,从XObject字典中提取信息。)我坚持认为上述内容(仍然)适用于Cocoa。 - Turix

2
答案绝对是否定的,因为PDF文档实际上没有固有分辨率。分辨率最终取决于处理文档及其元素的人员,并且甚至可以根据在Adobe Acrobat中使用的缩放量而变化。
例如,我创建了一个16x16像素尺寸的2D条形码,并将其缩放为一英寸宽和一英寸高,然后将其添加到文档中。在Adobe Acrobat阅读器中,它看起来非常清晰(即每个正方形元素有许多像素),但是当我将生成的PDF发送给传真服务时,它最终成为100x200分辨率(大约)。当我在acrobat reader中单击条形码图像并将其复制/粘贴到Gimp中时,它显示为一个小的16x16位图。

虽然PDF文档本身并没有固有的分辨率这一说法是正确的,但是OP在他的问题中澄清了他想要知道PDF文档中包含的图像的分辨率。 - mkl
我认为我的回答也涉及到了这一点。您可以确定图像的原始尺寸和显示尺寸,但dpi取决于呈现/打印文档的任何内容。如果我们知道OP的目的,那可能会有所帮助。我从识别传真条形码的角度来处理它,但他可能对搜索高分辨率摄影或其他内容的文档感兴趣。 - Jim W

0
每个图像在使用时的分辨率由cpdf -image-resolution <number>报告,其中number是所需的最低分辨率。因此,我们设置了非常高的分辨率,以便报告所有图像。在Kurt的示例PDF中:
cpdf -image-resolution 1000000 111_current-transformation-matrix-ctm.pdf 
1, /XOb1, 2, 2, 0.000694, 0.000694
1, /XOb1, 2, 2, 0.000926, 0.000556
1, /XOb1, 2, 2, 0.000545, 0.000958
1, /XOb1, 2, 2, 0.000694, 0.000694
1, /XOb1, 2, 2, 0.000694, 0.000694
1, /XOb1, 2, 2, 0.000491, 0.000694
1, /XOb1, 2, 2, 0.000491, 0.000694
1, /XOb1, 2, 2, 0.000694, 0.000491
1, /XOb1, 2, 2, 0.000139, 0.000098
1, /XOb1, 2, 2, 0.000139, 0.000120
1, /XOb1, 2, 2, 0.000087, 0.000694
1, /XOb1, 2, 2, 0.000694, 0.000087
1, /XOb1, 2, 2, 0.000087, 0.000694
1, /XOb1, 2, 2, 0.000116, 0.000694
1, /XOb1, 2, 2, 0.000087, 0.000694
1, /XOb1, 2, 2, 0.000087, 0.000694
1, /XOb1, 2, 2, 0.000694, 0.000087

这些列分别是页码、图片名称、像素宽度、像素高度、使用时的x分辨率和使用时的y分辨率。

0
您需要通过Do命令访问原始图像XObject的尺寸。

-2
你可以使用矢量图形编辑软件,比如Inkscape。导入PDF文档,测量图像的尺寸。然后靠近图片,以便能够看到像素。在任何像素上画一个正方形。通过建立比例,你可以计算图像的分辨率。

-2

这个答案是作为@Kurt Pfeifle答案的补充,适用于Objective C之外的情况。

或者:

如果您有Windows系统并且没有设置编译器,则以下是最简单的方法。下载Windows XPDF二进制文件;然后使用pdfimages提取图像,将它们转换为BMP格式,然后mspaint将告诉您分辨率。这种方法的优点是:

  • 您可以获得精确的分辨率,而无需通过测量图像大小来估计它;

  • 适用于XPDF版本的pdfimages

缺点是:

  • 需要更多的工作,包括将文件转换为您可以在不改变分辨率的情况下打开的格式;

  • 您必须针对每个文件单独执行此操作,而不是获取列表。

  • 它提供的是图像本身的分辨率,而不是它们在PDF文件中出现的分辨率。(感谢Kurt Pfeifle的评论)


2
抱歉,这个答案是完全错误的!一旦你提取了图像,你只能看到它们的绝对大小(宽度、高度)以像素为单位。当它们出现在PDF中时,它们的分辨率取决于它们在内容中被分配的大小。你可以在同一页上多次使用相同的图像,每次分配不同的分辨率。 - Kurt Pfeifle
1
敢不敢:从我的手工编码PDF文件的GitHub存储库下载此PDF。它只有30 KiB(大部分是注释)。它包含一个单独的2x2像素图像,在一页上多次使用并具有不同的分辨率。(这些极值将导致pdfimages报告错误的值...) - Kurt Pfeifle
@KurtPfeifle 你好, 感谢您的评论。我这样回答是因为既然OP问如何从文件中获取图像,我觉得他是在寻找原始图像的分辨率,而不是它们被包含在PDF文件中的分辨率:这也是我在发现这篇文章时所寻找的。您是正确的,这个过程并不能给出它们在PDF文件中显示的确切分辨率。 - Alex
1
一旦从PDF中提取出原始图像,就不存在所谓的“分辨率”。只有以像素数为单位测量的图像的宽度和高度。可能会有EXIF元数据信息,告诉一些“DPI”或“PPI”信息。但这只是一个注释。它是元数据,而不是图像数据!因此,它仅仅表示:“亲爱的渲染器或图像处理器:我希望以300 DPI的分辨率呈现,请问你能做到吗?”但并不能保证渲染器会遵守这个要求...(一旦图像嵌入在页面上或显示在屏幕上,DPI的概念就变得有效了...) - Kurt Pfeifle
我完全同意Kurt的观点,尽管我必须说这个答案和原问题一样令人困惑。图像的基本度量单位是像素;一个图像有宽度和高度。因此,谈论图像的DPI是不正确的。只有当该图像被放置在某种上下文中(比如在页面上)时,才能有意义地谈论DPI。 - David van Driessche
我实际上已经投票反对你的答案,因为我不喜欢你称这个为附录,并指出一种比Kurt的答案更加复杂且结果更差的方法(本来应该是这个问题的首选答案),而Kurt的答案应该是首选答案。 - David van Driessche

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