AI活用

扫描的PDF读不出文字、pdftotext输出为空时:用pdftoppm转成图片让AI读取的5个步骤

扫描的PDF读不出文字、pdftotext输出为空时:用pdftoppm转成图片让AI读取的5个步骤

早上好,我是まさきん。

孩子去体验兴趣班时拿回来一张传单,我用手机扫描之后想让AI读一下。结果从PDF里一个字都取不出来。我想只要是把家里的纸质资料数字化的人,迟早都会碰上一次,所以把分辨方法和应对办法记下来。

※本文为发布时的信息,最新条件请以官方网站为准。

POINT
  • 扫描的PDF读不出文字时,先看 pdftotext 的输出是不是空的
  • 如果是空的,就用 pdftoppm -r 200 -png 把页面转成图片,以图片的形式交给AI
  • 原因可以想到3种:“只有图片的PDF”“OCR层很粗糙”“没有字符编码的对应关系”
  • 分辨率方面,交给AI的话以150〜200dpi为参考,重新做OCR的话以300dpi为参考
  • 金额和日期这类数字,最后一定要对照纸质原件确认

扫描的PDF取不出文字

我用的是 Adobe Scan。把兴趣班的传单拍下来,保存成了PDF。打开一看,外观很干净,文字看起来也能选中。

我把这个PDF交给了一个叫 pdftotext 的命令处理。它是只从PDF里提取文字的工具。结果是空的,能用的文字一行都没出来。

于是我把页面转成图片交给AI,内容很正常地读出来了。

需要说明的是,这只是我那一张传单的情况,并不是想说App有缺陷。请把它当作“扫描App生成的PDF有可能发生这种事”的整理来读。

PDF有“看得见的层”和“文字的层”

扫描出来的PDF,底子是给纸拍的照片。在它上面,OCR识别出的文字作为透明的一层叠加上去。OCR就是把图片里的文字变成数据的处理。

屏幕上看到的是照片那一层,搜索和复制时用到的是透明的文字层。所以即使外观很干净,文字层也可能用不了。

把PDF交给AI时,也和这两层有关。如果用的是只读文字层的工具,层是空的话就什么也传达不过去。我认为这就是这次绊倒的真正原因。

分辨症状的3种方法

按不是工程师也能确认的顺序排列。

  1. 打开PDF拖选文字。选不中,或者粘贴出来是乱码
  2. 运行 pdftotext。输出是空的,或者只有换页符号
  3. 运行 pdffonts。一行字体都不显示

第1种只用App就能试,复制之后贴到记事本里就行。这一步如果是空的或乱码,文字层也许就不要指望了。

可以想到的3种原因

我并没有查明自己那张传单属于哪一种。所以这里是作为一般情况的整理。

种类内容复制粘贴的结果pdffonts 的显示
只有图片的PDF根本没有文字层无法选中不显示字体
OCR层很粗糙有层,但误识别很多变成别的字或残缺的句子显示字体
没有字符编码的对应关系没有文字和Unicode的对应表,或者对应表已损坏变成符号或空白uni 一列有时是 no

第3种需要稍微补充一下。pdffonts 的官方手册里有对 uni 这一列的说明:如果PDF里有名为 ToUnicode 的对应表,这一列就是 yes。

不过,手册里也有一条注意事项,大意是即使没有对应表,也不一定就不能转换成文字。所以 uni 是 no 也不代表立刻出局。把它当作线索之一来看比较好。

pdftotext 的手册里,BUGS一栏也写着类似的内容:有些PDF包含编码损坏的字体,这种情况下除了OCR之外没有别的办法提取文字。大意如此。看来工具这一方也承认“有取不出来的PDF”。

poppler 的安装方法

pdftotext 和 pdftoppm 都包含在一个叫 poppler 的软件里。它是处理PDF的经典免费工具。

环境安装方法补充
macOSbrew install poppler需要 Homebrew
Ubuntu / Debiansudo apt install poppler-utils软件包名是 poppler-utils
Windows在 WSL 的 Ubuntu 里用上面的 apt 安装官方网站以发布源代码为主

Windows 稍微麻烦一些。poppler 官方网站发布的是源代码,各个系统用的则是由各发行方提供的软件包。换作是我,会用 WSL 装上 Ubuntu,然后在里面用 apt。

有没有装好,可以用下面的命令确认。

