PDF对企业应用来说是刚需。
 
然而PDF显然不是一种对机器友好的格式,它只是对人类友好,就是说方便阅读打印,但让程序去提取其中的内容却很难。下面简单说说为什么是这样。
 
以前还读书的时候(20+年前了),一个同学跟我展示了PDF文档,他说这种格式不是普通的文本,它是图片,所以比较大。其实他说的并不完全正确,pdf中可以包含图片,也可以包含文字,且其中的文字跟传统的位图还真是不一样。那么PDF中的内容究竟是什么?
以增值税普通发票的电子档为例,相信大家手头都有,对,就这个:

上面的文字究竟是图还是文本?上面的印章是不是位图?

判断是不是位图很简单,就是用一个PDF阅读器打开,Adobe的或者福昕的都行,选择“Select”工具,看看上面的文字能否选中。你很快就发现,不光上面的楷体字、宋体字能选中,印章里的文字居然也能选中,并且能复制下来,你把复制下来的文本贴到记事本里,这就是普通的文本。

这是不是就说明PDF里的文字就是我们常规理解的文本呢?其实没那么简单,PDF的一个特性就是不管处于怎样的环境,PDF都能显示出完整的、一致的内容。这意味着这张发票放到一个完全不支持中文的系统中,它也能显示出上面的汉字,并且效果完全一直,当然也包含了不同的字体,楷体,宋体,都没问题,这就比较厉害了。
 
其实原理也不难,那就是把字体信息直接嵌入到PDF文件内部。也许你觉得不对,我一个中文宋体的字库就有超过10MB了,而我的PDF才几百K,怎么可能?——要做到这点也不难,只嵌入部分即可。用福昕的PDF阅读器打开这张电子档发票,菜单"File" - "Properties" - "Fonts",你会看到这样的信息:

KaiTi,很明显是楷体,SimSun这是宋体,STSong则是华文宋体,而且编码格式都有,上面的UniGB-UCS2-H是什么编码格式我不太清楚,可能是Unicode,UC应该是Unicode的简写。
 
这里顺便提个事情,就是字体的侵权问题,如果在自己生成的PDF中嵌入字体厂商未授权的字体,很可能会造成侵权!而如果你做了一个网页,网页上指定了用未授权的字体(如微软雅黑)显示一段文字,这样则不会造成侵权,原因在于你并没有在网页上嵌入微软雅黑,你只是告诉用户的浏览器,这段文字建议用微软雅黑显示,用户看到的微软雅黑字体还是用户自己电脑提供的,跟你没有关系,所以不会造成侵权,侵不侵权在于你是否二次“发布”了这个字体。其实要避免侵权也不难,对我们来说,用可免费商用的字体即可,目前还不少,如Google的Noto系列,华为鸿蒙Sans、阿里巴巴普惠体以及小米最近发布的MiSans,这些都是可以免费商用的。
 
字体,本质上来说是矢量图,当然过去也曾经有过点阵字体,但现在基本算是淘汰了,矢量图一个特点是无论你放大多少倍,它都不会失真或出现马赛克,所以一定要我说PDF中保存的文字到底是图还是字,那我就说,那是矢量图,这肯定是正确的,因为如今的字体本质上就是矢量图嘛。
 
而PDF中除了字之外,别的你能看到的很多的元素,其实也都是矢量图,如表格的线条,印章的圆圈这些,要证明也很简单,使劲放大,看看有没有失真出现马赛克或者模糊即可。
 
当然了PDF中还可能有位图,判断方法还是上面提到的,放大来看。
 
PDF的文字的组织形式与我们txt,word或是html都不太一样,举个例子,你打开PDF看到的两个挨在一块的文字,如“力量”,这两个字你觉得它是一个连在一起的词,其实未必,很可能它是通过两个不同的坐标来指定的,从文档结构上来说,你读取“力”字,不意味着它的下一个元素就一定是“量”字,尽管视觉上是这样。这就给我们提取PDF的文本信息带来很大的挑战,我们很难通过直接分析PDF的文档结构提取其中的文字,比较稳妥的方法还是得通过显示的结果来获取内容,是的,就是OCR的路线。但即便要使用OCR的路线,也是问题很多,下面这个例子就反映了一个很典型的问题:

阅读器显示的“μ”和“接”中间的这个符号在我看来很像一个竖线,即“|”,而实际上它却是英文字母“l”,用阅读器复制到记事本中可以证实这点,确实是字母“l”,只不过Windows10种的字母“l”显示得跟数值“1”一模一样,真是令人无语,如果使用OCR的方式,字母“l”很可能就被识别为竖线,或者字母“I”(大写的i),还有就是“μ”这种希腊字母,在OCR中直接被识别成了英文字母“u”,这就很明显有问题了,对于需要精确导入信息的企业应用来说,这显然是不行的。
 
另一个问题也在上图中有体现,就是对空格的理解,福昕阅读器复制出来的内容中包含了一个空格,而别的没有,究竟有没有这个空格,这个很难说,就像我在黑板上写了两个字,间隔远点就算有空格,间隔近了就没有空格,可这个远和近如何界定,这个就比较难办了。
 
我曾经做过一套PDF内容提取的框架,能通过一些配置信息尝试从PDF中提取文本内容,但遇到了很大的麻烦,就如上面提到的那样,两个看上去连贯的文字,读出来的先后顺序是没法保证的,绕来绕去还绕回了OCR的路子,但OCR也是问题不少,总得来说,对于需要精准信息提取的应用来说,真是最好别用PDF了。——但话虽然这么说,客户可不一定能理解,做和不做也不完全由得技术说了算,现实如此也……

最新文章

  1. Android中Activity的启动模式
  2. mysql 按时间段统计(年,季度,月,天,时)
  3. CentOS出错You don't have permission to access on this server
  4. Nginx 获取真实 IP 方案
  5. 团队作业—第二周—SRS
  6. 在ASP.NET开发中容易忽略的2个小问题
  7. 聊聊 if else 那些事
  8. ArcGIS Server 服务迁移、恢复
  9. java 面试每日一题6
  10. PHP使用libevent实现高性能httpServer
  11. DP之矩阵连乘问题
  12. linux yum install resource - epel
  13. Eclipse不能自动编译 java文件的解决方案
  14. C#中堆和栈的区别分析(有待更新总结2)
  15. Eclipse集成Tomcat教程
  16. Xftp连接阿里云Linux,向Linux上传文件,Windows和Linux文件传输
  17. window下如何使用文本编辑器(如记事本)创建、编译和执行Java程序
  18. mvc后台可以使前台弹出警告框的几种方法
  19. Centos7 安装redis集群哨兵模式
  20. pandas.Series

热门文章

  1. EBS 抓trace 文件
  2. 【编程思想】【设计模式】【创建模式creational】建造者模式builder
  3. 【Matlab】求矩阵行和/列和
  4. 使用RabbitMQ搭建MQTT服务
  5. docker容器使用loki收集日志
  6. array_filter()用法
  7. [BUUCTF]REVERSE——[FlareOn6]Overlong
  8. bootstrap.css 进度条没有动画效果
  9. CF415A Mashmokh and Lights 题解
  10. Centos7使用Docker启动elasticsearch服务秒退