Извлечение текста из PDF с помощью iTextSharp не работает для некоторых PDF

Я использую следующий код для извлечения текста из первой страницы файлов PDF с помощью iTextSharp:

public static string ExtractTextFromPDFFirstPage(string fileName)
{
    string text = null;
    using (var pdfReader = new PdfReader(fileName))
    {
        ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();

        text = PdfTextExtractor.GetTextFromPage(pdfReader,1,strategy);

        text = Encoding.UTF8.GetString(Encoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(text)));

    }
    return text;
}

Это работает достаточно хорошо для многих PDF, но не для некоторых других.

Рабочий PDF: http://data.hexagosoft.com/LFBO.pdf

Не работает PDF: http://data.hexagosoft.com/LFBP.pdf

Эти два PDF-файла кажутся очень похожими, но один работает, а другой нет. Я предполагаю, что тот факт, что их теги производителя не совпадают, является подсказкой. Еще одна подсказка заключается в том, что эта функция работает для любой другой страницы PDF без диаграммы.

Я также пытался с помощью ghostscipt, но безуспешно.

Строка Encoding также кажется бесполезной.

Как я могу извлечь текст первой страницы нерабочего PDF-файла, используя iTextSharp?

Спасибо


person Sebastien    schedule 28.01.2016    source источник
comment
Обе ссылки возвращают ошибку 503...   -  person Jan Slabon    schedule 28.01.2016
comment
Извините, кажется, что filebin.ca ненадежен ... Я разместил файлы в другом месте и отредактировал свое сообщение.   -  person Sebastien    schedule 28.01.2016
comment
Не имеет прямого отношения к вашей проблеме, но полностью удалите строку text = Encoding.UTF8.GetString..., потому что она не делает того, что вы думаете. Подробнее см. здесь.   -  person Chris Haas    schedule 28.01.2016


Ответы (2)


В обоих документах используются шрифты с неофициальными именами глифов в их массиве Encoding/Differences, и оба не используют карту ToUnicode. Именование глифа кажется несколько прямым: число, следующее за префиксом MT, является кодом ASCII используемого глифа.

Первый документ работает, потому что сопоставление вообще не меняется, и iText будет использовать кодировку по умолчанию (я думаю):

/Differences[65/MT65/MT66/MT67 71/MT71/MT72/MT73 76/MT76 78/MT78 83/MT83]

Другой документ действительно меняет отображение:

/Differences [2 /MT76 /MT105 /MT103 /MT104 /MT116 /MT110 /MT32 /MT97 /MT100 /MT115 /MT58 ]

Это означает: код символа 2 должен сопоставляться с глифом с именем MT76, который является неофициальным/частным именем глифа, которого iText не знает, поэтому у него нет дополнительной информации, кроме кода символа 2, и он будет использовать этот код для окончательного результата (я догадка).

Без реализации логики для имен глифов с префиксом MT невозможно получить правильный текст из этого документа. Во всяком случае, нигде не определено, что имя глифа, начинающееся с MT, за которым следует целое число, может быть сопоставлено со значением ASCII... Это просто случайно или реализовано инструментом дизайнера/создателя шрифтов, откуда бы он ни исходил.

person Jan Slabon    schedule 29.01.2016
comment
Спасибо за Ваш ответ. Означает ли это, что нет никакого способа извлечь текст из этого файла? И почему извлечение текста из других страниц того же документа работает? - person Sebastien; 29.01.2016
comment
Только явным образом следуя недокументированной и неуказанной логике: MT{ASCII}. Первый документ работает, потому что, например. 65 сопоставляется с MT65, 66 — с MT66... ​​код символа совпадает с сопоставленным значением ASCII. Что не относится ко 2-му документу: 2 к МТ76, 3 к МТ105,... - person Jan Slabon; 29.01.2016
comment
Итак, есть ли способ вручную создать сопоставление? Как я могу это сделать ? Я предполагаю, что все другие файлы, из которых мне нужно будет извлечь текст, будут иметь такое же пользовательское сопоставление. - person Sebastien; 04.02.2016
comment
Должен признаться, что я совсем не знаком с iText. Поэтому я не могу ответить, если и как можно было бы использовать собственные имена глифов, извините. - person Jan Slabon; 04.02.2016

Второй PDF-файл (LFBP.pdf) содержит неправильное сопоставление глифов с текстом, то есть вы видите правильные глифы, но текстовое представление по какой-то причине не было правильно закодировано во время создания этого PDF-файла. Если у вас много таких файлов, рабочий подход может быть таким:

  • обнаруживать неработающие страницы при извлечении текста путем поиска какой-либо фразы, которая должна появляться на каждой странице, например, «сервис»
  • обрабатывать эти страницы отдельно, используя OCR с такими инструментами, как Tesseract с .NET Wraper
person Eugene    schedule 02.02.2016
comment
Я попробовал этот LFBP.pdf с утилитой ByteScout PDF Multitool с (режим OCR в Repair Broken Fonts + выбран французский язык), и он работает нормально для не повернутого текста, но повернутый текст плохо работает с OCR. . Примечание. Я связан с ByteScout. - person Eugene; 03.02.2016