首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用pdfbox从pdf文档中提取文本以避免字体dict中缺少ToUnicode CMap条目时,没有Unicode映射错误。

用pdfbox从pdf文档中提取文本以避免字体dict中缺少ToUnicode CMap条目时,没有Unicode映射错误。
EN

Stack Overflow用户
提问于 2021-01-08 03:25:48
回答 1查看 965关注 0票数 1

Acrobat "Content“显示字符正常,但当我复制和粘贴时,它们是invalid.but如果”复制与格式化“,它将是正常的.坏案例图像

比如第一个字母“重”,当我使用pdfbox提取字母时,会发出一些警告警报。

代码语言:javascript
运行
复制
一月 08, 2021 11:14:37 上午 org.apache.pdfbox.pdmodel.font.PDType0Font toUnicode
警告: No Unicode mapping for CID+18429 (18429) in font GVAQVQ+SimSun

PDFont.loadUnicodeCmap()因为在字体GVAQVQ+SimSun中没有ToUnicode CMap条目,所以PDType0Font.toUnicodeCMap是空的。因此,当调用PDFont.toUnicode()时,它返回null。

@mkl如果有办法提前解决这个problem.Thanks .

代码语言:javascript
运行
复制
PDType0Font/null, PostScript name: GVAQVQ+SimSun

   0 = {SmallMap$SmallMapEntry@2123} "COSName{BaseFont}" -> "COSName{GVAQVQ+SimSun}"
   1 = {SmallMap$SmallMapEntry@2124} "COSName{DescendantFonts}" -> "COSArray{[COSDictionary{COSName{BaseFont}:COSName{GVAQVQ+SimSun};COSName{CIDSystemInfo}:COSDictionary{COSName{Ordering}:COSString{Identity};COSName{Registry}:COSString{PDFXC30};COSName{Supplement}:COSInt{0};};COSName{DW}:COSInt{1000};COSName{FontDescriptor}:COSObject{COSDictionary{COSName{Ascent}:COSInt{859};COSName{AvgWidth}:COSInt{500};COSName{CapHeight}:COSInt{668};COSName{Descent}:COSInt{-141};COSName{Flags}:COSInt{32};COSName{FontBBox}:COSArray{COSInt{-8};COSInt{-145};1000;859;};COSName{FontFile2}:COSObject{COSDictionary{COSName{Length}:COSInt{175201};COSName{Filter}:COSArray{COSName{FlateDecode};};COSName{Length1}:COSInt{468544};}COSStream{-708342007}};COSName{FontName}:-120083354;COSName{ItalicAngle}:0;COSName{Leading}:COSInt{141};COSName{MaxWidth}:1000;COSName{MissingWidth}:500;COSName{StemH}:COSInt{70};COSName{StemV}:70;COSName{Type}:COSName{FontDescriptor};COSName{XHeight}:COSInt{438};}};COSName{Subtype}:COSName{CIDFontType2};COSName{Type}:COSNa
   2 = {SmallMap$SmallMapEntry@2125} "COSName{Encoding}" -> "COSName{Identity-H}"
   3 = {SmallMap$SmallMapEntry@2126} "COSName{Subtype}" -> "COSName{Type0}"
   4 = {SmallMap$SmallMapEntry@2127} "COSName{Type}" -> "COSName{Font}"

