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

时间:2015-01-19 11:13:19

标签: image pdf ghostscript mupdf xpdf

目前,使用pdfimagesmupdf / mutool的图片提取工作正常。

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

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

2 个答案:

答案 0 :(得分:5)

在提取图像后,图像被“切片”的最可能原因是: 它们在提取之前已经“切片” - 作为它们在PDF文件本身中的生存方式。

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

MS Powerpoint对此很有说服力 - 显示一些渐变的背景图像经常被切成数万1x11x21x8像素以及类似大小的迷你图像PDF。


更新

1。确定问题的范围

可以使用pdfimages -list命令识别样本PDF的图像片段(这需要基于Poppler分支的最新版pdfimages,而不是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%

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

  1. ...首先将它们全部提取出来并将它们转换为JPEG格式,然后
  2. ......然后再将它们拼接在一起。
  3. 2。将片段解压缩为JPEG

    以下命令将提取片段并尝试将其保存为JPEG(-j 28023312

    pdfimages so-28023312-test1.pdf 28023312
    

    有3张图片以PPM形式出现。使用ImageMagick的convert从中制作JPEG(不是严格要求,但它简化了'拼接'命令行:

    for i in 11 12 13; do
      convert 28023312-0${i}.ppm 28023312-0${i}.jpg
    done
    

    以下是前三个片段,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
    

    解析命令:

    1. +append 图片运算符以水平顺序附加所有列出的图片。

    2. \( ... \)行表示图像堆栈的resprective部分的'旁边'处理(需要通过转义括号分隔)。然后,此水平追加操作的结果将替换当前图像堆栈中的各个片段。

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

    4. 这是生成的JPEG,再次完全拼接在一起:

      Stitched together: final image

      这可以自动化吗?

      理论上我们可以自动完成这个过程。为此,我们必须分析PDF源代码。但是,这很难,因为内容流可能会被压缩。

      为了解压缩所有或大部分内容流并更好地表示PDF文件结构,我们可以使用mutool clean -dpodofouncompressqpdf --qdf

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

      qpdf --qdf --object-streams=disable so-28023312-test1.pdf qdf.pdf
      

      生成的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
      

      所有/ImNN Do行插入图片(/Fm0 Do行指的是表单对象而不是图片)。

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

答案 1 :(得分:2)

FreePDF使用Ghostscript并创建一个虚拟打印机'。当您打印到PDF'实际发生的是您的应用程序打印到Windows打印管道,该管道将图形基元发送到Windows PostScript打印机驱动程序,后者将PostScript发送到端口监视器。 FreePDF端口监视器将此PostScript程序存储在磁盘上。输出完成后,它会启动Ghostscript,它解释PostScript并生成PDF文件。

现在,除非你使用一个非常古老的Ghostscript版本( 可能,你应该检查!)这将取输入中的任何内容并将其放入输出中。它不会切割图像。

这意味着,就像Kurt和David上面所说的那样,问题的真正原因是PostScript程序在Ghostscript看到它之前已经将图像切成了碎片。

现在我知道通常这种情况,但它在很大程度上取决于您安装的PostScript打印机驱动程序,配置方式,使用的Windows版本以及驱动打印机的应用程序是。

正如大卫正确地说的那样,Microsoft Office应用程序习惯于以这种方式绘制某些类型的模式(以获得半透明效果'他们使用的模式是单元格是图像掩码,&# 39;白色'像素是透明的)。

此外,如果你有大照片(例如)并且PostScript打印机配置的内存最少,驱动程序可能会分割图像以免耗尽打印机的内存。显然这是一个配置问题,因为在桌面PC上你必须使用怪物图像来压倒Ghostscript。

基本上,在我们完全回答这个问题之前,我们需要你提供更多信息,但原则是损坏是在它到达FreePDF之前完成的。用于创建PDF文件的Ghostscript版本将在PDF文件元数据中,除非FreePDF选择擦除/覆盖它。

最后,正如Kurt指出的那样,您应该发布PDF文件的链接,理想情况下是用于生成PDF的应用程序文件和中间PostScript文件。