1

我想连接 PDF/A 1b 文件。

我正在使用itext PdfACopy.getImportedPage,没有错误。Itext 的一致性检查很好。

我得到一个看起来不错的 PDF/A 1b 文件。

当我使用pdfbox检查我的 PDF/A 一致性时,我收到很多错误:

2.4.3 : Invalid Color space, DestOutputProfile is missing
2.4.3 : Invalid Color space, The operator "g" can't be used without Color Profile
2.4.3 : Invalid Color space, The operator "f" can't be used without Color Profile
2.4.1 : Invalid Color space, The operator "rg" can't be used with CMYK Profile
2.4.3 : Invalid Color space, DestOutputProfile is missing

注意:所有输入的 PDF 都是有效的 PDF/A 1b

这是我用来获取不符合 PDF/A 1b 的 PDF/A 的示例代码

Document document = new Document();
PdfACopy copy = new PdfACopy(document, new FileOutputStream(outFile), pdfAConformanceLevel);

document.open();

PdfReader reader;
int n;
for (int i = 0; i < args.length - 1; i++)
{
  reader = new PdfReader(args[i]);
  n = reader.getNumberOfPages();
  for (int page = 0; page < n;)
  {
    copy.addPage(copy.getImportedPage(reader, ++page));
  }

}

copy.createXmpMetadata();

document.close();

所以我很生气,决定解决它。

使用此示例从 PDF 转储 ICC 配置文件,我可以看到生成的 PDF/A 中确实没有包含 ICC 配置文件。

看完这个教程,我终于用里面的代码PdfWriter.setOutputIntents(final PdfReader reader, final boolean checkExistence)来获取输入PDF/A中的输出intent,并放回输出PDF/A中。

它有效...

我首先创建了一个公共方法

public static void copyOutputIntents(PdfReader reader, PdfACopy copy) throws IOException {


    PdfDictionary catalog = reader.getCatalog();

    PdfArray outs = catalog.getAsArray(PdfName.OUTPUTINTENTS);
    if (outs == null)
    {
        Logger.err("Reggie Watts gonna get you !!!");
    }
    else
    {
        if (outs.isEmpty())
        {
            Logger.err("Reggie Watts gonna get you !!!");
        }
        PdfDictionary out = outs.getAsDict(0);

        PRStream stream = (PRStream) PdfReader.getPdfObject(out.get(PdfName.DESTOUTPUTPROFILE));
        byte destProfile[] = null;
        if (stream != null)
        {
            destProfile = PdfReader.getStreamBytes(stream);
        }
        copy.setOutputIntents(getNameString(out, PdfName.OUTPUTCONDITIONIDENTIFIER), getNameString(out, PdfName.OUTPUTCONDITION), getNameString(out, PdfName.REGISTRYNAME), getNameString(out, PdfName.INFO), destProfile);

    }
}

还必须添加getNameString我只是批量复制的方法。

所以现在我的代码现在生成有效的 PDF/A :

Document document = new Document();
PdfACopy copy = new PdfACopy(document, new FileOutputStream(outFile), pdfAConformanceLevel);

document.open();

PdfReader reader;
int n;
for (int i = 0; i < args.length - 1; i++)
{
  reader = new PdfReader(args[i]);
  n = reader.getNumberOfPages();
  for (int page = 0; page < n;)
  {
    copy.addPage(copy.getImportedPage(reader, ++page));
  }
  // get last PDF's intent and put it into the output one
  Stamper.copyOutputIntents(reader, copy);
}

copy.createXmpMetadata();

document.close();

不应该PdfACopy.addPage保留添加页面的输出意图或以任何方式处理它吗?

我看不出拥有无法生成有效 PDF/A 文件的高级课程的意义。

我错过了什么吗?我疯了吗?

对不起,很长的帖子。

4

0 回答 0