CGPDFScannerPopString возвращает странный результат

Наконец-то у меня появился какой-то pdf-сканер. Он без проблем считывает функции обратного вызова, но когда я пытаюсь записать в NSLog результат из CGPDFScannerPopString, я получаю такой результат:

ˆ ˛˝     #    ˜˜˜      #˜'  ˜˜˜      "˜   '˜˜      " '   ˜˜

Ни одной строки здесь не найти...

Есть идеи, что это может быть? Это моя функция обратного вызова:

static void op_Tj (CGPDFScannerRef s, void *info)
{
    CGPDFStringRef string;

    if (!CGPDFScannerPopString(s, &string))
        return;

    NSLog(@"string: %@", (__bridge NSString *)CGPDFStringCopyTextString(string));
}

Спасибо уже!

Изменить: Пример PDF


person Ron    schedule 21.12.2012    source источник


Ответы (1)


Вы должны знать, что CGPDFStringRef не является строкой ASCII или чем-то подобным. См. http://developer.apple.com/library/mac/documentation/graphicsimaging/Reference/CGPDFString/Reference/reference.html --- это «серия байтов — целочисленные значения без знака в диапазоне от 0 до 255», которые должны интерпретироваться в соответствии с последними Ссылка в формате PDF.

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

CGPDFStringCopyTextString пытается соответствующим образом интерпретировать эти байты, но не обязательно иметь разумную интерпретацию как обычную строку.

РЕДАКТИРОВАНИЕ Проверка образца PDF, предоставленного Роном, показала, что в случае этого образца действительно кодировка шрифта в объекте 3 0 (которая преобладает на большинстве страниц документа) не является стандартной кодировкой, а вместо этого :

<</Type/Encoding
  /Differences[0/.notdef/C/O/V/E/R/space/slash/H/L/F/underscore/W/B/five/eight/four
                /zero/two/six/D/one/period/three/Z/I/N/G/U/S/T/colon/seven/A/M/P/Y
                /plus/nine/X/hyphen/i/s/p/a/t/c/h/n/f/o/K/greater/equal/l/m/y/J/Q
                /parenleft/parenright/comma/dollar/ampersand/d/r/v/b/e/u/w/k/g/x/bar
                /quotesingle/asterisk/q/question/percent]
>>

Глядя на верхнюю часть первой страницы документа

COVER / HLF_CWEB_58408485 / 58408485 / 26DEC12 10.30.22Z


BRIEFING INCLUDES FOLLOWING FLIGHTS:

26DEC12 OR0337 EHAM0630 MUVR1710 PHOYE VSM+2/8 179

NEXT FLIGHTS OF AIRCRAFT:

26DEC12 OR0338 MUVR1830 MMUN1940 PHOYE VSM+2/8 213
26DEC12 OR0338 MMUN2105 EHAM0655 PHOYE GPT+2/7 263
27DEC12 OR0365 EHAM0900 TNCB1930 PHOYE BAH+1/8 272
27DEC12 OR0366 TNCB2030 TNCC2110 PHOYE BAH+1/8 250
27DEC12 OR0366 TNCC2250 EHAM0835 PHOYE ASD+1/8 199 

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

При этом объект шрифта включает в себя как запись /Encoding, так и запись /ToUnicode. Таким образом, если бы методу CGPDFStringCopyTextString была дана ссылка на шрифт здесь и он действительно попытался бы правильно перевести эти байты в соответствующий текст. То, что он не достигает ничего приличного, похоже, указывает на то, что у него просто нет информации, для какого шрифта интерпретировать байты --- я не предполагаю, что он не пытается...

Поэтому для точного извлечения текста вы должны интерпретировать байты в CGPDFStringRef самостоятельно, используя информацию о шрифте в потоке содержимого. Если вы не хотите делать это с нуля, вас может заинтересовать PDFKitten, платформа для извлечения данные из PDF-файлов в iOS. Хотя он еще не совершенен (некоторые структуры шрифтов могут сбивать его с толку), это хорошая отправная точка.

person mkl    schedule 22.12.2012
comment
Ага, теперь это имеет немного больше смысла... Я искал некоторые и прочитал, что в документе должна быть запись ToUnicode. Есть, но, может быть, вы можете помочь мне, как использовать это? - person Ron; 22.12.2012
comment
Неважно, FastPDFKit даже не может извлечь текст. Не думаю, что я смог бы сделать это тогда... - person Ron; 22.12.2012
comment
PDF-файл, который я пытаюсь прочитать, представляет собой информацию о частной компании. Я посмотрю, смогу ли я отфильтровать некоторые вещи и опубликовать это ... Может быть, вы сможете взглянуть на это. - person Ron; 26.12.2012
comment
Я добавил пример в свой пост... Может быть, вы можете взглянуть на него, чтобы узнать, сможет ли кто-нибудь из вас, ребята, извлечь из него данные. - person Ron; 26.12.2012
comment
@Ron Я просмотрел предоставленный вами PDF-файл и соответствующим образом отредактировал свой ответ. В двух словах: преобладающая кодировка, используемая в нем, действительно очень индивидуальна, но она хорошо описана в объекте шрифта. Таким образом, метод CGPDFStringCopyTextString кажется менее чем подходящим для работы по извлечению текста. Вы можете посмотреть PDFKitten. - person mkl; 26.12.2012
comment
Прошу прощения, но нет. Мы не поженимся. Пробовал и читал все, что мог. Использовал фреймворки FastPDFKit, PDFKitten, PSPDF и некоторые мелкие вещи, но ни один из них не может извлечь текст со страниц. Пытался найти способ интерпретировать байты CGPDFStringRef, но нигде не нашел ответа. Так что, если вы можете это сделать, будьте моим гостем, но в противном случае я перестану рвать на себе волосы... вздох - person Ron; 27.12.2012
comment
@ Рон, так что никакого брака ... * g Должен признать, что я не проверял, может ли PdfKitten обработать файл. Все, что у меня было под рукой, это мой ПК с Windows и Java на нем, и программа извлечения текста Java, использующая iText, могла правильно извлечь текст без дальнейших церемоний. Проблема с PDFKitten может быть такой же, как и в этом вопросе SO . Возможно, однострочное исправление, примененное к PDFKitten в ходе этого вопроса, в конце концов было недостаточным... - person mkl; 27.12.2012
comment
@mkl пример в PDFKitten отображает только страницы PDF с помощью функции CGContextDrawPDFPage(), не касаясь ни одного из методов stringWithPDFString() в фреймворке. Если я хочу протестировать эти методы, как мне инициализировать эти объекты шрифта и использовать их реализации этой функции? - person CodeBrew; 21.05.2018
comment
@CodePlumber, пожалуйста, сделайте это самостоятельным вопросом. Я не занимался обработкой pdf под iOS уже несколько лет, так что больше ничем помочь не могу. - person mkl; 21.05.2018