Как извлечь текст в PDF, если кодировка и ToUnicode оба присутствуют в PDF? как отобразить это?

Здесь я использовал инструмент qpdf для распаковки данных и ниже вывод. если вы видите, что есть кодировка и ToUnicode оба присутствуют в PDF. я знаю, если есть только ToUnicode, так как сопоставить отдельный символ с Cmap file.but, если вы видите, что вывод потока контента следующий

Tf 0.999402 0 0 1 71.9995 759.561 Tm [()-2.11826()-1.14177()2.67786()-2.11826()8.55269()-5.44998()-4.70186()2.67786()-2.32338()2.67786()12.679()-3,75591()9,73429()]TJ

в перерыве есть некоторые данные garbag, которые не видны. так как связать данные с файлом Cmap?

и еще один вопрос заключается в том, что в /Encoding какие значения содержатся в разнице?

10 0 obj<< / BaseEncoding / WinAnsiEncoding / Различия [ 1 /g100 /g28 /g94 /g3 /g87 /g24 /g38 /g47 /g62 ] / Тип / Кодировка >>

даже я передаю одно за другим значения массива Difference в одну из функций FreeType, которая называется FT_Get_Name_Indek. эта функция возвращает значения как [ 100 28 94 3 87 24 38 47 62]

что это за ценности? как сопоставить эти значения?

здесь pdf

запустить следующий cmd

qpdf --stream-data = распаковать input.pdf output.text

output.text

такой же вывод я получаю, если передаю данные потока содержимого в zlib. пожалуйста, проверьте файл output.txt по ссылке

2 ответа

Решение

Во-первых общий вопрос

Как извлечь текст в PDF, если кодировка и ToUnicode оба присутствуют в PDF? как отобразить это?

[...] если вы видите, что кодировка и ToUnicode присутствуют в pdf. я знаю, если только ToUnicode там, так как сопоставить отдельный символ с файлом Cmap.

В таком случае, т. Е. Когда у вас есть достаточно полная и правильная карта ToUnicode и кодировка для шрифта, вы можете игнорировать кодировку и использовать только карту ToUnicode.

Это следует из спецификации PDF, которая в разделе 9.10.2 "Отображение кодов символов в значения Unicode" гласит, что методы для сопоставления кода символов со значением Unicode с наивысшим приоритетом

Если словарь шрифтов содержит ToUnicode CMap (см. 9.10.3, "ToUnicode CMaps"), используйте этот CMap для преобразования кода символа в Unicode.

Таким образом, если вы (как вы говорите) уже знаете, как извлечь текст, если есть только карта ToUnicode, вы можете использовать тот же алгоритм без изменений. И как следствие, если это не сработает, рассматриваемая карта ToUnicode недостаточно полная или неправильная, или ваши знания о том, как извлечь текст с использованием только карты ToUnicode, на самом деле неполны.

Во-вторых, образец документа

Вы написали

[()-2.11826()-1.14177()2.67786()-2.11826()8.55269()-5.44998()-4.70186()2.67786()-2.32338()2.67786()12.679()-3.75591()9.73429()]TJ

в перерыве есть некоторые данные garbag, которые не видны. так как связать данные с файлом Cmap?

В скобках указаны значения, идентифицирующие ваши глифы, поэтому они не являются мусором.

Таким образом, вот значения байтов из скобок:

[(
    01
)-2.11826(
    02
)-1.14177(
    03
)2.67786(
    01
)-2.11826(
    04
)8.55269(
    05
)-5.44998(
    06
)-4.70186(
    07
)2.67786(
    04
)-2.32338(
    07
)2.67786(
    08
)12.679(
    09
)-3.75591(
    02
)9.73429(
    04
)]TJ

Использование карты ToUnicode соответствующего шрифта

/CIDInit /ProcSet findresource begin
12 dict begin
begincmap
/CMapType 2 def
1 begincodespacerange
<00><ff>
endcodespacerange
9 beginbfrange
<01><01><0054>
<02><02><0045>
<03><03><0053>
<04><04><0020>
<05><05><0050>
<06><06><0044>
<07><07><0046>
<08><08><0049>
<09><09><004c>
endbfrange
endcmap
CMapName currentdict /CMap defineresource pop
end end 

