Парсинг документа в формате PDF

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

Поток содержания PDF, что его имя предлагает — последовательный поток данных такой как 'BT 12 /F71 Tf (draw this text) Tj . . . ' где операторы PDF и их дескрипторы смешаны с фактическим содержанием PDF. Проверка потока содержания требует, чтобы Вы получили доступ к нему последовательно.

Эта глава показывает, как исследовать структуру документа в формате PDF и проанализировать содержание документа в формате PDF.

Проверка структуры документа в формате PDF

Файлы PDF могут содержать многократные страницы изображений и текста. Можно использовать Кварц для доступа к метаданным в документе и уровнях страницы, а также объектах на странице PDF. Этот раздел обеспечивает очень краткое введение в метаданные, к которым можно получить доступ.

Объект документа в формате PDF (CGPDFDocument) содержит всю информацию, касающуюся документа в формате PDF, включая его каталог и содержание. Записи в каталоге рекурсивно описывают содержание документа в формате PDF. Можно получить доступ к содержанию каталога документа в формате PDF путем вызывания функции CGPDFDocumentGetCatalog.

Объект страницы PDF (CGPDFPage) представляет страницу в документе в формате PDF и содержит информацию, касающуюся определенной страницы, включая словарь страницы и содержание страницы. Можно получить словарь страницы путем вызывания функции CGPDFPageGetDictionary.

Рисунок 14-1 показывает некоторые метаданные, описывающие два изображения — текст и изображение петуха — которые составляют файл PDF, выведенный на экран на рисунке 13-2.

  Метаданные рисунка 14-1 для двух изображений в файле PDF
Metadata for two images in a PDF file

Можно получить намного более полезную информацию путем доступа к метаданным PDF. Элементы на рисунке 14-1 являются просто выборкой. Например, можно проверить, чтобы видеть, имеет ли PDF изображения миниатюр (показанный на рисунке 14-2) использование кода, показанного в Перечислении 14-1.

Перечисление 14-1  , Получающее режим просмотра миниатюр PDF

