Некоторые идентификаторы глифов отсутствуют при попытке извлечь идентификатор глифа из pdf - PullRequest
0 голосов
/ 03 июня 2018

Из-за неправильного отображения символа Деванагири на символ Юникода я использовал следующий код для извлечения идентификатора глифа и сформировал свою собственную карту для сопоставления идентификаторов с соответствующим символом Юникода.

public class ExtractCharacterCodes {
public static void testExtractFromSingNepChar() throws IOException {
    PDDocument document = PDDocument.load(new File("C:/PageSeparator/pattern3.pdf"));
    PDFTextStripper stripper = new PDFTextStripper() {
        @Override
        protected void writeString(String text, List<TextPosition> textPositions) throws IOException {
            for (TextPosition textPosition : textPositions) {
                writeString(String.format("%s%s", textPosition.getUnicode(), Arrays.toString(textPosition.getCharacterCodes())));
            }
        }
    };
    //stripper.setSortByPosition(true);
    String text = stripper.getText(document);

    System.out.printf("\n*\n* singNepChar.pdf\n*\n%s\n", text);
}

public static void main(String[] args) throws IOException {
    ExtractCharacterCodes.testExtractFromSingNepChar();
}

}

При подаче заявки на этот pdf непальский pdf

я получил следующее: स[1434]नु[1418] [3]त[1414]स्[7021]क[1399]र[1426]ी[1440]क[1399]ा[1438] [3]म[1424]खु्[6990]य[1425] [3]अ[1383]ा[4285]ा[1438]र[1426]ो[1451]प[1420]ी[1440] [3]'[39]ग[1401]ो[1451]रे[1426]'[39] [32] क[1399]ा[1438]ठ[1410]म[1424]ा[1438]ड[1411]ौं[7301]क[1399]ो[1451] [3]ग[1401]ौ[1452]र[1426]ी[1440]घ[1402]ा[1438]ट[1409]ब[1422]ा[1438]ट[1409] [3]प[1420]क्र[7059]ा[1438]उ[1387] [32] ज[1406]न[1418]क[1399]र[1426]ा[1438]ज[1406] [3]स[1434]ा[1438]प[1420]क[1399]ो[1451]ट[1409]ा[1438]त[1414]स्[1439]स्[7021]ब[1422]र[1426] [3]:[29] [3]क[1399]स्[1439]ि[1431]न[1418] [3]अ[1383]स्[1439]ध[1417]क[1399]ा[1438]र[1426]ी[1440] [32]|[124] [32]ज[1406]े[1447]ष्ठ[7399] [3] ८[1481],[44] [32]२[1475]०[1473]७[1480]५[1478] [32] и т. Д.

, как вы видите, у меня есть строка "सुन«будучи разделенным как स [1434], नु [1418].Я начал создавать свою собственную карту идентификатора глифа для символа, но в этом случае идентификатор глифа отсутствует.Это должно быть स [1434], न [1441], ु [1418].Как мне это получить?

1 Ответ

0 голосов
/ 04 июня 2018

Причина в том, что PDFTextStripper не просто организует объекты TextPosition, которые он извлекает из базового анализатора, в строки и добавляет подразумеваемые пробелы, но также выполняет некоторую дополнительную предварительную обработку на них перед пересылкой на writeString.В частности, он

  • подавляет дублирующиеся перекрывающиеся глифы: один из способов создать смелый эффект для бедняков - это рисовать глифы дважды с небольшим смещением, и эти дубликаты подавляются;и
  • объединяет TextPosition объекты, содержащие диакритический знак, с TextPosition, содержащим соответствующий базовый глиф, в TextPosition, представляющий объединенную кодовую точку Unicode.

Прежняя обработкашаг может быть отключен с помощью PDFTextStripper.setSuppressDuplicateOverlappingText(false), но последний не может.

Эффект, который вы наблюдаете, связан с последним шагом обработки.

Если вы хотите получить глифы без какой-либо предварительной обработки, т.е. без подавления дубликатов и диакритического слияния, а также без их организации в строки и добавления неявных пробелов, вы можете переопределить processTextPosition вместо writeString:

PDDocument document = PDDocument.load(resource);
PDFTextStripper stripper = new PDFTextStripper() {
    @Override
    protected void processTextPosition(TextPosition textPosition) {
        try {
            writeString(String.format("%s%s", textPosition.getUnicode(), Arrays.toString(textPosition.getCharacterCodes())));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
};

String text = stripper.getText(document);

( ExtractCharacterCodes test testExtractFromPattern3)

Результат для вашего примера документа теперь будет

स[1434]ु[1441]न[1418] [3]त[1414]स्[7021]क[1399]र[1426]ी[1440]क[1399]ा[1438] [3]...

Если вы все еще хотите, чтобы PDFTextStripper организовалГлифы в строки и добавление подразумеваемых пробелов, вы должны исправить этот класс (или свою собственную копию) и в конце его реализации processTextPosition отключить слияние диакритических знаков, заменив

// test if we overlap the previous entry.
// Note that we are making an assumption that we need to only look back
// one TextPosition to find what we are overlapping.
// This may not always be true. */
TextPosition previousTextPosition = textList.get(textList.size() - 1);
if (text.isDiacritic() && previousTextPosition.contains(text))
{
    previousTextPosition.mergeDiacritic(text);
}
// If the previous TextPosition was the diacritic, merge it into this
// one and remove it from the list.
else if (previousTextPosition.isDiacritic() && text.contains(previousTextPosition))
{
    text.mergeDiacritic(previousTextPosition);
    textList.remove(textList.size() - 1);
    textList.add(text);
}
else
{
    textList.add(text);
}

простым

textList.add(text);

Кстати, ваш тестовый файл выдает ошибку в определении PDFBox базового глифа для слияния диакритического знака с: "स [1434] ु [1441] न [1418] "предназначено для отображения в виде" सुन ", т. Е. Знак гласного u" ु "объединяется с буквой sa" स ", но PDFBox объединяет его с последующей буквой na" न "как "सनु".

Причина заключается в том, что оно определяет букву, с которой соединяется диакритический знак, по своему происхождению, которое здесь действительно находится в диапазоне последней буквы na "न", но в качестве символа гласногоОтрисованный до его происхождения (он рисуется в области с отрицательной x координатой), PDFBox определяет неправильную связь:

SA-U-NA

...