PDFBox 2.0:在 TextStripper 中获取颜色信息

Posted

技术标签:

【中文标题】PDFBox 2.0:在 TextStripper 中获取颜色信息【英文标题】:PDFBox 2.0: Get color information in TextStripper 【发布时间】:2018-06-28 12:07:29 【问题描述】:

我正在使用 PDFBox PDFTextStripper 进行文本提取。我还需要获取每个字符的颜色信息,最好是在 writeString 方法中。 我发现的是this PDFBox 1.8 的解决方案(实际上可以很容易地转换为 2.0 版本),而我还要寻找的是每个字符的背景颜色(因为在那个答案中只有字符颜色)。 我为 Fill 运算符添加了所有处理程序 - CloseFillNonZeroAndStrokePath、CloseFillEvenOddAndStrokePath FillNonZeroAndStrokePath、FillEvenOddAndStrokePath、LegacyFillNonZeroRule、FillNonZeroRule、FillEvenOddRule(如 this 主题中建议的那样),并且在这些运算符中获得 nonStrokingColor:

public final class FillEvenOddRule extends OperatorProcessor 
        @Override
        public void process(Operator operator, List<COSBase> operands) throws IOException 
            linePath.setWindingRule(GeneralPath.WIND_EVEN_ODD);
            deleteCharsInPath();
            linePath.reset();
            PDGraphicsState gs = getGraphicsState();    
            PDColor nonStrokingColor = gs.getNonStrokingColor();
            fillColor = nonStrokingColor.toRGB();
        

        @Override
        public String getName() 
            return "f*";
        
    

然后在 processTextPosition 我试图得到这个 fillColor 并将其映射到每个字符(假设内容流以连续方式工作 - 在 Fill 运算符完成,所有接下来的 processTextPosition 字符都应该有这个 fillColor。但这不是事实,所有字符都有错误的颜色。有file 我正在尝试要进行处理,每第二行都有蓝色填充,我想为该行中的每个字符获取蓝色,为白行中的每个字符获取白色。PDFBox 可以吗?

【问题讨论】:

【参考方案1】:

示例文档上下文中的问题

然后在processTextPosition 中,我尝试获取此fillColor 并将其映射到每个字符(假设内容流以连续方式工作-Fill 运算符完成后,所有接下来到processTextPosition 的字符都应该有这个@987654325 @. 然而这不是事实,所有字符都有错误的颜色。

正如您所发现的,您对手头的 PDF 的假设是错误的。本文档中的策略是先绘制所有背景材料,然后绘制所有文本。因此,您对本文档的处理方法应始终返回最后一点背景材料的颜色。

正如my comment 中提到的第二个问题中提到的那样,您必须收集与实际文本提取并行填充的所有矩形(或更一般地说:路径),并检查字体渲染颜色是否( )(取决于文本渲染模式,它也可能是 StrokingColor!)当前检查的文本与文本位置的当前顶部填充路径的一致。

在你想知道的评论中

这是否意味着这种方法适用于所有文档?

此方法是否适用于所有文档

对许多人来说是这样,但不是对所有人。

立即想到以下问题:

并非所有色彩空间都支持您使用的toRGB 方法。 (我刚刚查了一下,我很惊讶有多少 PDFBox 有实现。)

特别是在图案颜色的情况下,您必须深入研究图案及其在您的案例中的用法才能找到实际的背景颜色。

还有其他方法可以绘制背景表单,特别是:

该方法仅考虑填充路径,但如果您使用较大的图形状态线宽度值或拉伸变换矩阵,则描边线也可以绘制矩形形状。因此,对于这种情况,您还必须考虑描边路径。

背景可能是位图图像。在这种情况下,您必须分析图像以获取背景颜色

要考虑的另一种替代方法是阴影填充。这通常也会在背景中产生一系列颜色。

随后在字形上绘制而不是覆盖它的表单可能会显着改变前景和背景。那里例如是从背景中获取色调并从前景中获取饱和度的混合模式...

绘制背景或前景时激活的软蒙版也可能很重要。

...

【讨论】:

谢谢,这是否意味着这种方法适用于所有文档? @DmitryK “这是否意味着这种方法适用于所有文档?” - 对许多人来说确实如此,但并非对所有人都适用。有关详细信息,请参阅。我的答案的新部分“这种方法是否适用于所有文档”。

以上是关于PDFBox 2.0:在 TextStripper 中获取颜色信息的主要内容,如果未能解决你的问题,请参考以下文章

pdfBox 读取pdf文件

使用 maven-shade-plugin 构建的 pdfbox 程序的结果与正常的 NetBeans 运行不同

pdf转图片以及内容读取

pdf转图片以及内容读取

pdf转图片以及内容读取

用java读取多种文件格式的文件(pdf,pptx,ppt,doc,docx..)