CGPDFDictionaryRef d;
CGPDFStreamRef stream; // represents a sequence of bytes
d = CGPDFPageGetDictionary(page);
// check for thumbnail data
if (CGPDFDictionaryGetStream (d, “Thumb”, &stream)){
    // get the data if it exists
    data = CGPDFStreamCopyData (stream, &format);

Кварц выполняет все дешифрование и декодирование потока данных для Вас.

  Изображения миниатюр рисунка 14-2
Thumbnail images

Кварц обеспечивает много функций, которые можно использовать для получения отдельных значений для элементов в метаданных PDF. Вы используете функцию CGPDFObjectGetValue, передача a CGPDFObjectRef, тип объекта PDF (kCGPDFObjectTypeBoolean, kCGPDFObjectTypeInteger, и т.д), и хранение для значения. По возврату хранение заполнено значением.

Существуют многочисленные другие функции, которые можно использовать для пересечения иерархии файла PDF для доступа к различным узлам и их дочерним элементам. Например, CGPDFArray функции (CGPDFArrayGetBoolean, CGPDFArrayGetDictionary, CGPDFArrayGetInteger, и т.д), позволяют Вам массивы доступа значений для получения значений определенных типов. Можно узнать больше о том, как использовать эти функции путем чтения спецификации PDF.

Парсинг содержания PDF

Поток содержания PDF содержит операторов, показывающих части потока содержания PDF, который может представлять интерес для Вашего приложения. Оператор или отмечает единственную точку или последовательность. Оператор указан как тег, имеющий список свойств или объект, связанный с ним. Тег указывает то, что представляет последовательность точки или содержания. Список свойств является словарем, содержащим пары ключ/значение, указанные автором контента PDF. При парсинге потока содержания PDF приложение ищет любые маркеры интереса, проверяет тег, список свойств или объект, связанный с маркером, и затем выполняет дальнейшую обработку, это является надлежащим. Консультируйтесь со Ссылкой PDF для полного списка операторов PDF.

Вы используете объект CGPDFScanner (CGPDFScannerRef тип данных) для парсинга потока содержания PDF. Объект CGPDFScanner вызывает обратные вызовы для любого оператора в потоке, для которого Вы зарегистрировали обратный вызов.

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

  1. Запишите Обратные вызовы для Операторов. Необходимо записать обратные вызовы только для операторов, которых Вы хотите обработать.

  2. Создайте и установленный таблица оператора.

  3. Откройте документ в формате PDF.

  4. Отсканируйте поток содержания для каждой страницы.

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

Следующие разделы показывают, как проанализировать поток содержания для нахождения операторов отмеченного содержания (см. Таблицу 14-1). Отмеченные операторы содержания представляют только некоторых операторов PDF, используемых в содержании PDF. Когда Вы пишете свой собственный код, Вы искали бы операторов PDF, подходящих для Вашего приложения.

  Отмеченные операторы содержания таблицы 14-1 представляют некоторых операторов PDF, которых можно проанализировать

Оператор

Описание

MP

Отмеченная точка, которой связали тег с ним.

DP

Отмеченная точка, имеющая тег и список свойств или объект, связанный с ним.

BMC

Сигнализирует запуск последовательности отмеченного содержания (начните отмеченное содержание), и соединяется с EMC маркер, сигнализирующий конец последовательности. Связали тег с ним.

BDC

Сигнализирует, что запуск отмеченного содержания упорядочивает, и соединяется с EMC маркер, сигнализирующий конец последовательности. Имеет тег и список свойств или объект, связанный с ним.

EMC

Сигнализирует конец последовательности отмеченного содержания (конец отмеченное содержание), который начинается с a BMC или a BDC маркер. Этому оператору не связывали тег с ним.

Запишите обратные вызовы для операторов

Когда Кварц вызывает Ваш обратный вызов для PDF операторы, это передает объект CGPDFScanner и указатель на любую информацию, необходимую Вашему обратному вызову. Как правило, Ваш обратный вызов получает любые элементы, связанные с оператором. Например, обратный вызов для MP оператор, которого это показано в Перечислении 14-2, вызывает функцию CGPDFScannerPopName получать символьную строку связалось с оператором от штабеля. Если код в перечислении успешно получает имя от штабеля сканера, это распечатывает имя.

Кварц имеет выбор CGPDFScannerPop функции для получения объектов, булевых значений, имен, чисел, строк, массивов, словарей и потоков. Каждая функция возвращает булево значение, чтобы указать, был ли элемент получен успешно.

Перечисление 14-2  обратный вызов для оператора MP

static void
op_MP (CGPDFScannerRef s, void *info)
{
    const char *name;
 
    if (!CGPDFScannerPopName(s, &name))
        return;
 
    printf("MP /%s\n", name);
}

Создайте и установленный таблица оператора

A CGPDFOperatorTable функции обратного вызова оператора PDF объектно-ориентированных памятей, которые Вы пишете. Функция CGPDFOperatorTableCreate составляет таблицу оператора, как показано в Перечислении 14-3. После того, как Вы составите таблицу оператора, Вы вызываете функцию CGPDFOperatorTableSetCallback для каждого обратного вызова Вы хотите добавить к таблице. Вы передаете таблицу, строка, указывающая оператора PDF и указатель на функцию обратного вызова, которую Вы пишете для обработки того оператора. Можно назвать обратные вызовы вообще, Вы хотели бы. Просто удостоверьтесь, что имя обратного вызова Вы передаете функции CGPDFOperatorTableSetCallback не пишется c орфографическими ошибками.

Код в Перечислении 14-3 устанавливает обратный вызов для каждого из операторов отмеченного содержания, перечисленных в Таблице 14-1. Ваше приложение установило бы обратные вызовы только для тех операторов интереса. Строки оператора PDF определяются в Ссылке PDF от Adobe.

Перечисление 14-3  , Устанавливающее обратные вызовы для таблицы оператора

CGPDFOperatorTableRef myTable;
 
myTable = CGPDFOperatorTableCreate();
 
CGPDFOperatorTableSetCallback (myTable, "MP", &op_MP);
CGPDFOperatorTableSetCallback (myTable, "DP", &op_DP);
CGPDFOperatorTableSetCallback (myTable, "BMC", &op_BMC);
CGPDFOperatorTableSetCallback (myTable, "BDC", &op_BDC);
CGPDFOperatorTableSetCallback (myTable, "EMC", &op_EMC);

Откройте документ в формате PDF

Прежде чем можно будет отсканировать содержание документа в формате PDF, необходимо открыть его. Перечисление 14-4 показывает фрагмент кода, создающий объект CGPDFDocument из URL, предоставленного коду. Обратите внимание на то, что перечисление является фрагментом кода, так, чтобы не были объявлены все переменные. Подробное объяснение каждой пронумерованной строки кода появляется после перечисления.

Перечисление 14-4  , Открывающее документ в формате PDF от URL

CGPDFDocumentRef myDocument;
myDocument = CGPDFDocumentCreateWithURL(url);// 1
if (myDocument == NULL) {// 2
        error ("can't open `%s'.", filename);
        CFRelease (url);
        return EXIT_FAILURE;
}
CFRelease (url);
if (CGPDFDocumentIsEncrypted (myDocument)) {// 3
    if (!CGPDFDocumentUnlockWithPassword (myDocument, "")) {
        printf ("Enter password: ");
        fflush (stdout);
        password = fgets(buffer, sizeof(buffer), stdin);
        if (password != NULL) {
            buffer[strlen(buffer) - 1] = '\0';
            if (!CGPDFDocumentUnlockWithPassword (myDocument, password))
                error("invalid password.");
        }
    }
}
if (!CGPDFDocumentIsUnlocked (myDocument)) {// 4
        error("can't unlock `%s'.", filename);
        CGPDFDocumentRelease(myDocument);
        return EXIT_FAILURE;
    }
}
 if (CGPDFDocumentGetNumberOfPages(myDocument) == 0) {// 5
        CGPDFDocumentRelease(myDocument);
        return EXIT_FAILURE;
}

