ファイルの内容を読み取らずに、PDF に 3D 要素 (ユニバーサル 3D オブジェクトが埋め込まれている) が含まれているかどうかを検出する方法はありますか? この情報はメタデータから取得できますか?
3 に答える
私の知る限り、ドキュメントに 3D 要素が含まれている可能性があるという事実について、メタデータに情報を入力する必要はありません。
ただし、一部の U3D 書き込みソフトウェアは、それに関するヒントをXMLメタデータに入れる場合があります。
長い答え
調べるには、PDF ページ ツリーを少なくとも部分的に解析する必要があります。
技術的には、3D 要素は注釈として実装されます。注釈を発見するには、次の解析パスに従う必要があります。
予告編を読む。
/Rootドキュメントの間接オブジェクトのオブジェクト番号を示します。相互参照表を読んでください。ドキュメント内の各間接オブジェクトのバイト オフセットがわかります。
/Root間接オブジェクトに移動します。/Pagesそのキーを読み取ります。これにより、ドキュメントのページ ツリーのルートを表す間接オブジェクトがわかります。を表す間接オブジェクトに移動します
/Pages。/Kidsそのキーを読み取ります。これにより、文書ページを表すその他の間接オブジェクトがわかります。ドキュメント ページを表す各間接オブジェクトに移動します。
/Annots(オプションで存在する)キーを探します。存在する場合、(おそらくあらゆる種類の) 注釈を表す他の間接オブジェクトを指します。
これで、PDF に注釈が含まれているかどうかがわかりました。そうでない場合は、ここで停止します。はいの場合は、注釈の種類を決定します。
最後のステップで見つかったすべての間接オブジェクトに移動します。彼らはのです
/Type /Annot。それらが追加であるかどうかを確認してください/Subtype /3D。はいの場合、3D 注釈が見つかりました。(注意、これはまだ U3D ではない可能性があります!)最後に見つかった間接オブジェクト (キーを持つオブジェクト) 内で、
/Subtype /3Dの追加のキーを探します/3DD。実際の 3D ストリームを含むこの間接オブジェクトを指します。3D ストリームを含む間接オブジェクトに移動します。そのオブジェクト ディクショナリには、再び のキー:値のペアが含まれている必要があります
/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
出力で、ファイルに存在するすべての注釈を一覧表示する「annotations」要素を確認し、サブタイプが「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>
これは、上記の @kurt-pfeifle の回答のステップ 1 に対応します。VeraPDF は U3D ストリームを識別するために必要なレベルまでドリルダウンしないため、そのレベルの詳細が必要な場合には @kurt-pfeifle の回答をお勧めします。