php 如何检测PDF是文本还是图像

bgtovc5b  于 2023-06-28  发布在  PHP
关注(0)|答案(2)|浏览(189)

我有一个应用程序,用户可以上传pdf,转换为text进行进一步处理。事情是,一些上传的文件是图像PDF,所以转换它不起作用。而不是发送所有的PDF被分割成图像,然后OCR他们,我宁愿只发送那些被证明或检测到的图像,有没有办法做到这一点,我在linux (debian)环境与php工作

更新

在寻找最终解决方案时,我遵循了@Andrew的建议,计算生成的txt文件的字数,如果少于10个单词,则进行下一步:PDF转换成图像,以便以后进行OCR识别,这就是我现在正在做的……

// convert any file with pdf extension to text
$cmd = "pdftotext -eol unix '$uploadedfile'";
shell_exec($cmd);
// save original file at the orig directory
rename("$uploadedfile", "orig/$uploadedfile");
// pdftotext renames files to txt so I need the file name with txt extension
$textfile = preg_replace('"\.(pdf|PDF)$"', '.txt', $uploadedfile);
// count words on the generated txt file
$cmd = "wc -w '$textfile' | cut -f1 -d' '";
$wc = shell_exec($cmd);
// proceed if words are less than 10
    if ($wc < 10)
    {
//take out the pdf extension for directory creation
    $imgdir = preg_replace('"\.(pdf|PDF)$"', '', $uploadedfile);
    $cmd = "mkdir '$imgdir'";
    shell_exec($cmd);
//change pdf extension to jpg for images creation
    $imgfile = preg_replace('"\.(pdf|PDF)$"', '.jpg', $uploadedfile);
//convert pdf to images
    $cmd = "convert 'orig/$uploadedfile' '$imgdir/$imgfile'";

然后它会出现OCR...

更新2感谢@Mark-Setchell的建议,我修改了一点代码,现在最后一部分是这样的:

//take out the pdf extension for directory creation
$imgdir = preg_replace('"\.(pdf|PDF)$"', '', $uploadedfile);
$cmd = "mkdir '$imgdir'";
shell_exec($cmd);
//convert pdf to images
$cmd = "pdfimages 'orig/$uploadedfile' '$imgdir/$imgdir'";
oxf4rvwz

oxf4rvwz1#

您可以使用Poppler包中的pdfimages来列出和提取所有原始格式、大小和质量的图像:

pdfimages -list SomeFile.pdf
page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   9     0 image      37    39  icc     3   8  jpeg   no       978  0   102   102  915B  21%
   9     1 smask      37    39  gray    1   8  image  no       978  0   102   102  334B  23%
   9     2 image     110   120  icc     3   8  jpeg   no       977  0   101   101 2246B 5.7%
   9     3 image     113   103  icc     3   8  jpeg   no       976  0   101   101 2951B 8.5%
  20     4 image     212   156  icc     3   8  jpeg   no       996  0   101   101 3664B 3.7%
  20     5 image      19    23  icc     3   8  jpeg   no      1003  0   103   103 1619B 123%
  20     6 smask      19    23  gray    1   8  image  no      1003  0   103   103  291B  67%
  22     7 image     212   156  icc     3   8  jpeg   no      1188  0   101   101 3579B 3.6%
  24     8 image     212   156  icc     3   8  jpeg   no      1195  0   101   101 2824B 2.8%
  25     9 image     212   156  icc     3   8  jpeg   no      1202  0   101   101 3247B 3.3%
  25    10 image     348    92  icc     3   8  jpeg   no      1209  0   101   101 5022B 5.2%
  25    11 smask     348    92  gray    1   8  jpeg   no      1209  0   101   101  754B 2.4%
  32    12 image     600   400  icc     3   8  jpeg   no      1217  0   150   150 26.9K 3.8%
  32    13 smask     600   400  gray    1   8  jpeg   no      1217  0   150   150 3090B 1.3%
  43    14 image     151   101  icc     3   8  jpeg   no      1228  0   101   102 2656B 5.8%
  43    15 image      71    84  icc     3   8  jpeg   no      1227  0   101   101 1540B 8.6%
  43    16 image     119    84  icc     3   8  jpeg   no      1226  0   101   101 1768B 5.9%
  43    17 image      83    84  icc     3   8  jpeg   no      1230  0   101   101 2082B  10%
  43    18 image     118    84  icc     3   8  jpeg   no      1229  0   101   101 2205B 7.4%
  46    19 image     170   114  icc     3   8  jpeg   no      1243  0   101   101 2594B 4.5%
  46    20 image     125    84  icc     3   8  jpeg   no      1242  0   101   101 3029B 9.6%
  46    21 image     125    84  icc     3   8  jpeg   no      1242  0   101   101 3029B 9.6%
  46    22 image     126    84  index   1   8  image  no      1244  0   101   101 5849B  55%
  48    23 image     226   234  icc     3   8  jpeg   no      1260  0   151   151 5310B 3.3%
  48    24 smask     226   234  gray    1   8  image  no      1260  0   151   151   81B 0.2%
  48    25 image     226   234  icc     3   8  jpeg   no      1259  0   151   151 10.3K 6.7%
  48    26 smask     226   234  gray    1   8  image  no      1259  0   151   151   81B 0.2%
  48    27 image     226   234  icc     3   8  jpeg   no      1259  0   151   151 10.3K 6.7%
  48    28 smask     226   234  gray    1   8  image  no      1259  0   151   151   81B 0.2%
  48    29 image     226   234  icc     3   8  jpeg   no      1264  0   151   151 4052B 2.6%
  48    30 smask     226   234  gray    1   8  image  no      1264  0   151   151  284B 0.5%
  48    31 image     109   113  index   1   8  image  no      1263  0   151   150 5066B  41%
  48    32 smask     109   113  gray    1   8  image  no      1263  0   151   150   76B 0.6%
  48    33 image     109   113  index   1   8  image  no      1262  0   151   150 5362B  44%
  48    34 smask     109   113  gray    1   8  image  no      1262  0   151   150   76B 0.6%
  48    35 image     226   234  index   1   8  image  no      1261  0   151   151 15.5K  30%
  48    36 smask     226   234  gray    1   8  image  no      1261  0   151   151  284B 0.5%
  50    37 image     156   103  icc     3   8  jpeg   no      1291  0   101   101 3625B 7.5%
  50    38 smask     156   103  gray    1   8  jpeg   no      1291  0   101   101  490B 3.0%
  50    39 image     156   103  icc     3   8  jpeg   no      1290  0   101   101 3615B 7.5%
  50    40 smask     156   103  gray    1   8  jpeg   no      1290  0   101   101  472B 2.9%
  50    41 image     157   103  icc     3   8  jpeg   no      1289  0   101   101 3254B 6.7%
  50    42 image     157   104  index   1   8  image  no      1292  0   101   101 3020B  18%
  52    43 image     181   139  icc     3   8  jpeg   no      1309  0   101   101 4407B 5.8%
  52    44 image     181   139  icc     3   8  jpeg   no      1308  0   101   101 4744B 6.3%
  52    45 image     181   139  icc     3   8  jpeg   no      1307  0   101   101 2356B 3.1%
  53    46 image     261   146  icc     3   8  jpeg   no      1320  0   151   150 6577B 5.8%
  53    47 smask     261   146  gray    1   8  image  no      1320  0   151   150  264B 0.7%
  53    48 image     261   146  icc     3   8  jpeg   no      1319  0   151   150 7406B 6.5%
  53    49 smask     261   146  gray    1   8  image  no      1319  0   151   150  264B 0.7%
  53    50 image     261   146  icc     3   8  jpeg   no      1318  0   151   150 9274B 8.1%
  53    51 smask     261   146  gray    1   8  image  no      1318  0   151   150  264B 0.7%
  53    52 image     261   146  icc     3   8  jpeg   no      1318  0   151   150 9274B 8.1%
  53    53 smask     261   146  gray    1   8  image  no      1318  0   151   150  264B 0.7%
  53    54 image     261   146  index   1   8  image  no      1323  0   151   150 6681B  18%
  53    55 smask     261   146  gray    1   8  image  no      1323  0   151   150  264B 0.7%
  53    56 image     261   146  icc     3   8  jpeg   no      1322  0   151   151 7089B 6.2%
  53    57 smask     261   146  gray    1   8  image  no      1322  0   151   151  264B 0.7%
  53    58 image     261   146  index   1   8  image  no      1321  0   151   150 6981B  18%
  53    59 smask     261   146  gray    1   8  image  no      1321  0   151   150  264B 0.7%
  58    60 image     600   556  icc     3   8  image  no      1344  0   145   145  289K  30%
  58    61 smask     600   556  gray    1   8  jpeg   no      1344  0   145   145 8055B 2.4%
  71    62 image     150   175  icc     3   8  jpeg   no      1383  0   101   101 4008B 5.1%
  71    63 image     150   174  icc     3   8  jpeg   no      1382  0   101   101 2523B 3.2%
  74    64 image     510   456  rgb     3   8  image  no      1392  0   144   144 22.9K 3.4%
  74    65 smask     510   456  gray    1   8  image  no      1392  0   144   144 1438B 0.6%
  74    66 image     443   177  rgb     3   8  image  no      1398  0   144   144 25.0K  11%
  74    67 smask     443   177  gray    1   8  image  no      1398  0   144   144  102B 0.1%

然后使用extracted作为文件名的根来提取它们:

pdfimages SomeDoc.pdf extracted

-rw-r--r--@ 1 mark  staff      915  7 Oct 10:21 extracted-000.jpg
-rw-r--r--  1 mark  staff     4342  7 Oct 10:21 extracted-000.ppm
-rw-r--r--  1 mark  staff     4342  7 Oct 10:21 extracted-001.ppm
-rw-r--r--@ 1 mark  staff     2246  7 Oct 10:21 extracted-002.jpg
-rw-r--r--  1 mark  staff    39615  7 Oct 10:21 extracted-002.ppm
-rw-r--r--@ 1 mark  staff     2951  7 Oct 10:21 extracted-003.jpg
-rw-r--r--  1 mark  staff    34932  7 Oct 10:21 extracted-003.ppm
-rw-r--r--@ 1 mark  staff     3664  7 Oct 10:21 extracted-004.jpg
-rw-r--r--  1 mark  staff    99231  7 Oct 10:21 extracted-004.ppm
-rw-r--r--@ 1 mark  staff     1619  7 Oct 10:21 extracted-005.jpg
-rw-r--r--  1 mark  staff     1324  7 Oct 10:21 extracted-005.ppm
-rw-r--r--  1 mark  staff     1324  7 Oct 10:21 extracted-006.ppm
-rw-r--r--@ 1 mark  staff     3579  7 Oct 10:21 extracted-007.jpg
-rw-r--r--  1 mark  staff    99231  7 Oct 10:21 extracted-007.ppm
-rw-r--r--@ 1 mark  staff     2824  7 Oct 10:21 extracted-008.jpg
-rw-r--r--  1 mark  staff    99231  7 Oct 10:21 extracted-008.ppm
-rw-r--r--@ 1 mark  staff     3247  7 Oct 10:21 extracted-009.jpg
-rw-r--r--  1 mark  staff    99231  7 Oct 10:21 extracted-009.ppm
-rw-r--r--@ 1 mark  staff     5022  7 Oct 10:21 extracted-010.jpg
-rw-r--r--  1 mark  staff    96062  7 Oct 10:21 extracted-010.ppm
-rw-r--r--@ 1 mark  staff      754  7 Oct 10:21 extracted-011.jpg
-rw-r--r--  1 mark  staff    96062  7 Oct 10:21 extracted-011.ppm
-rw-r--r--@ 1 mark  staff    27539  7 Oct 10:21 extracted-012.jpg
-rw-r--r--  1 mark  staff   720015  7 Oct 10:21 extracted-012.ppm
-rw-r--r--@ 1 mark  staff     3090  7 Oct 10:21 extracted-013.jpg
-rw-r--r--  1 mark  staff   720015  7 Oct 10:21 extracted-013.ppm
-rw-r--r--@ 1 mark  staff     2656  7 Oct 10:21 extracted-014.jpg
-rw-r--r--  1 mark  staff    45768  7 Oct 10:21 extracted-014.ppm
-rw-r--r--@ 1 mark  staff     1540  7 Oct 10:21 extracted-015.jpg
-rw-r--r--  1 mark  staff    17905  7 Oct 10:21 extracted-015.ppm
-rw-r--r--@ 1 mark  staff     1768  7 Oct 10:21 extracted-016.jpg
-rw-r--r--  1 mark  staff    30002  7 Oct 10:21 extracted-016.ppm
-rw-r--r--@ 1 mark  staff     2082  7 Oct 10:21 extracted-017.jpg
-rw-r--r--  1 mark  staff    20929  7 Oct 10:21 extracted-017.ppm
-rw-r--r--@ 1 mark  staff     2205  7 Oct 10:21 extracted-018.jpg
-rw-r--r--  1 mark  staff    29750  7 Oct 10:21 extracted-018.ppm
-rw-r--r--@ 1 mark  staff     2594  7 Oct 10:21 extracted-019.jpg
-rw-r--r--  1 mark  staff    58155  7 Oct 10:21 extracted-019.ppm
-rw-r--r--@ 1 mark  staff     3029  7 Oct 10:21 extracted-020.jpg
-rw-r--r--  1 mark  staff    31514  7 Oct 10:21 extracted-020.ppm
-rw-r--r--@ 1 mark  staff     3029  7 Oct 10:21 extracted-021.jpg
-rw-r--r--  1 mark  staff    31514  7 Oct 10:21 extracted-021.ppm
-rw-r--r--  1 mark  staff    31766  7 Oct 10:21 extracted-022.ppm
-rw-r--r--@ 1 mark  staff     5310  7 Oct 10:21 extracted-023.jpg
-rw-r--r--  1 mark  staff   158667  7 Oct 10:21 extracted-023.ppm
-rw-r--r--  1 mark  staff   158667  7 Oct 10:21 extracted-024.ppm
-rw-r--r--@ 1 mark  staff    10564  7 Oct 10:21 extracted-025.jpg
-rw-r--r--  1 mark  staff   158667  7 Oct 10:21 extracted-025.ppm
-rw-r--r--  1 mark  staff   158667  7 Oct 10:21 extracted-026.ppm
-rw-r--r--@ 1 mark  staff    10564  7 Oct 10:21 extracted-027.jpg
-rw-r--r--  1 mark  staff   158667  7 Oct 10:21 extracted-027.ppm
-rw-r--r--  1 mark  staff   158667  7 Oct 10:21 extracted-028.ppm
-rw-r--r--@ 1 mark  staff     4052  7 Oct 10:21 extracted-029.jpg
-rw-r--r--  1 mark  staff   158667  7 Oct 10:21 extracted-029.ppm
-rw-r--r--  1 mark  staff   158667  7 Oct 10:21 extracted-030.ppm
-rw-r--r--  1 mark  staff    36966  7 Oct 10:21 extracted-031.ppm
-rw-r--r--  1 mark  staff    36966  7 Oct 10:21 extracted-032.ppm
-rw-r--r--  1 mark  staff    36966  7 Oct 10:21 extracted-033.ppm
-rw-r--r--  1 mark  staff    36966  7 Oct 10:21 extracted-034.ppm
-rw-r--r--  1 mark  staff   158667  7 Oct 10:21 extracted-035.ppm
-rw-r--r--  1 mark  staff   158667  7 Oct 10:21 extracted-036.ppm
-rw-r--r--@ 1 mark  staff     3625  7 Oct 10:21 extracted-037.jpg
-rw-r--r--  1 mark  staff    48219  7 Oct 10:21 extracted-037.ppm
-rw-r--r--@ 1 mark  staff      490  7 Oct 10:21 extracted-038.jpg
-rw-r--r--  1 mark  staff    48219  7 Oct 10:21 extracted-038.ppm
-rw-r--r--@ 1 mark  staff     3615  7 Oct 10:21 extracted-039.jpg
-rw-r--r--  1 mark  staff    48219  7 Oct 10:21 extracted-039.ppm
-rw-r--r--@ 1 mark  staff      472  7 Oct 10:21 extracted-040.jpg
-rw-r--r--  1 mark  staff    48219  7 Oct 10:21 extracted-040.ppm
-rw-r--r--@ 1 mark  staff     3254  7 Oct 10:21 extracted-041.jpg
-rw-r--r--  1 mark  staff    48528  7 Oct 10:21 extracted-041.ppm
-rw-r--r--  1 mark  staff    48999  7 Oct 10:21 extracted-042.ppm
-rw-r--r--@ 1 mark  staff     4407  7 Oct 10:21 extracted-043.jpg
-rw-r--r--  1 mark  staff    75492  7 Oct 10:21 extracted-043.ppm
-rw-r--r--@ 1 mark  staff     4744  7 Oct 10:21 extracted-044.jpg
-rw-r--r--  1 mark  staff    75492  7 Oct 10:21 extracted-044.ppm
-rw-r--r--@ 1 mark  staff     2356  7 Oct 10:21 extracted-045.jpg
-rw-r--r--  1 mark  staff    75492  7 Oct 10:21 extracted-045.ppm
-rw-r--r--@ 1 mark  staff     6577  7 Oct 10:21 extracted-046.jpg
-rw-r--r--  1 mark  staff   114333  7 Oct 10:21 extracted-046.ppm
-rw-r--r--  1 mark  staff   114333  7 Oct 10:21 extracted-047.ppm
-rw-r--r--@ 1 mark  staff     7406  7 Oct 10:21 extracted-048.jpg
-rw-r--r--  1 mark  staff   114333  7 Oct 10:21 extracted-048.ppm
-rw-r--r--  1 mark  staff   114333  7 Oct 10:21 extracted-049.ppm
-rw-r--r--@ 1 mark  staff     9274  7 Oct 10:21 extracted-050.jpg
-rw-r--r--  1 mark  staff   114333  7 Oct 10:21 extracted-050.ppm
-rw-r--r--  1 mark  staff   114333  7 Oct 10:21 extracted-051.ppm
-rw-r--r--@ 1 mark  staff     9274  7 Oct 10:21 extracted-052.jpg
-rw-r--r--  1 mark  staff   114333  7 Oct 10:21 extracted-052.ppm
-rw-r--r--  1 mark  staff   114333  7 Oct 10:21 extracted-053.ppm
-rw-r--r--  1 mark  staff   114333  7 Oct 10:21 extracted-054.ppm
-rw-r--r--  1 mark  staff   114333  7 Oct 10:21 extracted-055.ppm
-rw-r--r--@ 1 mark  staff     7089  7 Oct 10:21 extracted-056.jpg
-rw-r--r--  1 mark  staff   114333  7 Oct 10:21 extracted-056.ppm
-rw-r--r--  1 mark  staff   114333  7 Oct 10:21 extracted-057.ppm
-rw-r--r--  1 mark  staff   114333  7 Oct 10:21 extracted-058.ppm
-rw-r--r--  1 mark  staff   114333  7 Oct 10:21 extracted-059.ppm
-rw-r--r--  1 mark  staff  1000815  7 Oct 10:21 extracted-060.ppm
-rw-r--r--@ 1 mark  staff     8055  7 Oct 10:21 extracted-061.jpg
-rw-r--r--  1 mark  staff  1000815  7 Oct 10:21 extracted-061.ppm
-rw-r--r--@ 1 mark  staff     4008  7 Oct 10:21 extracted-062.jpg
-rw-r--r--  1 mark  staff    78765  7 Oct 10:21 extracted-062.ppm
-rw-r--r--@ 1 mark  staff     2523  7 Oct 10:21 extracted-063.jpg
-rw-r--r--  1 mark  staff    78315  7 Oct 10:21 extracted-063.ppm
-rw-r--r--  1 mark  staff   697695  7 Oct 10:21 extracted-064.ppm
-rw-r--r--  1 mark  staff   697695  7 Oct 10:21 extracted-065.ppm
-rw-r--r--  1 mark  staff   235248  7 Oct 10:21 extracted-066.ppm
-rw-r--r--  1 mark  staff   235248  7 Oct 10:21 extracted-067.ppm
mrphzbgm

mrphzbgm2#

我还没有对世界上的每一个pdf文件进行测试,所以可能会有一些假阳性或假阴性,但这段代码对我来说正好是OP想要做的。当上传的PDF文件中有一些文本时,我使用PHP文本提取库,如果它是一个只有图像的PDF,我会将其发送到几个OCR作为服务端点。(虽然不是OP问题的一部分,但我为什么要发送到多个服务?答:因为我没有发现一个是准确的。通过使用六个,我通常可以找到我正在搜索的文本至少被其中一个识别,但在OCR世界中仍然是命中和错过。当然,如果PDF是基于文本的,提取后的搜索结果是100%准确的。

$path='path to your pdf file';
$buf=file_getcontents($path);
if(strpos($buf,'/Font')===false){
 print $path.' is an image only pdf';
}else{
 if(strpos($buf,'/Image')===false){
  print $path.' is a text only pdf';
 }else{
  print $path.' is a pdf consisting of both text and images';
 }
}

相关问题