значения байтов в скобках отображаются на:

    01    0054    "T"
    02    0045    "E"
    03    0053    "S"
    01    0054    "T"
    04    0020    " "
    05    0050    "P"
    06    0044    "D"
    07    0046    "F"
    04    0020    " "
    07    0046    "F"
    08    0049    "I"
    09    004c    "L"
    02    0045    "E"
    04    0020    " "

Таким образом,

"TEST PDF FILE "

который соответствует отрендеренному файлу просто отлично:

Скриншот

В-третьих кодировка

и еще один вопрос заключается в том, что в /Encoding какие значения содержатся в разнице?

10 0 obj << / BaseEncoding / WinAnsiEncoding / Различия [ 1 /g100 /g28 /g94 /g3 /g87 /g24 /g38 /g47 /g62 ] / Тип / Кодировка >>

Согласно спецификации PDF,

Значение записи Различия должно быть массивом кодов символов и имен символов, организованных следующим образом:

код 1 имя 1,1 имя 1,2

код 2 имя 2,1 имя 2,2

...

код n имя n,1 имя n, 2

Каждый код должен быть первым индексом в последовательности кодов символов, подлежащих изменению. Имя первого символа после кода становится именем, соответствующим этому коду. Последующие имена заменяют последовательные индексы кода, пока следующий код не появится в массиве или массив не закончится. Эти последовательности могут быть указаны в любом порядке, но не должны перекрываться.

Таким образом, запись кодирования в вашем случае говорит, что кодировка в основном представляет собой WinAnsiEncoding с той разницей, что коды 1, ..., 9 вместо этого представляют глифы с именами /g100, /g28, /g94, /g3, /g87, /g24 /g38, /g47 и / g62 соответственно.

Поскольку эти имена глифов не являются стандартными именами глифов, спецификация PDF не считает эту кодировку полезной для извлечения текста, поскольку она описывает только метод для простого шрифта.

он имеет кодировку, в которой массив Differences включает только имена символов, взятые из стандартного набора символов латинского алфавита Adobe, и набор именованных символов шрифтом Symbol (см. Приложение D)

Имена "/gXX" в вашем образце явно не входят в их число.

Стоит заметить, что в большинстве случаев карта представляет собой коды символов (предназначенные как закодированные байты строки) для карты CID , где CID (идентификатор символа) в большинстве типов шрифтов соответствует индексу / идентификатору глифа. Исключением являются шрифты Type2, которые имеют отдельные концепции CID и GID (Glyph ID), предоставляя /CIDToGIDMapконвертировать между ними. В приведенных выше случаях карта не имеет ничего общего с декодированием Unicode- представления строки. Чтобы декодировать представление Unicode, вам определенно следует использовать /ToUnicodeкогда доступно, как указано bt @mkl. Если он недоступен, вы попадаете в тот случай, когда у вас либо есть предопределенная кодировка (необязательно с /Differencemap) или CMap , или вы a в случае, когда программа шрифтов предоставляет неявную кодировку, как в шрифтах Type1 . Об этом также говорится в очень хорошем ответе @mkl . /Encodingможет соответствовать карте для преобразования между кодами символов и кодовыми точками Unicode, когда это либо предопределенная кодировка (например, MacRomanEncoding, MacExpertEncoding или WinAnsiEncoding , но я также видел использование, возможно, несовместимого Identity-H , которое является предопределенным именем CMap , а не предопределенная кодировка) или предположительно искаженным шрифтом. В связи с этим в справочнике / стандарте PDF часто возникает путаница в отношении того, что является законным, а что нет, поэтому библиотека, декодирующая закодированные строки в PDF, всегда должна быть как можно более снисходительной. Также ссылка / стандарт PDF не очень ясны в объяснении различия между кодами символов., CID, GID и представления Unicode .

Другие вопросы по тегам