Проблема извлечения текста PDFBox fi, fl на Android Studio

Я использую этот https://github.com/TomRoush/PdfBox-Android PDFBox на Библиотека Android Studio для извлечения текста из документа PDF. Вот что я делаю:

File pdf_file = new File(file_path);

чтобы создать файл, затем

PDDocument document = null;
document = PDDocument.load(pdf_file);

чтобы загрузить файл в объект PDDocument, а затем

PDFTextStripper pdfStripper = new PDFTextStripper();
pdfStripper.setStartPage(...);
pdfStripper.setEndPage(...);
String page_text = pdfStripper.getText(document);

чтобы получить текстовое содержимое страницы. Проблема в том, что когда есть, например, слово «фирма», оно отображается как «фирма». Это в основном ставит пробел после fi (и, я думаю, fls и другие лигатуры). Я попытался прочитать это Проблемы с извлечением текста OpenTypeFont с помощью pdfBox, но я не не пойму как исправить. Деталей решения нет.

Важно: как оказалось, в моем PDF-файле нет лигатур, таких как fi, но есть обычная fi, но после нее есть пробел. Решение непонятно.

PDF-файл: https://wetransfer.com/downloads/09e9036dda4a7062ccad357/232b19abcd8edc202


person Sleb Lagnej    schedule 05.05.2020    source источник
comment
Пожалуйста, поделитесь файлом. Интересно, происходит ли это с PDFBox для рабочего стола.   -  person Tilman Hausherr    schedule 06.05.2020
comment
@TilmanHausherr Здравствуйте, я обновил свой вопрос ссылкой для загрузки PDF-файла.   -  person Sleb Lagnej    schedule 06.05.2020
comment
У меня тоже была эта проблема однажды, и я решил ее, выполнив поиск fi AND fi (лигатура)   -  person Lonzak    schedule 06.05.2020
comment
@Lonzak Хм, как ты это исправил? Находишь лигатуру fi и убираешь после нее пробел?   -  person JingleBells    schedule 06.05.2020
comment
@JingleBells Смотрите мой опубликованный ответ ...   -  person Lonzak    schedule 06.05.2020
comment
Один из способов — найти fi или fl и удалить пробел, если он есть.   -  person Lonzak    schedule 08.05.2020
comment
@Lonzak Хорошая идея, но меня немного беспокоят слова, оканчивающиеся на fi и fl, или места, где после fi и fl должен быть пробел. Что интересно, так это то, что я создал свой собственный PDF-файл с fi и fl, и после них не было пробела, поэтому я предполагаю, что есть какая-то проблема с PDF-файлом (с Гарри Поттером, с проблемами fi и fl), которая вызывает ошибки пространства.   -  person Sleb Lagnej    schedule 08.05.2020
comment
@Lonzak Это единственное доступное в настоящее время исправление?   -  person JingleBells    schedule 09.05.2020
comment
@Anovalium: Что вы имеете в виду под в моем PDF-файле, у меня нет лигатур, таких как fi? В файле, на который вы ссылаетесь (Мальчик, который выжил), похоже, есть литургии в фирме. Когда я пытаюсь выбрать слово «фирма» в программе для чтения PDF-файлов, «фи» воспринимается как единое целое.   -  person Lii    schedule 11.05.2020
comment
@Lii Хм, когда я запускаю PDF-файл через программу чтения PDFBox Android Studio, он отображает его как твердый, а не твердый. Странный. В моем читателе PDF на ПК он отображается как единое целое. Я полагаю, что библиотека PDFBox что-то делает. В Android Studio я печатаю его с помощью Log.d(Debug, pdf_text);   -  person JingleBells    schedule 11.05.2020
comment
@Lii я Ановалиум кстати   -  person JingleBells    schedule 11.05.2020
comment
Я предполагаю, что проблема должна заключаться в том, что лигатуры во входном PDF-файле переводятся в соответствующие буквы-ПЛЮС-пространство.   -  person Lii    schedule 11.05.2020
comment
@Lii Вы знаете, как это исправить?   -  person JingleBells    schedule 11.05.2020