Вот то, что делает код:

  1. Создает объект CGPDFDocument из URL, предоставленного коду.

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

  3. Проверки, шифруется ли документ. Если документ шифруется, код пытается открыться, использует пустой пароль. Если это перестало работать, код просит у пользователя пароль и пытается разблокировать документ с паролем.

  4. Проверки, разблокирован ли документ. Если это не, выходы кода.

  5. Проверки для проверки документа имеют по крайней мере одну страницу. Иначе, выходы кода.

Отсканируйте поток содержания для каждой страницы

Фрагмент кода в Перечислении 14-5 сканирует каждую страницу в документе. Когда сканер встречается с одним из операторов PDF, для которых Вы зарегистрировали обратный вызов, Кварц вызывает Ваш обратный вызов. Подробное объяснение каждой пронумерованной строки кода следует за перечислением.

Перечисление 14-5  , Сканирующее каждую страницу документа

int k;
CGPDFPageRef myPage;
CGPDFScannerRef myScanner;
CGPDFContentStreamRef myContentStream;
 
numOfPages = CGPDFDocumentGetNumberOfPages (myDocument);// 1
for (k = 0; k < numOfPages; k++) {
    myPage = CGPDFDocumentGetPage (myDocument, k + 1 );// 2
    myContentStream = CGPDFContentStreamCreateWithPage (myPage);// 3
    myScanner = CGPDFScannerCreate (myContentStream, myTable, NULL);// 4
    CGPDFScannerScan (myScanner);// 5
    CGPDFPageRelease (myPage);// 6
    CGPDFScannerRelease (myScanner);// 7
    CGPDFContentStreamRelease (myContentStream);// 8
 }
 CGPDFOperatorTableRelease(myTable);// 9

Вот то, что делает код:

  1. Получает число страниц в документе, который Вы ранее открыли. Посмотрите Открытый Документ в формате PDF.

  2. Получает страницу для сканирования. Номера страниц запускаются в 1.

  3. Создает поток содержания для страницы.

  4. Создает сканер для потока содержания. Необходимо передать поток содержания и таблицу оператора, которую Вы ранее составили и установили с обратными вызовами. Посмотрите Создают и Установленный Таблица Оператора. Можно также передать любые данные, в которых нужны обратные вызовы.

  5. Анализирует поток содержания, связанный со сканером. Кварц вызывает Ваш обратный вызов каждый раз, когда это встречается с одним из операторов, для которых Вы обеспечили обратный вызов.

  6. Выпускает страницу.

  7. Выпускает сканер.

  8. Выпускает поток содержания.

  9. Выпускает таблицу оператора после сканирования всех страниц в PDF.