Обнаружение, содержит ли файл PDF трехмерный элемент

Есть ли способ определить, содержит ли PDF-файл 3D-элемент (встроенный универсальный 3D-объект), не считывая содержимое файла? Можно ли получить эту информацию из метаданных?

3 ответа

Решение

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

Однако некоторые программы для написания U3D могут внести некоторую подсказку в метаданные XML.

Длинный ответ

Вам нужно будет хотя бы частично разобрать дерево страниц PDF, чтобы выяснить это.

Технически, 3D-элементы реализованы в виде аннотаций. Чтобы обнаружить какую-либо аннотацию, вам нужно пройти по этому пути:

  1. Прочитайте трейлер. Он говорит вам номер объекта /Root косвенный объект документа.

  2. Прочитайте таблицу перекрестных ссылок. Он сообщает вам смещения байтов для каждого косвенного объекта в документе.

  3. Перейти к /Root косвенное дополнение. Прочитайте его /Pages ключ. Это говорит вам, какой косвенный объект представляет корень дерева страниц документа.

  4. Перейти к косвенному объекту, который представляет /Pages, Прочитайте его /Kids ключ. Это говорит вам, какие другие косвенные объекты представляют страницы документа.

  5. Перейти к каждому косвенному объекту, представляющему страницу документа. Ищите любую (опционально присутствует) /Annots ключ. Если он присутствует, он будет указывать на другие косвенные объекты, представляющие (возможно, всевозможные) аннотации.

Теперь вы узнали, содержит ли PDF аннотацию (и) или нет. Если нет, остановитесь здесь. Если да, перейдите к определению типа (типов) аннотаций:

  1. Перейти ко всем сторонним объектам, найденным в последнем шаге. Они из /Type /Annot, Посмотрите, если они дополнительно /Subtype /3D, Если да, вы нашли 3D-аннотацию. (Внимание, это может быть не U3D!)

  2. Внутри последнего найденного косвенного объекта (объектов) - объекта (ов) с /Subtype /3D ключ - ищите дополнительный ключ /3DD, Это указывает на этот косвенный объект, который содержит фактический трехмерный поток.

  3. Перейти к косвенному объекту, содержащему трехмерный поток. Его объектный словарь должен снова содержать пару ключ: значение /Type /3D, Посмотрите на его /Subtype ключ. Если это говорит /U3D Вы нашли то, что искали...

Короткий ответ

Возможно, вам повезет, и вы можете собрать немного висящих фруктов, используя старый добрый grep как это:

$> grep -a U3D cc-7-july09.pdf

  /Subtype /U3D
  /MS /U3D
  /U3DPath [ <135BB3D42FBD85F7C2E178> <056D9A891FB5FDCE8E> ]
  /MS /U3D
  /U3DPath [ <5FFAF35CE3CBD34FAE5360> <4DDFD6048FC6DA05> ]
  /MS /U3D
  /U3DPath [ <2E4E4FD7FEC771038BC5EA> <2A6579CC91BE0B> ]
  /MS /U3D
  /U3DPath [ <6F303AF9850721D5D1FC6C> <7D1B08BEAE4A5A9BEDBB> ]
  /MS /U3D
  /U3DPath [ <F270A04603F0DE08B8AA29> <EE5180016FFBD542> ]
  /MS /U3D
  /U3DPath [ <A1D5848F6841ADA9A3583C> <A3F8A5D45849D392EF> ]
  /MS /U3D
  /U3DPath [ <34B8650D178BBDFF61DC03> <2D8F4C7D3CD980F976> ]
  /MS /U3D
  /U3DPath [ <843CD0339FD1852CCA235B> <9719FB65A990897F> ]

Однако это не будет работать для всех документов 3D PDF, особенно если 3D-элементы являются частью потока объектов.

Для тех, у кого есть такая же проблема, как у нас, это подход, который мы придумали, используя "iText" (бесплатная версия все еще доступна).

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

        PdfReader reader = new PdfReader(contents);
        int pages = reader.getNumberOfPages();
        boolean pdf3D = false;
        for (int i = 1; i <= pages; i++) {
            PdfDictionary page = reader.getPageN(i);
            PdfArray array = page.getAsArray(PdfName.ANNOTS);
            if (array == null) {
                continue;
            }
            for (ListIterator<PdfObject> iter = array.listIterator(); iter.hasNext();) {
                PdfDictionary annot = (PdfDictionary) PdfReader.getPdfObject(iter.next());
                PdfObject pdfObject = annot.get(PdfName.SUBTYPE);
                if (pdfObject != null) {
                    if (PdfName._3D.equals(pdfObject) || PdfName.GOTO3DVIEW.equals(pdfObject)) {
                        pdf3D = true;
                        break;
                    }
                }
            }
            if (pdf3D) {
                // if we already any of 3D element, we can break the loop
                break;
            }
        }

В тех случаях, когда достаточно знать, содержит ли PDF какой- либо 3D-контент (включая, помимо прочего, универсальные 3D-объекты), вы также можете использовать программное обеспечение VeraPDF в режиме извлечения функций. Выполните следующие действия, чтобы получить список всех типов аннотаций (включая 3D-аннотации).

Сначала отредактируйте файл конфигурации VerapDF «features.xml», как описано здесь:

https://docs.verapdf.org/cli/config/#features.xml

Убедись, что <feature>ANNOTATION</feature>входит в enabledFeaturesэлемент.

Используя этот файл в качестве примера, запустите:

      verapdf --off --extract action_goto3dview.ar10.pdf > action_goto3dview.ar10.xml

В выходных данных проверьте элемент «аннотации», в котором перечислены все аннотации, присутствующие в файле, и найдите аннотации с подтипом «3D» (что указывает на аннотацию 3D):

      <annotation id="annotIndir186">
<subType>3D</subType>
<rectangle lly="129.348" llx="163.939" urx="437.813" ury="331.861"></rectangle>
<width>273.874</width>
<height>202.513</height>
<contents>3D Model</contents>
<annotationName>3D3</annotationName>
<resources>
    <xobject id="xobjIndir187"></xobject>
</resources>
<invisible>false</invisible>
<hidden>false</hidden>
<print>true</print>
<noZoom>false</noZoom>
<noRotate>false</noRotate>
<noView>false</noView>
<readOnly>true</readOnly>
<locked>false</locked>
<toggleNoView>false</toggleNoView>
<lockedContents>false</lockedContents>
</annotation>

Это соответствует шагу 1 в ответе @ kurt-pfeifle выше. Поскольку VeraPDF не выполняет детализацию до уровня, необходимого для идентификации потоков U3D, я бы предложил ответ @kurt-pfeifle для случаев, когда необходим такой уровень детализации.

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