PDFBox:来自PdfTextStripper的不可见文本(不是剪辑路径或颜色问题)

时间:2018-04-26 13:56:06

标签: java pdf pdfbox

文件示例:test

此处在表格第2行中," 3500 RENT" PdfTextStripper返回了2个文本标记(" 1"," 1"),但实际上在原始PDF中不可见。 我知道它可能是剪辑路径(如帖子here中)或颜色问题(如帖子here)。

然而,在这种情况下,它看起来像是通过其他方式隐藏了......剪辑路径不重叠,并且这些标记的颜色是黑色的。

还有什么呢?

1 个答案:

答案 0 :(得分:2)

这是一个颜色问题,' 1以白色打印。

使情况有点特别的是,使用的 ColorSpace 不是您现成的 DeviceRGB DeviceGray ,而是分色色彩空间和分色色彩空间中的色彩值始终被视为减色。因此,0.0的色调值表示用给定的着色剂可以实现的最浅的颜色,1.0是最暗的。此约定与 DeviceCMYK 颜色组件相同,但与 DeviceGray DeviceRGB 相反。

(参见ISO 32000-1第8.6.6.4节"分隔色彩空间")

内部视图

您的内容流开头如下:

/Cs8 cs 1 scn

Cs8 分离色彩空间:

/Cs8 [/Separation /Black [/ICCBased 17 0 R] 18 0 R] 

ICCBased 备用空间,其中<​​strong> DeviceRGB 为备用空间

17 0 obj
<<
/Length 2597
/Alternate /DeviceRGB
/Filter /FlateDecode
/N 3
>>
stream
[...ICC profile...]
endstream
endobj 

并通过样本将色调转换为备用色彩空间

18 0 obj
<<
/Length 779
/BitsPerSample 8
/Decode [0 1 0 1 0 1]
/Domain [0 1]
/Encode [0 254]
/Filter /FlateDecode
/FunctionType 0
/Range [0 1 0 1 0 1]
/Size [255]
>>
stream
[...255 samples from (255,255,255) to (35,31,32)...]
endstream
endobj 

您的内容流继续绘制标题和第一行开头的操作,然后

/TT2 1 Tf
0 scn
13.559 0 TD
6.8438 Tc
<00140014>Tj
1 scn 

0 scn将颜色设置为最亮的 Cs8 BLACK分色,在屏幕上将样本映射到(255,255,255)非常白,6.8438 Tc设置为大字符间距(导致两个&#39; 1之间的差距),<00140014>Tj将两个&1;&#39;和1 scn切换回最暗的 Cs8 BLLC分色在屏幕上按样本映射到(35,31,32),这将是一种非常深的浅灰色。

使用PDFBox

在评论中你说

  

当我在processTextPosition(TextPosition text)中对其进行调试时,gs.getNonStrokingColor()对于那些&#34; 1&#34;具有相同的值。代币和其他代币一样,实际上是黑色的

要使用PDFBox识别这一点,您必须告诉其PDFTextStripper寻找通用颜色空间选择和颜色选择运算符 cs scn 并扩展processTextPosition就像这个概念验证一样:

PDFTextStripper stripper = new PDFTextStripper() {
    @Override
    protected void processTextPosition(TextPosition text) {
        PDGraphicsState gs = getGraphicsState();
        PDColor color = gs.getNonStrokingColor();
        float[] currentComponents = color.getComponents();
        if (!Arrays.equals(components, currentComponents)) {
            System.out.print(Arrays.toString(currentComponents));
            components = currentComponents;
        }
        System.out.print(text.getUnicode());
        super.processTextPosition(text);
    }

    float[] components;
};

stripper.addOperator(new SetNonStrokingColorSpace());
stripper.addOperator(new SetNonStrokingColorN());

ExtractText test testTestSeparation

有了这些设置,你就得到了

[1.0]TenantLeaseStart ... 3,500.00RENT[0.0]11[1.0]16,133.33

如您所见,颜色组件以1.0开头,对于两个&#39;它是0.0,此后它再次变为1.0,直到下一个看不见的&#39; 1。