PDF:将提取的图像切片/平铺

Jue*_*gen 2 pdf image ghostscript xpdf mupdf

到目前为止,使用pdfimagesmupdf/进行的图像提取mutool效果还不错。

用FreePDF生成的PDF中的图像始终被切片,因此一张图像会生成多个图像文件。

有避免这种情况的技巧吗?如何使用的结果pdfshow?将PDF转换为PNG或JPEG后,是否有坐标可知道要剪切/裁剪图像的位置,高度和宽度?

Kur*_*fle 5

提取图像后对其进行“切片”的最可能原因是:在提取图像之前就对其进行了“切片”,这是它们在PDF文件本身中的生存方式。

不要问我为什么有些PDF生成软件会这样做。

懂MS PowerPoint是臭名昭著的本-显示出一些梯度经常得到切片成数以万计的背景图片1x11x21x8像素,同样大小的微型图像的PDF中。


更新资料

1.确定问题的范围

可以使用以下pdfimages -list命令来识别样本PDF的图像片段(这需要pdfimages基于Poppler fork 的最新版本,而不是xpdf一个!):

pdfimages -list so-28023312-test1.pdf

page   num  type   width height color comp bpc  enc interp objectID x-ppi y-ppi size ratio
------------------------------------------------------------------------------------------
   1     0 image     271   271  rgb     3   8  jpeg   no       18 0   163   163 26.7K  12%
   1     1 image     271   271  rgb     3   8  jpeg   no       19 0   163   163 21.7K  10%
   1     2 image     271   271  rgb     3   8  jpeg   no       30 0   163   163 22.9K  11%
   1     3 image     271   271  rgb     3   8  jpeg   no       31 0   163   163 21.8K  10%
   1     4 image     132   271  rgb     3   8  jpeg   no       32 0   162   163 9895B 9.2%
   1     5 image     271   271  rgb     3   8  jpeg   no       33 0   163   163 22.5K  10%
   1     6 image     271   271  rgb     3   8  jpeg   no       34 0   163   163 16.5K 7.7%
   1     7 image     271   271  rgb     3   8  jpeg   no       35 0   163   163 16.9K 7.9%
   1     8 image     271   271  rgb     3   8  jpeg   no       36 0   163   163 20.3K 9.4%
   1     9 image     132   271  rgb     3   8  jpeg   no       37 0   162   163 14.5K  14%
   1    10 image     271   271  rgb     3   8  jpeg   no       20 0   163   163 17.1K 8.0%
   1    11 image     271   271  rgb     3   8  image  no       21 0   163   163  107K  50%
   1    12 image     271   271  rgb     3   8  image  no       22 0   163   163 96.7K  45%
   1    13 image     271   271  rgb     3   8  image  no       23 0   163   163  119K  56%
   1    14 image     132   271  rgb     3   8  jpeg   no       24 0   162   163 10.7K  10%
   1    15 image     271    99  rgb     3   8  jpeg   no       25 0   163   161 7789B 9.7%
   1    16 image     271    99  rgb     3   8  jpeg   no       26 0   163   161 6456B 8.0%
   1    17 image     271    99  rgb     3   8  jpeg   no       27 0   163   161 7202B 8.9%
   1    18 image     271    99  rgb     3   8  jpeg   no       28 0   163   161 8241B  10%
   1    19 image     132    99  rgb     3   8  jpeg   no       29 0   162   161 5905B  15%
Run Code Online (Sandbox Code Playgroud)

因为一页上只有20个不同的片段,所以很容易...

  1. ...首先将它们全部提取出来,然后将它们转换为JPEG,然后
  2. ...然后再将它们缝合在一起。

2.将片段提取为JPEG

以下命令将提取片段,并尝试将其另存为JPEG(-j28023312

pdfimages so-28023312-test1.pdf 28023312
Run Code Online (Sandbox Code Playgroud)

有3张图像以PPM的形式出现。使用ImageMagick's convert从其中制作JPEG(并非严格要求,但是可以简化“拼接”命令行:

for i in 11 12 13; do
  convert 28023312-0${i}.ppm 28023312-0${i}.jpg
done
Run Code Online (Sandbox Code Playgroud)

以下是前三个片段280233312-000.jpg,280233312-001.jpg和280233312-002.jpg:

  

3.再次将20个片段缝合在一起

ImageMagick可以再次将20张图像拼接在一起。在查看PDF页面以及20个JPEG时,很容易确定将它们放在一起的顺序:

convert                                         \
   \( 28023312-0{00,01,02,03,04}.jpg +append \) \
   \( 28023312-0{05,06,07,08,09}.jpg +append \) \
   \( 28023312-0{10,11,12,13,14}.jpg +append \) \
   \( 28023312-0{15,16,17,18,19}.jpg +append \) \
 -append                                        \
  complete.jpg
Run Code Online (Sandbox Code Playgroud)

剖析命令:

  1. +append 图像操作者附加所有在水平顺序列出的图像。

  2. 这些\( ... \)行表示图像堆栈的显示部分的“旁通处理(需要用转义的括号分隔)。然后,此水平附加操作的结果将替换当前图像堆栈内的各个片段。

  3. 最终-append 图像运算符垂直附加当前图像。

这是生成的JPEG,再次完全缝合在一起:

缝合在一起:最终图像

这可以自动化吗?

从理论上讲,我们可以使这一过程自动化。为此,我们必须分析PDF源代码。但是,这很困难,因为可以压缩内容流。

为了解压全部或大部分内容流,并获得PDF文件结构的一个更好的表现,我们可以使用mutool clean -dpodofouncompressqpdf --qdf

我更喜欢qpdf“结构化,内容保留的PDF文件转换器”。这是命令:

qpdf --qdf --object-streams=disable so-28023312-test1.pdf qdf.pdf
Run Code Online (Sandbox Code Playgroud)

生成的PDF文件qdf.pdf更易于分析,因为大多数(但不是全部)以前的二进制部分现在都使用ASCII。当您搜索Do此文件内部的内容时,您会看到插入图像的位置(但是,我无法在此处为您提供完整的PDF分析教程,对不起...)。

以下命令将打印所有Do出现的行,以及前一行(-B 1):

grep -a -B 1 " Do" qdf.pdf

1002 0 0 1002 236 5776.67 cm
/Im0 Do
--
1001 0 0 1002 1237 5776.67 cm
/Im1 Do
--
120.12 0 0 120.24 268.44 693.2004 cm
/Im2 Do
--
[...skipping 15 other output segments...]
--
1002 0 0 369 3237 3406.67 cm
/Im18 Do
--
490 0 0 369 4238 3406.67 cm
/Im19 Do
--
1 0 0 1 204.9037018 508.5130005 cm
/Fm0 Do
Run Code Online (Sandbox Code Playgroud)

所有/ImNN Do行都插入图像(该/Fm0 Do行引用的是表单对象,而不是图像)。

例如,前面的几行490 0 0 369 4238 3406.67 cm设置了当前的转换矩阵。仅仅从这一行,有时就可以得出图像的位置及其大小。对于此文件,这是不够的-需要更多前几行的内容才能确定当前的“绘图位置”。