pdftotext -v

显示出版本号就可以了。

应对的步骤

流程分5个阶段。我想到第4步为止,大部分的纸都能处理完。

步骤1:用 pdftotext 确认是不是空的

先看文字层能不能用。文件名这里以 flyer.pdf 为例。

pdftotext -layout flyer.pdf flyer.txt
wc -c flyer.txt

-layout 是尽量保持原来版面布局的选项。像传单这种分栏多的纸,加上它会更好读。wc -c 只是统计文件大小的命令。

如果数字是0或个位数,文字就没有取出来。我的传单在这一步就是空的。反过来,如果能正常输出文章,就可以直接用,不需要转成图片。

要限定页数的话,用 -f 和 -l,也就是起始页和结束页的页码。

pdftotext -f 1 -l 2 -layout flyer.pdf -

最后的 - 表示不写入文件,而是输出到屏幕上。

步骤2:用 pdffonts 和 pdfimages 看里面的内容

这一步省略也没关系。不过因为能对原因有个大致判断,我是倾向于做一下的那一派。

pdffonts flyer.pdf
pdfimages -list flyer.pdf

pdffonts 会列出PDF里的字体。如果只输出了表头那一行,基本可以认为没有文字层。pdfimages -list 会列出里面的图片。如果每一页各有一张大图,那就是扫描得来的PDF了。

步骤3:用 pdftoppm 把页面转成图片

如果取不出文字,就转成每页一张的图片。

pdftoppm -r 200 -png flyer.pdf page

这样就会生成 page-1.png、page-2.png 这样的文件。-r 是分辨率,单位是dpi,不指定的话是150。不加 -png 的话会输出成PPM这种不好处理的格式,所以这里最好不要忘。

只想要1页的时候这样做。

pdftoppm -r 200 -png -f 1 -l 1 -singlefile flyer.pdf flyer

加上 -singlefile,就只会生成一张不带编号的 flyer.png。

步骤4:以图片的形式交给AI

把生成的PNG直接添加到AI的聊天里。就我的情况来说,这样就读出了内容。

请求的写法越具体,结果越稳定。比如这样的内容。

附件是扫描传单得到的图片。
请把日期时间、地点、携带物品、费用、报名截止日期整理成表格。
读不出来的地方不要推测,请写“无法辨认”。

我认为最后一行很重要。因为AI有时会把读不出来的字像模像样地补上。

直接交PDF不行吗

并不是不行。Claude 面向开发者的文档里,写着把PDF的每一页转换成图片的处理。它的机制是把从页面提取的文字和图片两者一起传过去。Gemini 的文档里,也有把PDF作为图片来理解的说明。

所以,把PDF直接放进App里,很多时候应该也能读出来。会出问题的,是走上了只使用文字提取的那条路径的时候。比如用自己写的脚本只把 pdftotext 的结果传过去,就属于这种情况。

页数多的PDF也需要注意。Claude 的帮助页面上写着,页数多的时候会变成只处理文字。拿不准的时候就转成图片再交,把这个定为默认做法,应该会比较安心吧。

我想今后让AI读家庭开支相关纸张的场面还会越来越多。对比价目表这件事,在重新审视通信费的时候也是一样的。

无需签约也能获得100积分的资费模拟 手机资费也把价目表摆在一起重新看看

点击后会跳转到乐天登录页面,登录后即可看到活动内容。

步骤5:有需要的话用OCRmyPDF重新加上文字层

想把PDF本身以可搜索的形式保存下来。这种时候,有重新加上文字层的方法,就是一个叫 OCRmyPDF 的免费工具。

根据官方文档,它是给扫描图片的PDF加上文字层、使其可以搜索的工具。OCR的核心用的是名为 Tesseract 的引擎。

brew install ocrmypdf
brew install tesseract-lang
ocrmypdf -l jpn --redo-ocr flyer.pdf flyer-ocr.pdf

-l jpn 是指定按日语来识别。不指定的话会当作英语处理。日语的纸如果忘了这一点,我想结果会乱得相当厉害。在 Ubuntu 上,语言数据要通过 tesseract-ocr-jpn 这样的独立软件包安装。

--redo-ocr 是把其他软件加上的OCR重做一遍的选项。如果不顺利,还有 --force-ocr。不过后者会把所有页面重新做成图片。官方也写着画质有可能下降。