Ответы (2)


Проблема в том, что когда есть, например, слово «фирма», оно отображается как «фирма».

Причина проста: после "fi" есть пробел!

Это инструкция по рисованию текста, рисующая линию с первым вхождением слова «фирма» в файл примера:

 [( )360.3(Mr Dursley was the director of a “)250( )110.3(rm called Grunnings, )]TJ

Байт (147) с помощью кодировки шрифта сопоставляется с именем глифа fi и с помощью сопоставления шрифта ToUnicode с символом Unicode U+fb01. , латинская малая лигатура fi.

Таким образом, средства просмотра PDF отображают лигатурный глиф fi, а средства извлечения текста извлекают либо лигатурный символ Unicode fi, либо после расширения символы f и я.

После этой лигатуры начальная точка для рисования следующего глифа смещается влево на 250 единиц, затем рисуется пробел, затем следующая начальная точка перемещается влево на 110,3 единицы, а затем рисуется «rm».

Таким образом, вы не видите пробела между "fi" и "rm" в средствах просмотра (поскольку оставшиеся ходы противодействуют рисованию глифа пробела), но средства извлечения текста извлекают символ пробела (потому что он есть).

Вы можете проверить, что это не причуда PDFBox, например. Adobe Reader с функцией копирования и вставки извлекает эту текстовую строку как

Mr Dursley was the director of a fi rm called Grunnings,

Как и PDFBox, он расширяет лигатуру и извлекает символ пробела.

person mkl    schedule 11.05.2020
comment
Вы можете попробовать удалить все пробелы и позволить PDFBox вставлять пробелы там, где это необходимо, из-за расстояния, как показано в этом ответе. - person mkl; 11.05.2020
comment
Спасибо за ответ! Так что оказывается, что между fi и rm на самом деле есть пространство, и программы просмотра PDF работают с координатами и игнорируют пробел, но когда PDFBox извлекает текст, пространство на самом деле есть. Эта проблема связана с самим файлом PDF или это произойдет с другими файлами PDF? Предложение в приведенном выше комментарии хорошее, но я не уверен, что хочу удалить все пробелы и доверить PDFBox добавление туда, где он считает это необходимым. Решение, которое я нашел, состоит в том, чтобы просто искать fi и fl и затем удалять пробел. Насколько я знаю, в английском языке не так много слов, оканчивающихся на fi или fl. - person JingleBells; 11.05.2020
comment
В любом случае, я очень надеюсь, что проблема связана с самим файлом PDF и его системой координации. - person JingleBells; 11.05.2020
comment
Строго говоря, простое и правильное извлечение текста не является обязательным требованием для файлов PDF, так что это не проблема сама по себе. Но это усложнение действительно совершенно не нужно (насколько это касается стандарта PDF); поэтому, если у вас есть контракт с производителем PDF, в котором указанный производитель обещает сделать возможным извлечение текста с разумными усилиями, вы действительно можете попросить его изменить это. На самом деле это выглядит так, как будто производитель обращается с лигатурами как с диакритическими знаками, применяемыми к космическому глифу. - person mkl; 11.05.2020
comment
Кстати, вы резюмировали, что просмотрщики PDF работают с координатами и игнорируют пробел... Они не игнорируют пробел, они на самом деле рисуют это! Но из-за числовых параметров в инструкции, обсуждаемой в моем ответе, они рисуют пустой (полностью прозрачный) космический глиф поверх лигатуры, поэтому вы его не воспринимаете в финальном рендеринге. - person mkl; 11.05.2020
comment
Я не знаю производителя PDF, мое приложение вращается вокруг того, что пользователь может импортировать любую книгу в формате PDF, а PDFBox преобразует ее в текст и так далее. Спасибо за ответ и объяснение! И последнее, так что эта проблема с fi и fl лигатурой связана с самим файлом PDF, а это означает, что если я пойду и загружу PDF-файл какой-либо другой книги, проблемы может не быть? Я все равно удалю пробел после fi и fl на всякий случай, потому что, как я уже говорил, не думаю, что многие слова заканчиваются на fi или fl. - person JingleBells; 11.05.2020
comment
Эта конструкция ненужного добавления пробела, перекрывающего предыдущий символ, совершенно не нужна, поэтому в вашем следующем PDF-файле его, вероятно, не будет. Однако, если он из того же источника, он, вероятно, есть. - person mkl; 12.05.2020

