是否有办法检测PDF文档中是否包含3D元素(嵌入的通用3D对象),而不需要读取文件内容?这些信息能否从元数据中获取?
是否有办法检测PDF文档中是否包含3D元素(嵌入的通用3D对象),而不需要读取文件内容?这些信息能否从元数据中获取?
$> 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
<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>