话虽如此,精度是有限的。文档自己也写着有时比不上商用的OCR。如果只是读一张传单,把图片交给AI大概更快。

分辨率的参考值

-r 的数字设成多少,要看交给谁来变。按A4纸计算是这样的。

分辨率A4的像素数(大致)适合的用法
150dpi(默认)1240 × 1754让AI读普通大小的文字
200dpi1654 × 2339带有小字注意事项的传单
300dpi2480 × 3508交给Tesseract等OCR处理

并不是越大越好。Claude 的文档里写着,超过上限的图片会在处理之前被缩小。Gemini 也说明,大的页面会被缩小到最大3072 × 3072。调得太高也只是被丢掉而已。

另一方面,Tesseract 的官方文档说,它在300dpi以上的图片上工作得比较好。所以我的参考值有2个:给AI用150〜200,给OCR用300。

小字读不出来的时候,比起提高分辨率,裁剪出来也许更有效。也就是只把价目表那部分做成另一张图片再交过去。

数字一定要对照原件确认

就算用图片读出来了,数字也不一定是对的。

同一天,我还把体验说明会的录音转成了文字。这边出现了金额听错的情况。我只把相关的部分截出来,用精度更高的模型重做之后才确定下来。经过写在Whisper把金额数字弄错的那件事里。

不管是纸还是声音,AI给出的数字都只是草稿。像月费、报名截止日期这样的数字,最后要和纸质原件对照一下。我觉得只有这一步最好不要省。

交出含有个人信息的纸张时的注意事项

学校和兴趣班的纸上,有时会印着姓名和联系方式。在交给AI之前,希望能稍微停一下。

注意
  • 先看有没有拍进姓名、住址、电话号码、人脸照片
  • 不需要的部分,先把图片裁掉再交
  • 确认一次所用AI服务对数据的处理方式(是否用于训练的设置)
  • 印有其他家庭姓名的名册和联络网,根本就不要交

转成图片的好处在这里也有体现。保持PDF的话,要遮住一部分很麻烦。图片的话,用手机的相册App裁剪一下就行了。

还有一点。PDF里有时会带着创建时间、App名称等信息。转成图片之后这些就没有了,所以从减少交出去的信息这个意义上说,我感觉也不坏。

扫描时的小窍门

让后续工序变轻松的,归根结底还是拍法。这里把一般常说的几点列出来。

最后一项我是在 Adobe Scan 的官方帮助里确认的。文字识别默认是开启的。在偏好设置的“对已保存的 PDF 运行文本识别”里也可以关掉。

据说识别的语言默认是设备的语言,可以在偏好设置的“文本识别语言”里更改。支持的语言里也包括日语。把设备设成英语来用的人,把这里改成日语也许比较好。

帮助里还写着,页数多的扫描不会执行OCR。上限似乎免费版和付费版不一样。一次拍几十页的人,请看一下官方最新的记载。

常见的失误与陷阱

凭外观来判断。 就算在屏幕上读得很清楚,文字层也不一定能用。试一次复制粘贴就知道了。

忘了加 -png。 pdftoppm 默认输出的是PPM格式。很多时候没法添加到AI的聊天里,所以要指定PNG或JPEG。

分辨率调得太高。 用600dpi输出的话文件会变大,要么碰到上传的上限,要么最后还是被缩小。

不指定OCR的语言。 OCRmyPDF 没有指定的话会当作英语来读。日语的纸需要 -l jpn。

把AI读出来的内容直接记进日程。 日期和金额先和原件对照之后再登记比较安全。把通知单变成日程的流程,写在把学校通知单登记到日历和提醒事项的机制里。

常见问题

Q. 为什么扫描的PDF读不出文字?

可以认为是没有文字层,或者有但处于用不了的状态。有代表性的是3种:只有图片的PDF、OCR的误识别,以及没有字符编码对应关系的情况。属于哪一种,用 pdftotext 和 pdffonts 可以在一定程度上判断出来。

Q. 为什么 pdftotext 输出为空却不报错?

因为没有文字层的PDF并不是损坏了。没有可提取的文字,所以正常地返回了空的结果。正因为不报错,在自动处理里就不容易发现。

Q. 有没有不用命令就能解决的办法?

有。把打开PDF的画面截个图,那就是图片了。用手机的话,我觉得把原来的照片直接交给AI也是个办法。只有张数多的时候,用命令才会更省事。

