如何使用 Ghostscript 和 Ghostscript .NET 通过嵌入 IIC 配置文件生成正确的 PDF/A

How to generate proper PDF/A with embedding IIC profile using Ghostscript and Ghostscript .NET

当前情景:

我正在尝试 生成正确且一致的 PDF/A,基于普通的 PDF 文档,在花了几个小时调查之后,我们决定制作使用 Ghostscript 功能。这个业务要求是为我正在工作的一个更大的 C# 项目设置的,但首先我一方面开始使用 Ghostscript 命令 在 Windows 上下文上进行一些测试,并创建了一个隔离的 控制台应用程序,该应用程序在另一端使用 Ghostscript .NET,以测试此功能的可行性。

我们集中精力在PFD/A-1B格式上进行第一次测试,并利用VeraPDF PDF-Tools 检查生成文件的一致性。

以下测试是用几个不同的PDF文件完成的,其中一些是我们的项目应用程序实际生成的文件。为简单起见,以防万一有人想检查,我提供了一个简单的 PDF(只有几行文本),它已经以相同的方式使用和测试并重现了相同的行为。

Download PDF for testing

Ghostscript 命令测试

执行

使用 GhostScript v 9.52,我尝试了以下命令:

gswin32c.exe -dNOSAFER -dPDFA=1 -sColorConversionStrategy=RGB -sDEVICE=pdfwrite -dPDFACompatibilityPolicy=1 -dNOPAUSE -dBATCH -o result.pdf "C:\GS_PDFA\PDFA_def.ps" WriterPDF.pdf

*注意:即使我读到不推荐 -dNOSAFER 参数,但没有它我无法为 /invalidfileaccess[=129 生成 PDF =] 错误。我怀疑访问权限是原因,正如在整个 Whosebug (GhostScript: Error: /invalidfileaccess in --file--) 中搜索所发现的那样,但仍然没有找到适合我的解决方案。

也尝试了以下命令但同样的错误(在与 .ps 模板文件相同的文件中找到所需的 ICC 配置文件):

gswin32c.exe --permit-file-read=c:/GS_PDFA/srgb.icc -dPDFA=1 -sColorConversionStrategy=RGB -sDEVICE=pdfwrite -dPDFACompatibilityPolicy=1 -dNOPAUSE -dBATCH -o result2.pdf C:/GS_PDFA/PDFA_def_FULL.ps WriterPDF.pdf 

对于 PDFA 配置文件,我尝试提供在 /lib 上找到的默认 PDFA_def.ps 模板,在 Ghostscript 安装目录中。之后,尝试使用 PDFA_def.ps 模板文件,更新行:

/ICCProfile (C:/GS_PDFA/srgb.icc)

/OutputConditionIdentifier (sRGB)

结果和验证

结果:Download PDF generated by command line

VeraPDF 说:

PDF file is compilant with Validation Profile requirements

PDF 工具说:

The document does conform to the PDF/A-1b standard.

此外,当使用 Adob​​e Reader DC 打开时,一致性选项卡显示所选格式 (PFD/A-1B) 的所有详细信息,但 不显示 OutputIntent,甚至PDFA_def.ps template被设置为参数,并且sRGB ICC配置文件在模板文件中计算。 Adobe conformance status missed OutputIntend capture

Ghostscript .NET 控制台应用程序:

执行

我尝试根据 Ghostscript 测试期间使用的相同参数编写代码:

string outputFile = @"C:\temp\output.pdf";
string inputFile = @"C:\temp\WriterPDF.pdf";

GhostscriptPipedOutput gsPipedOutput = new GhostscriptPipedOutput();

// pipe handle format: %handle%hexvalue
string outputPipeHandle = "%handle%" + int.Parse(gsPipedOutput.ClientHandle).ToString("X2");