Как упоминалось в комментарии, у меня была похожая проблема с лигатурами. Мне пришлось проверять файлы PDF на наличие определенных строк, и мне было интересно, почему для некоторых это не сработало. После анализа я обнаружил, что эти файлы содержат лигатуры, и поэтому я не мог найти «Текстовое поле», хотя визуально оно содержалось. Мое решение состояло в том, чтобы искать не только textfield, но и textfield - поэтому ищите две строки, одну с и одну без лигатуры.

Вы сказали, что хотите извлечь текст из файлов PDF. Поэтому я бы добавил этап постобработки.

  1. Извлеките текст, как вы делаете сейчас
  2. Искать все лигатуры, например. "фи" и "фи" и замените его на "фи".

У меня были документы без пробела после лигатуры - поэтому я бы рассмотрел оба случая. Также следует учитывать случаи окончания слов (например, buffi) (тогда может быть два пробела?).

Общее слово: Тема непростая, как вы уже исследовали. Этот шаг называется нормализацией NFKC. В pdfbox 2.X теперь это делается внутри (см. PDFBOX-2384), но в pdfbox 1.X TextNormalize.java был делает это.

Обновление:

Еще одна возможность, которую вы могли бы попробовать, — это изменить файл PDFTextStripper.java. Существует метод под названием normalizeWord(...). Он преобразует одинарную лигатуру «fi» в «f» и «i». Там можно было добавить

//line 1971...
//for PDFs where ligatures are followed by a space (e.g. "fi ve") 
if(word.substring(q+1,q+2).equals(" ")) {
  p = q + 2;
}
else {
  p = q + 1;
}

Но пробовал только с pdfbox 2.0.19 (а у вас вроде 1.8.X). Хорошо, что это применяется только тогда, когда лигатура была найдена. Однако, похоже, это не общее решение из-за проблем со словами, оканчивающимися на лигатуру. Но в вашем случае все должно быть в порядке, поскольку после каждой лигатуры постоянно появляется пробел.

person Lonzak    schedule 06.05.2020
comment
Вы уверены, что имеете в виду itext в последнем абзаце? - person mkl; 06.05.2020
comment
да, конечно, я имел в виду Pdfbox... спасибо, что заметили это - person Lonzak; 06.05.2020
comment
Хм, оказывается, у меня нет лигатур. Это текстовое поле, а не текстовое поле, поэтому метод замены не работает :\ По какой-то причине он ставит пробел после fi, а не fi - person Sleb Lagnej; 07.05.2020
comment
@Lonzak Учитывая сообщение выше, вы случайно не знаете способ это исправить? - person Sleb Lagnej; 07.05.2020
comment
@mkl Учитывая, что fi — это f, а i, а не fi, у меня нет лигатур в PDF, но после fi есть пробел. Вы случайно не знаете решения? - person Sleb Lagnej; 07.05.2020
comment
У меня еще не было времени проверить ваш файл, так как на этой неделе я в основном не в сети (кроме смартфона). Я постараюсь найти какую-нибудь возможность изучить это. - person mkl; 07.05.2020
comment
то же самое здесь, в настоящее время слишком занят. - person Lonzak; 07.05.2020
comment
Хорошо, ребята, пожалуйста, когда у вас есть время, помогите мне с этим, потому что я действительно понятия не имею, как решить эту проблему. - person Sleb Lagnej; 07.05.2020
comment
@Lonzak Ой, извините, я не видел обновления. Спасибо! Я попробую. - person JingleBells; 11.05.2020