Q. PNG和JPEG哪个好?

以文字为主的纸,用PNG比较稳妥。JPEG因为压缩,文字边缘有时会发虚。不过文件太大的时候,换成 -jpeg 会轻一些。

Q. 用 PyMuPDF 等别的工具可以吗?

没问题。我在练习题的批量扫描与分拣里就是用 PyMuPDF 转成图片的。做的事情是一样的,只是把页面变成图片。我觉得用手边现有的工具就足够了。

Q. OCRmyPDF 是一定要用的吗?

不是。如果只是让AI读内容,图片就够了。它是在想把PDF保存下来、以后再搜索这种目的下的一个选项。

Q. 手写的文字也能读吗?

如果是AI的图片识别,很多时候是能读的。不过字迹潦草或者很淡的铅笔字,误读会变多。像 Tesseract 这样的传统OCR,一般认为不擅长手写。

Q. 只用手机就能搞定吗?

可以。从扫描App里以图片(JPEG)导出,再交给AI的App,就是一样的效果。需要做成PDF的,也许只有想把多页合成一个文件的时候。

参考的官方信息

总结

扫描出来的PDF,外观和文字层是两回事。pdftotext 是空的话,不用纠结,直接用 pdftoppm 转成图片。在我这里这样就读出来了。查明原因往后放一放,我想也不会有什么困扰。

纸上的信息变成数据之后,对比起来就轻松了。兴趣班的月费也好,手机的资费也好,都是一样的。只要把数字摆在一起看,做判断就会轻松不少吧。

无需签约也能获得100积分的资费模拟 通信费也把数字摆在一起重新看看

点击后会跳转到乐天登录页面,登录后即可看到活动内容。

本文包含联盟营销广告。如果您通过本站链接申请相关商品或服务,我们可能会从合作企业获得报酬。此外,运营者是乐天集团的员工,也可能通过员工推荐计划获得报酬。文章内容与评价均基于运营者的真实体验与调查完成,与是否存在广告无关,但请您在阅读前了解上述关系。详情请参阅免责声明与联盟营销说明。 免责声明与联盟营销说明

本文包含机器翻译内容。正式条件请以乐天移动官方网站的多语言页面为准。

如果您对乐天移动的通信区域·信号状况有疑问,可以通过官方的 电波改善调查申请表 进行咨询。

ABOUT THE AUTHOR
まさきん

乐天集团员工·数字营销人(持有FP资格)

40岁出头,双职工家庭、四个孩子的父亲。在乐天集团担任数字营销工作的同时,也活用理财规划师(FP)资格,专注于家庭理财与资产配置。

查看简介

相关文章

RELATED
Gemini(Google AI Pro)家庭共享最多5名家人|设置步骤与共享范围 AI活用

Gemini(Google AI Pro)家庭共享最多5名家人|设置步骤与共享范围

Google AI Pro除管理员外最多可与5名家人共享。Gemini App和存储空间可以共享,YouTube Premium Lite仅限管理员,Flow的上限由全家分摊。本文根据官方帮助整理了设置步骤和儿童账号的处理方式。

2026.10.13 · 阅读约9分钟
AI订阅扣款日与记账对不上的3个原因|Claude升级后扣款日会改变 AI活用

AI订阅扣款日与记账对不上的3个原因|Claude升级后扣款日会改变

Claude在月中升级到Max时,计费周期会重置,当天成为新的扣款日。美元换算日元的汇率在数据到达发卡公司时确定,账单和记账App的同步也会晚几天。本文整理了以收据邮件为准来确定月份的5个步骤。

2026.10.13 · 阅读约10分钟
把freee会计的未处理明细改成每月一次的核销班次:每月5日7:30、分3类、最多15条交给人处理的设计 AI活用

把freee会计的未处理明细改成每月一次的核销班次:每月5日7:30、分3类、最多15条交给人处理的设计

freee会计里有大约18条未处理明细,连续6次每周检查都原封不动地留着。这里整理一下每月5日早上7:30在家里的Mac上运行的核销班次的设计,以及“能确定的部分每月合并成1个任务、拿不准的明细逐条交给人、上限15条”的界线。

2026.10.12 · 阅读约11分钟
转到乐天移动,最高可获14,000积分 无需签约也能获得100积分的资费模拟 →
立即申请 →