PDFBox: невидимый текст из PdfTextStripper (не проблема пути или цвета) - PullRequest
0 голосов
/ 26 апреля 2018

Пример файла: тест

Здесь, во 2-й строке таблицы, после «3500 RENT» есть 2 текстовых токена («1», «1»), возвращаемых PdfTextStripper, но фактически не видимых в исходном PDF. Я знаю, что это может быть путь клипа (как в посте здесь ) или проблема цвета (как в посте здесь ).

Тем не менее, похоже, что в этом случае он скрыт каким-либо другим способом ... путь клипа не перекрывается, и цвет для этих токенов черный.

Что еще это может быть?

1 Ответ

0 голосов
/ 26 апреля 2018

Это проблема цвета, цифры 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 альтернативным пробелом, который в свою очередь имеет 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 ЧЕРНЫЙ цвет разделения, который отображается для образца на (255,255,255) на экране, который будет довольно белым, 6.8438 Tc устанавливает большой интервал между символами (в результате чего промежуток между двумя «1», <00140014>Tj рисует два «1», и 1 scn переключается обратно к самому темному цвету разделения Cs8 BLACK, отображаемому в образце на (35,31,32) на экране который будет очень темного сероватого цвета.

С PDFBox

В комментарии вы говорите

когда я отлаживаю в processTextPosition(TextPosition text), gs.getNonStrokingColor() имеет то же значение для этих "1" токенов, что и для других токенов, и на самом деле черный

Чтобы распознать это с помощью 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, для двух '1 это 0.0, и после этого он снова становится 1.0 до следующего запуска невидимых' 1.

...