PdfBox:PDF/A-1A 至 PDF/A-3A
PdfBox: PDF/A-1A to PDF/A-3A
我有以下问题:
我想将 PDF/A-1A 文档转换为 PDF/A-3A。
原始文档由 Arobat Reader Pro 验证,因此我可以认为它是 PDF/A-1A 符合。
我尝试使用以下代码转换 PDF 元数据:
private PDDocumentCatalog makeA3compliant(PDDocument doc) throws IOException, TransformerException {
PDDocumentCatalog cat = doc.getDocumentCatalog();
PDMetadata metadata = new PDMetadata(doc);
cat.setMetadata(metadata);
XMPMetadata xmp = new XMPMetadata();
XMPSchemaPDFAId pdfaid = new XMPSchemaPDFAId(xmp);
xmp.addSchema(pdfaid);
XMPSchemaDublinCore dc = xmp.addDublinCoreSchema();
String creator = "TestCr";
String producer = "testPr";
dc.addCreator(creator);
dc.setAbout("");
XMPSchemaBasic xsb = xmp.addBasicSchema();
xsb.setAbout("");
xsb.setCreatorTool(creator);
xsb.setCreateDate(GregorianCalendar.getInstance());
PDDocumentInformation pdi = new PDDocumentInformation();
pdi.setProducer(producer);
pdi.setAuthor(creator);
doc.setDocumentInformation(pdi);
XMPSchemaPDF pdf = xmp.addPDFSchema();
pdf.setProducer(producer);
pdf.setAbout("");
PDMarkInfo markinfo = new PDMarkInfo();
markinfo.setMarked(true);
doc.getDocumentCatalog().setMarkInfo(markinfo);
pdfaid.setPart(3);
pdfaid.setConformance("A");
pdfaid.setAbout("");
metadata.importXMPMetadata(xmp);
return cat;
}
如果我尝试再次使用 Acrobat 验证新文件,我收到验证错误:
CIDset in subset font is incomplete (font contains glyphs that are not listed)
如果我尝试使用此在线验证器 (http://www.pdf-tools.com/pdf/validate-pdfa-online.aspx) 验证文件,它是有效的 PDF/A-3A...
我是不是漏了什么?
没有人能帮忙吗?
编辑:这是 PDF file
好的 - 我想我从马蹄莲 and/or Adobe 技术 的角度回答了你的问题(再一次,我隶属于马蹄莲及其 pdfToolbox 技术也在 Acrobat 内部使用).
根据我的研究和我咨询过的人,您的示例 PDF 文档包含一个 CID 字符集不完整的字体。为什么 pdfToolbox 或 Acrobat 说它是有效的 PDF/A-1a 文件而不是有效的 PDF/A-3a 文件?有趣的问题:
1) 不完整 CID 集的规则 在 PDF/A-1a 和 PDF/A-3a 之间更改了 。他们在 PDF/A-3a.
中 更严格
2) 但是在 PDF/A-1a 中,CID 集总是必须存在,而在 PDF/A-3a 中,您可以拥有一个有效的、合规的文件,而无需这样的 CID 集。
因此,您的 PDF 文件包含一个 CID 集(这使其对 PDF/A-1a 和 A-3a 有效)但是虽然该 CID 集适用于 A-1a 但 不 包含符合 A-3a 标准的所有字符。
为了至少测试这个理论的一部分,我通过 pdfToolbox 处理了你的文件,其中包含一个名为 "Remove CIDset if incomplete" 的修正。该更正(顾名思义)会从文件中删除 CID 集,但不会更改任何其他内容。执行此操作后,您的文件将验证为有效的 A-3a 文件。
这就留下了一个问题,为什么 pdftools 网站声称这是一个有效的 PDF/A-3a 文件;根据与我交谈过的人的说法,该文件的预检结果是正确的,该文件应该有错误。所以也许这就是您需要与 pdftools 人员一起解决的问题(他们可能与 callas 一起找出最终正确的人)。
如果您想进一步讨论这个问题,请随时给我发送个人消息 - 关于工具本身的更多讨论可能会成为这个 public 站点的题外话。
这使我们在 CIDset 问题上完全 PDF/A-3 合规:
private void removeCidSet(PDDocumentCatalog catalog) {
COSName cidSet = COSName.getPDFName("CIDSet");
// iterate over all pdf pages
for (Object object : catalog.getAllPages()) {
if (object instanceof PDPage) {
PDPage page = (PDPage) object;
Map<String, PDFont> fonts = page.getResources().getFonts();
Iterator<String> iterator = fonts.keySet().iterator();
// iterate over all fonts
while (iterator.hasNext()) {
PDFont pdFont = fonts.get(iterator.next());
if (pdFont instanceof PDType0Font) {
PDType0Font typedFont = (PDType0Font) pdFont;
if (typedFont.getDescendantFont() instanceof PDCIDFontType2Font) {
PDCIDFontType2Font f = (PDCIDFontType2Font) typedFont.getDescendantFont();
PDFontDescriptor fontDescriptor = f.getFontDescriptor();
if (fontDescriptor instanceof PDFontDescriptorDictionary) {
PDFontDescriptorDictionary fontDict = (PDFontDescriptorDictionary) fontDescriptor;
fontDict.getCOSDictionary().removeItem(cidSet);
}
}
}
}
}
}
}
我有以下问题: 我想将 PDF/A-1A 文档转换为 PDF/A-3A。 原始文档由 Arobat Reader Pro 验证,因此我可以认为它是 PDF/A-1A 符合。
我尝试使用以下代码转换 PDF 元数据:
private PDDocumentCatalog makeA3compliant(PDDocument doc) throws IOException, TransformerException {
PDDocumentCatalog cat = doc.getDocumentCatalog();
PDMetadata metadata = new PDMetadata(doc);
cat.setMetadata(metadata);
XMPMetadata xmp = new XMPMetadata();
XMPSchemaPDFAId pdfaid = new XMPSchemaPDFAId(xmp);
xmp.addSchema(pdfaid);
XMPSchemaDublinCore dc = xmp.addDublinCoreSchema();
String creator = "TestCr";
String producer = "testPr";
dc.addCreator(creator);
dc.setAbout("");
XMPSchemaBasic xsb = xmp.addBasicSchema();
xsb.setAbout("");
xsb.setCreatorTool(creator);
xsb.setCreateDate(GregorianCalendar.getInstance());
PDDocumentInformation pdi = new PDDocumentInformation();
pdi.setProducer(producer);
pdi.setAuthor(creator);
doc.setDocumentInformation(pdi);
XMPSchemaPDF pdf = xmp.addPDFSchema();
pdf.setProducer(producer);
pdf.setAbout("");
PDMarkInfo markinfo = new PDMarkInfo();
markinfo.setMarked(true);
doc.getDocumentCatalog().setMarkInfo(markinfo);
pdfaid.setPart(3);
pdfaid.setConformance("A");
pdfaid.setAbout("");
metadata.importXMPMetadata(xmp);
return cat;
}
如果我尝试再次使用 Acrobat 验证新文件,我收到验证错误:
CIDset in subset font is incomplete (font contains glyphs that are not listed)
如果我尝试使用此在线验证器 (http://www.pdf-tools.com/pdf/validate-pdfa-online.aspx) 验证文件,它是有效的 PDF/A-3A...
我是不是漏了什么?
没有人能帮忙吗?
编辑:这是 PDF file
好的 - 我想我从马蹄莲 and/or Adobe 技术 的角度回答了你的问题(再一次,我隶属于马蹄莲及其 pdfToolbox 技术也在 Acrobat 内部使用).
根据我的研究和我咨询过的人,您的示例 PDF 文档包含一个 CID 字符集不完整的字体。为什么 pdfToolbox 或 Acrobat 说它是有效的 PDF/A-1a 文件而不是有效的 PDF/A-3a 文件?有趣的问题:
1) 不完整 CID 集的规则 在 PDF/A-1a 和 PDF/A-3a 之间更改了 。他们在 PDF/A-3a.
中 更严格2) 但是在 PDF/A-1a 中,CID 集总是必须存在,而在 PDF/A-3a 中,您可以拥有一个有效的、合规的文件,而无需这样的 CID 集。
因此,您的 PDF 文件包含一个 CID 集(这使其对 PDF/A-1a 和 A-3a 有效)但是虽然该 CID 集适用于 A-1a 但 不 包含符合 A-3a 标准的所有字符。
为了至少测试这个理论的一部分,我通过 pdfToolbox 处理了你的文件,其中包含一个名为 "Remove CIDset if incomplete" 的修正。该更正(顾名思义)会从文件中删除 CID 集,但不会更改任何其他内容。执行此操作后,您的文件将验证为有效的 A-3a 文件。
这就留下了一个问题,为什么 pdftools 网站声称这是一个有效的 PDF/A-3a 文件;根据与我交谈过的人的说法,该文件的预检结果是正确的,该文件应该有错误。所以也许这就是您需要与 pdftools 人员一起解决的问题(他们可能与 callas 一起找出最终正确的人)。
如果您想进一步讨论这个问题,请随时给我发送个人消息 - 关于工具本身的更多讨论可能会成为这个 public 站点的题外话。
这使我们在 CIDset 问题上完全 PDF/A-3 合规:
private void removeCidSet(PDDocumentCatalog catalog) {
COSName cidSet = COSName.getPDFName("CIDSet");
// iterate over all pdf pages
for (Object object : catalog.getAllPages()) {
if (object instanceof PDPage) {
PDPage page = (PDPage) object;
Map<String, PDFont> fonts = page.getResources().getFonts();
Iterator<String> iterator = fonts.keySet().iterator();
// iterate over all fonts
while (iterator.hasNext()) {
PDFont pdFont = fonts.get(iterator.next());
if (pdFont instanceof PDType0Font) {
PDType0Font typedFont = (PDType0Font) pdFont;
if (typedFont.getDescendantFont() instanceof PDCIDFontType2Font) {
PDCIDFontType2Font f = (PDCIDFontType2Font) typedFont.getDescendantFont();
PDFontDescriptor fontDescriptor = f.getFontDescriptor();
if (fontDescriptor instanceof PDFontDescriptorDictionary) {
PDFontDescriptorDictionary fontDict = (PDFontDescriptorDictionary) fontDescriptor;
fontDict.getCOSDictionary().removeItem(cidSet);
}
}
}
}
}
}
}