"COSName{FontDescriptor}" -> "COSObject{15, 0}"
key = {COSName@2168} "COSName{FontDescriptor}"
value = {COSObject@2169} "COSObject{15, 0}"
baseObject = {COSDictionary@2209} "COSDictionary{COSName{Ascent}:COSInt{859};COSName{AvgWidth}:COSInt{500};COSName{CapHeight}:COSInt{668};COSName{Descent}:COSInt{-141};COSName{Flags}:COSInt{32};COSName{FontBBox}:COSArray{COSInt{-8};COSInt{-145};COSInt{1000};859;};COSName{FontFile2}:COSObject{COSDictionary{COSName{Length}:COSInt{175201};COSName{Filter}:COSArray{COSName{FlateDecode};};COSName{Length1}:COSInt{468544};}COSStream{-708342007}};COSName{FontName}:COSName{GVAQVQ+SimSun};COSName{ItalicAngle}:COSInt{0};COSName{Leading}:COSInt{141};COSName{MaxWidth}:1000;COSName{MissingWidth}:500;COSName{StemH}:COSInt{70};COSName{StemV}:70;COSName{Type}:COSName{FontDescriptor};COSName{XHeight}:COSInt{438};}"
needToBeUpdated = false
items = {SmallMap@2211}  size = 16
0 = {SmallMap$SmallMapEntry@2214} "COSName{Ascent}" -> "COSInt{859}"
1 = {SmallMap$SmallMapEntry@2215} "COSName{AvgWidth}" -> "COSInt{500}"
2 = {SmallMap$SmallMapEntry@2216} "COSName{CapHeight}" -> "COSInt{668}"
3 = {SmallMap$SmallMapEntry@2217} "COSName{Descent}" -> "COSInt{-141}"
4 = {SmallMap$SmallMapEntry@2218} "COSName{Flags}" -> "COSInt{32}"
5 = {SmallMap$SmallMapEntry@2219} "COSName{FontBBox}" -> "COSArray{[COSInt{-8}, COSInt{-145}, COSInt{1000}, COSInt{859}]}"
6 = {SmallMap$SmallMapEntry@2220} "COSName{FontFile2}" -> "COSObject{12, 0}"
7 = {SmallMap$SmallMapEntry@2221} "COSName{FontName}" -> "COSName{GVAQVQ+SimSun}"
8 = {SmallMap$SmallMapEntry@2222} "COSName{ItalicAngle}" -> "COSInt{0}"
9 = {SmallMap$SmallMapEntry@2223} "COSName{Leading}" -> "COSInt{141}"
10 = {SmallMap$SmallMapEntry@2224} "COSName{MaxWidth}" -> "COSInt{1000}"
11 = {SmallMap$SmallMapEntry@2225} "COSName{MissingWidth}" -> "COSInt{500}"
12 = {SmallMap$SmallMapEntry@2226} "COSName{StemH}" -> "COSInt{70}"
13 = {SmallMap$SmallMapEntry@2227} "COSName{StemV}" -> "COSInt{70}"
14 = {SmallMap$SmallMapEntry@2228} "COSName{Type}" -> "COSName{FontDescriptor}"
15 = {SmallMap$SmallMapEntry@2229} "COSName{XHeight}" -> "COSInt{438}"
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-08 10:15:56

PDFBox文本提取根据规范的9.10.2节“将字符代码映射到Unicode值”中的算法工作。当试图将此算法应用于您的文件时,它无法提取用SimSun字体嵌入子集(F2)绘制的文本:

  • “如果字体字典包含一个ToUnicode CMap”-- F2没有ToUnicode CMap。
  • “如果字体是简单字体”- F2不是简单字体。
  • “如果字体是复合字体”- F2确实是一种复合字体,但是.
    • “它使用表118中列出的预定义CMaps之一(标识-H和标识-V除外)”-- F2使用标识-H
    • “或者其后代CIDFont使用AdobeGB1、Adobe-CNS1、Adobe 1或Adobe 1字符集合”-- F2使用PDFXC30 30-标识字符集合。

  • 如果这些方法无法生成Unicode值,则无法确定字符代码代表什么,在这种情况下,符合条件的读者可以选择他们选择的字符代码。

因此,在PDFBox中实现的文本提取不能提取该中文文本。

PDF规范中提供的文本提取过程中文本信息的另一个来源是用于结构元素或标记内容序列的ActualText条目。但是您的PDF也没有任何这样的ActualText条目。

因此,Acrobat复制和粘贴(它使用了前面提到的算法和ActualText分析的结合)无法提取该中文文本。

因此,Acrobat中的“复制与格式化”显然必须使用PDF规范提出的机制之外的一些信息。

检查嵌入的字体资源本身,可以看到它既不包含对Unicode的映射,也不包含任何标准名称。值得注意的是,字形数字不是连续编号,而是有空白。这些数字可能是从整个字体中保留下来的。

因此,Adobe Acrobat Pro在“复制和形成”您的中文文本时,似乎会执行下列任何一种选择:

  • 他们知道PDFXC30 30-标识字符集合的细节,无论是官方的PDFXC30还是逆向工程,并使用这些信息进行提取。
  • (如果这个假设是正确的,即符号号已经在整个字体中保留下来:)他们知道SimSun字体,并且有一个从Unicode映射到Unicode的字形来进行提取。
  • 它们获取SimSun字体的完整副本(无论是内部提供的还是由主机操作系统提供的),将其中的符号与嵌入式子集中的字体进行比较,并从用于文本提取的字体中派生到Unicode的映射。
  • 他们将OCR应用于嵌入式字体的单个字体,并从结果派生到Unicode的映射。

在搜索PDFXC30 30-标识字符集合时,可以看到有许多文本提取工具存在问题,例如在Aspose论坛上可以读到:

我们的团队已经调查了这个问题,我想和大家分享一下,您用来创建样例PDF文件的软件使用了PDFXC30字符集合。这个字符集合是不标准的,我们没有关于这个编码的任何信息。这使得目前无法进行正确的文本提取。

( https://forum.aspose.com/t/pdfextractor-encoding-issue/113923线程中的最新响应)

如果可以从可信任的源提供PDFXC30字符集合映射文件,则PDFBox开发可能会将它们包含到PDFBox中,以便为类似您的文件启用文本提取。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65623041

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档