using (GhostscriptProcessor processor = new GhostscriptProcessor())
{
    List<string> switches = new List<string>();
    switches.Add("-empty");
    switches.Add("-dPDFA=1");
    switches.Add("-sColorConversionStrategy=RGB");
    switches.Add("-dPDFACompatibilityPolicy=1");
    switches.Add("-dBATCH");
    switches.Add("-dNOPAUSE");
    switches.Add("-sDEVICE=pdfwrite");
    switches.Add("-o" + outputPipeHandle);
    //switches.Add("c:/GS_PDFA/PDFA_def.ps");
    switches.Add(inputFile);

    try
    {
        processor.StartProcessing(switches.ToArray(), null);

        byte[] rawDocumentData = gsPipedOutput.Data;
        
        File.WriteAllBytes(outputFile, rawDocumentData);

    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);

        Console.ReadLine();
    }
    finally
    {
        gsPipedOutput.Dispose();
        gsPipedOutput = null;
    }
}

*注意:注意这次没有使用-dNOSAFER参数。 如果包含,结果相同,没有附加信息或详细错误如果注释行 (switches.Add("c:/GS_PDFA/PDFA_def.ps");) [=包含 110=],然后应用程序引发错误:

An error occured when call to 'gsapi_init_with_args' is made: -100

我试图为模板文件使用另一个位置来防止错误,但没有成功。还在顶部添加了代码行:switches.Add("-Ic:/GS_PDFA/"); 但同样的错误。

结果和验证

结果:Download PDF generated by GS .NET DLL

VeraPDF 说:

如果没有设置PDFA_def.ps模板文件,生成的文件不会通过验证检查。

PDF file is not compilant with Validation Profile requirements

PDF 工具说:

The document does conform to the PDF/A-1b standard.

此外,当使用 Adob​​e Reader DC 打开时,一致性选项卡会显示所选格式 (PFD/A-1B) 的所有详细信息,现在 OutputIntent 存在,但是详细信息不完整,因为标识符和信息值未显示。 Adobe conformance status OutputIntend incomplete capture

问题

  • 根据 Ghostscript 命令,有没有办法生成具有正确 ICC 信息的 PDF/A?据我所见,none 的结果非常令人满意,那么我应该怎么做才能将此信息成功嵌入到 PDF/A 生成的文件中?
  • 猜测 Ghostscript 命令可以实现包含适当 ICC 配置文件的符合 PDF/A 文件的技巧,并且由于我们计划使用 Ghostscript .NET,我如何包含 PDF/A 模板文件作为 C# 代码中的参数?

非常感谢。

[编辑]

我无法使用 --permit-file-read 更改权限。我通常在 C:\GS_PDFA 中有 ps 和 icc 文件,但在 GS 本地安装文件夹中尝试使用它们,但总是出现相同的错误:

Error: /invalidfileaccess in --file-- Operand stack: --nostringval-- --nostringval-- (C:/GS_PDFA/srgb.icc) (r) Execution stack: %interp_exit .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- --nostringval-- --nostringval-- false 1 %stopped_push 1990 1 3 %oparray_pop 1989 1 3 %oparray_pop 1977 1 3 %oparray_pop 1833 1 3 %oparray_pop --nostringval-- %errorexec_pop .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- Dictionary stack: --dict:741/1123(ro)(G)-- --dict:0/20(G)-- --dict:76/200(L)-- Current allocation mode is local Last OS error: Permission denied Current file position is 2118

使用 Ghostscript .NET 对控制台应用程序进行了大量测试,甚至将 PDFA_def.ps 和 srgb.icc 文件放在解决方案文件夹中,并且出现相同的错误。尝试在 C:\GS_PDFA 中找到主要的 GS 安装文件,包括 ICC 配置文件(srgb.icc),打开命令提示符并再次测试,使用 Ghostscript 命令,但均未成功。

以下是我尝试过的一些命令示例:

--permit-file-read=c:/GS_PDFA/srgb.icc
 --permit-file-read="c:/GS_PDFA/srgb.icc"
 --permit-file-read="c:/GS_PDFA/srgb.icc"
 --permit-file-read=srgb.icc
 --permit-file-read="c:\GS_PDFA\srgb.icc"
 --permit-file-read="/srgb.icc"
 --permit-file-read=/srgb.icc
 --permit-file-read="\srgb.icc"
 --permit-file-read=\srgb.icc
 --permit-file-read=c:/GS_PDFA/
 --permit-file-read="c:/GS_PDFA/"
 --permit-file-read=c:\GS_PDFA\
 --permit-file-read=c:/GS_PDFA/****.icc
 --permit-file-read=c:/GS_PDFA/*.icc
 --permit-file-read=c:/GS_PDFA/*

我试过移动文件、更改位置、文件夹等。我试过更改文件夹安装,即使使用 Ghostscriptx64 也是如此...安装时我是否遗漏了什么?

请问有人有 windows 的工作示例可以帮助我吗?

您不应使用 -dNOSAFER,而应使用 --permit-file-read 开关将 files/directories 添加到允许的文件阅读列表中。需要读取的文件是 OutputIntent 配置文件,它是 pdfa_def.ps 文件的主要成分之一。见下文。

如果您不包含 pdfa_def.ps 文件,那么您将不会在最终的 PDF/A 文件中获得 OutputIntent,并且它不会 PDF/A 兼容(除非您将 UseDeviceIndependentColor 指定为ColorConversionStrategy)。这就是为什么您的代码示例不起作用的原因。注意到 PDF-Tools 仍然说该文件有效,我将停止使用它作为验证器,它显然不可靠。我发现 VeraPDF 是个人最好的验证器(它比 Acrobat 内置验证器更好)。

令我惊讶的是,您在问题顶部显示的命令行生成了一个有效的 PDF/A 文件,除非您修改了 pdfa_def.ps 文件?您应该,尤其是您必须修改与 /ICCProfile 键关联的值。该值(括号内的字符串)需要是 ICC 配置文件的完全限定路径,并且需要将 ICC 配置文件或其所在的目录添加到允许读取的文件列表中,请参阅文档 here-dSAFER.

假设您这样做了,那么生成的 PDF 文件应该是符合 PDF/A-1b 的文件。事实上,根据你的问题,VeraPDF 说它是一致的,所以我不清楚你的问题是什么。共享输入和输出 PDF 文件比共享 Acrobat 显示的(部分)图片要有用得多。

所以回答你的问题:

  1. 是的,有一种方法可以生成带有 ICC 信息的 PDF/A 文件(如果它没有 OutputIntent,则该文件无效)并且您的命令行可以这样做。如果您没有适当地修改 pdfa_def.ps 文件,您可能仍然有问题。

  2. 据我所知,运行 pdfa_def.ps 文件使用 Ghostscript.NET 的方式与在命令行上的方式完全相同,您只需将它在参数列表中。所以你只需要取消注释你评论过的行。当然,您没有包括 -dNOSAFER,也没有将 ICC 配置文件添加到允许读取的文件列表中,因此您 得到一个错误。我很惊讶你得到了一个致命错误,我期待一个无效的访问,但显而易见的事情是将 -dNOSAFER 添加到参数中。反向通道输出可能有用,它可能包含更多信息,但您没有包含这些信息。

哦,我也不会写管道。 pdfwrite 设备希望写入文件,并且它可能会在写入文件时尝试在文件内查找。如果它确实存在并且您已经写入管道(或其他不可搜索的输出),那么它将失败。

您不需要将 -f 添加到参数列表中,并且:

switches.Add("-dNOPAUSEgsArgs");

我觉得很可疑,看起来应该是 -dNOPAUSE。

最后,如果你打算分发这个应用程序你应该检查 AGPL 的条款,我相信 Artifex 会考虑使用 Ghostscript.NET 和 Ghostscript DLL 是 'derivative work' 和您可能需要商业许可证。

编辑

output_gscommand.pdf 有这个:

1 0 obj
<</Type /Catalog /Pages 3 0 R
/OutputIntents [ 5 0 R ]
/Metadata 27 0 R
>>

5 0 obj
<</OutputConditionIdentifier(sRGB)
/DestOutputProfile  4 0 R 
/S/GTS_PDFA1
/Type/OutputIntent>>
endobj

所以这是目录中指定的 OutputIntent,唯一的 OutputIntent 具有 PDFA1 标识符、有效的 OutputConditionIdentifier(仅用于人类可读信息)和 ICC 配置文件。据我所知,这是完全有效的。

VeraPDF 和 Adob​​e Acrobat X (Pro) 中的预检工具都会验证 PDF 文件是否符合要求。所以我认为该文件是一个符合标准的 PDF/A 文件(Acrobat X 预检工具还将 OutputIntent 列为 sRGB(Custom) ICC OutputProfile: "Artifex Software sRGB ICC Profile")。

我不知道为什么 DC 没有显示 OutputIntent,我看不出文件有问题。