如何检测PDF中内嵌图像的方向?
嘿,我太懂你这种头疼的情况了——扫描生成的PDF里图像居然倒着存在里面,翻遍pdfparser的属性都找不到能判断方向的标记,确实闹心。结合你说的“每周最多两三个文件、性能完全无所谓”的场景,给你几个实用的解决思路,都是能直接套进你现有代码里的:
1. 先试试从PDF页面的旋转属性下手
你提到试过getPages()[0]->getDataTm()返回空,可能这类极简扫描PDF根本没存这个变换矩阵。不过可以换个方法,直接拿pdfparser提供的页面旋转属性:
$page = $pdf->getPages()[0]; $rotation = $page->getRotation(); // 标准返回值是0/90/180/270
如果扫描设备或者生成PDF的工具良心,把旋转信息存在了PDF页面属性里,这个值直接就能告诉你要不要转180度。但可惜很多扫描生成的PDF根本不存这个,这时候就只能从图像内容本身入手了。
2. 用Tesseract自带的方向检测(最推荐)
既然你本来就要用Tesseract处理OCR,其实它自己就有专门的文本方向检测功能,完全不用依赖PDF的元数据,准确率还超高。步骤很简单:
- 先给Tesseract跑一次方向检测,拿到图像的旋转角度
- 根据结果动态旋转图像,再做OCR
对应的PHP代码片段可以插在你保存完图像之后、OCR之前:
// 先检测图像方向 $detectCmd = sprintf( "%s %s stdout --psm 0", TESSERACT_LOCATION, escapeshellarg($imageName) ); $detectOutput = shell_exec($detectCmd); // 从输出里提取旋转角度 preg_match('/Orientation in degrees: (\d+)/', $detectOutput, $matches); $needRotate = isset($matches[1]) ? (int)$matches[1] : 0; // 如果需要旋转,就调用ImageMagick处理 if ($needRotate != 0) { $rotateCmd = sprintf( "convert -rotate %d %s %s", $needRotate, escapeshellarg($imageName), escapeshellarg($imageName) ); exec($rotateCmd); }
这个方法的好处是完全不依赖PDF的任何元数据——不管图像在PDF里是倒着、侧着,Tesseract能通过识别文本的方向直接判断,完美适配你的场景(反正本来就要跑Tesseract,多一次检测完全没压力)。
3. 图像层面的兜底检测(备选方案)
如果遇到极端情况(比如图像里文本特别少,Tesseract检测不准),还可以用GD或Imagick做个简单的像素分布判断:
- 扫描的文本图像,通常文本的像素会集中在中间区域,倒过来后这个分布会“上下颠倒”,但这个方法容错率低,只适合当备选。
- 举个GD的简单示例(思路为主,不用照搬):
$img = imagecreatefromjpeg($imageName); $height = imagesy($img); $topPixelCount = 0; $bottomPixelCount = 0; $threshold = 0xFFFFFF; // 白色阈值,非白色算文本像素 // 统计上下半区的非白色像素数 for ($x = 0; $x < imagesx($img); $x++) { for ($y = 0; $y < $height/2; $y++) { if (imagecolorat($img, $x, $y) < $threshold) { $topPixelCount++; } } for ($y = $height/2; $y < $height; $y++) { if (imagecolorat($img, $x, $y) < $threshold) { $bottomPixelCount++; } } } imagedestroy($img); // 如果上下像素占比差特别大,判断为倒转(比如底部像素只有顶部的30%以下) if ($bottomPixelCount / $topPixelCount < 0.3) { // 执行旋转180度的命令 }
不过这个方法对留白均匀的图像完全失效,所以还是优先用Tesseract的方案。
对你现有代码的小调整
你现在是用ROTATE_IMAGE常量强制旋转,把它替换成上面检测到的$needRotate != 0就行了,这样就能实现自动判断旋转,不用硬编码。
最后说回你提到的pdfparser拿不到方向的问题:很多极简扫描PDF就是把图像直接塞进去,完全不在PDF结构里加任何旋转标记,这时候不管用什么PDF解析库都拿不到方向信息,只能从图像内容本身入手——而Tesseract的方向检测是最省心、准确率最高的方案。
内容来源于stack exchange

