如何使用 Ghostscript 和 Ghostscript .NET 通过嵌入 IIC 配置文件生成正确的 PDF/A
Posted
技术标签:
【中文标题】如何使用 Ghostscript 和 Ghostscript .NET 通过嵌入 IIC 配置文件生成正确的 PDF/A【英文标题】:How to generate proper PDF/A with embedding IIC profile using Ghostscript and Ghostscript .NET 【发布时间】:2020-07-28 10:29:35 【问题描述】:当前情景:
我正在尝试基于普通 PDF 文档生成正确且符合标准的 PDF/A,经过几个小时的调查,我们决定使用 Ghostscript 功能。这个业务需求是为我正在从事的一个更大的 C# 项目设置的,但首先我开始在 Windows 上下文中使用 Ghostscript 命令 进行一些测试,并创建了一个独立的 另一个使用 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 参数,我也无法在没有它的情况下生成 PDF,因为 /invalidfileaccess 错误。我怀疑访问权限是原因,正如在 *** (GhostScript: Error: /invalidfileaccess in --file--) 上搜索时发现的那样,但仍然没有找到任何适合我的解决方案。
也尝试了以下命令,但同样的错误(将所需的 ICC 配置文件与 .ps 模板文件放在同一文件中):
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 配置文件,我尝试在 Ghostscript 安装目录中的 /lib 上提供默认 PDFA_def.ps template。之后,尝试使用 PDFA_def.ps 模板文件,更新行:
/ICCProfile (C:/GS_PDFA/srgb.icc)
和
/OutputConditionIdentifier (sRGB)
结果和验证
结果:Download PDF generated by command line
VeraPDF 说:
PDF 文件符合验证配置文件要求
PDF-Tools 说:
该文档确实符合 PDF/A-1b 标准。
此外,当使用 Adobe 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");) 包含,则应用程序会引发错误 :
调用“gsapi_init_with_args”时出错:-100
我试图防止错误使用模板文件的另一个位置,但没有成功。还在顶部添加了代码行:switches.Add("-Ic:/GS_PDFA/"); 但同样的错误。
结果和验证
结果:Download PDF generated by GS .NET DLL
VeraPDF 说:
如果没有设置 PDFA_def.ps 模板文件,则生成的文件不会通过验证检查。
PDF 文件不符合验证配置文件要求
PDF-Tools 说:
该文档确实符合 PDF/A-1b 标准。
此外,当使用 Adobe Reader DC 打开时,一致性选项卡会显示所选格式 (PFD/A-1B) 的所有详细信息,现在 OutputIntent 存在,但详细信息不完整,因为未显示标识符和信息值。 Adobe conformance status OutputIntend incomplete capture
问题
根据 Ghostscript 命令,有没有办法生成带有正确 ICC 信息的 PDF/A?就我所见,没有一个结果真正令人满意,那么我应该怎么做才能成功地将这些信息嵌入到 PDF/A 生成的文件中? 猜测 Ghostscript 命令可以实现包含正确 ICC 配置文件的符合标准的 PDF/A 文件,并且由于我们计划使用 Ghostscript .NET,如何将 PDF/A 模板文件作为参数包含在 C# 代码中?非常感谢。
[编辑]
我无法使用 --permit-file-read 更改权限。我通常在 C:\GS_PDFA 中有 ps 和 icc 文件,但在 GS 本地安装文件夹中尝试使用它们,但总是出现相同的错误:
错误:/invalidfileaccess in --file-- 操作数栈: --nostringval-- --nostringval-- (C:/GS_PDFA/srgb.icc) (r) 执行栈: %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-- 字典栈: --dict:741/1123(ro)(G)-- --dict:0/20(G)-- --dict:76/200(L)-- 当前分配模式是本地的 最后一个操作系统错误:权限被拒绝 当前文件位置是 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 工作示例吗?
【问题讨论】:
【参考方案1】:您不应使用-dNOSAFER
,而应使用 --permit-file-read 开关将文件/目录添加到允许的文件阅读列表中。需要读取的文件是 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 显示的(部分)图片更有用。
所以回答你的问题:
是的,有一种方法可以生成带有 ICC 信息的 PDF/A 文件(如果它没有 OutputIntent,则它无效)并且您的命令行会这样做。如果您没有适当地修改 pdfa_def.ps 文件,您可能仍然会遇到问题。
据我所知,您使用 Ghostscript.NET 以与在命令行上完全相同的方式运行 pdfa_def.ps 文件,只需将其放在参数列表中即可。因此,您只需要取消注释您已评论的行。当然,您没有包含 -dNOSAFER,也没有将 ICC 配置文件添加到允许读取的文件列表中,因此您会收到错误消息。我很惊讶你得到了一个致命的错误,我期待一个无效的访问,但显而易见的事情是将 -dNOSAFER 添加到参数中。反向通道输出可能有用,它可能包含更多信息,而您没有包含这些信息。
哦,我也不会写信给管道。 pdfwrite 设备期望写入文件,它可能会在写入文件时尝试在文件中查找。如果确实如此,并且您已写入管道(或其他不可搜索的输出),那么它将失败。
您不需要将 -f 添加到参数列表中,并且:
switches.Add("-dNOPAUSEgsArgs");
在我看来很可疑,看起来应该是 -dNOPAUSE。
最后,如果您打算分发此应用程序,您应该检查 AGPL 的条款,我相信 Artifex 会将 Ghostscript.NET 和 Ghostscript DLL 的使用视为“衍生作品”,您可能需要商业许可证。
编辑
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
所以这是 Catalog 中指定的 OutputIntent,唯一的 OutputIntent 具有 PDFA1 标识符、有效的 OutputConditionIdentifier(仅用于人类可读信息)和 ICC 配置文件。据我所知,这是完全有效的。
VeraPDF 和 Adobe Acrobat X (Pro) 中的印前检查工具都会验证 PDF 文件是否符合要求。所以我认为该文件是符合标准的 PDF/A 文件(Acrobat X 预检工具还将 OutputIntent 列为 sRGB(Custom) ICC OutputProfile: "Artifex Software sRGB ICC Profile")。
我不知道为什么 DC 没有显示 OutputIntent,我看不出文件有任何问题。
【讨论】:
非常感谢您的全面深入审查,我注意到您的答案中可能包含有关某些提示的其他信息,因此我更新了问题。我会尝试 UseIndependentColor 选项,但尝试包含 --permit-file-read 命令但没有成功(有问题更新)。我很抱歉 PDF/A 模板已经在某些测试用例中进行了修改,但我的问题中没有提到这一事实,所以我更新了它。如果您愿意,请再次查看以检查修改的行。 感谢您建议包含在生成的文件中,认为包含多个文件附件是不建议的。 Acrobat 捕获仅假装描述在一种情况下遗漏了 OutputIntent 而在另一种情况下不完整。正如您所说,由于 IIC 并未真正包括在内,因此似乎与此行为有关。关于一致性,PDF-tools 指出文件不符合标准。另一方面,VeraPDF 指出该文件是符合标准的,即使它不包含 ICC 配置文件,PDF 文件是否有可能在不包含 ICC 的情况下符合 PDF/A 格式? 写入管道被认为是 byte[] 生成 (***.com/questions/25240436/…) 的工作解决方案。是否有替代解决方案或最佳实践?我更新了你评论的代码行。关于 AGPL,我已经与 Artifex 取得联系,因为我们的项目仅针对内部企业,并且他们已经确认我们使用 DLL(或者即使您向客户提供和生成的文件)不需要商业许可,甚至发布你的源代码。我们将再次检查 GS.NET。感谢您的建议。 恐怕回复慢,这对我来说是兼职练习。感谢您澄清许可证,只是想确保您没有浪费时间或有一个令人讨厌的惊喜。拥有没有 OutputIntent 的有效 PDF/A 的唯一方法是将所有颜色都放在与设备无关的空间中(srgb、ICCBased、Lab,我可能错过了一些)。通常 pdfwrite 不会产生那些,除非你说 UseDeviceIndependentColor。 --permit-file-read 应该可以工作,它已经过测试,但是要使咒语正确可能会很棘手。是的,我猜 pdfa_def.ps 被修改了,很高兴听到它确实如此。 写入管道“通常”会起作用,直到有一天它不起作用。只有当 pdfwrite 设备需要回溯生成的 PDF 文件并更新一些数据时,它才会失败。 目前在生成线性化文件时就是这种情况,但将来无法保证。我不会依赖它。 Ghostscript.NET(与 Ghostscript 本身相反)可能通过写入文件然后将文件读回内存来处理此问题,我不知道,抱歉。如果是我,除非你确定 Ghostscript.NET 正在做什么,否则我会自己编写代码。以上是关于如何使用 Ghostscript 和 Ghostscript .NET 通过嵌入 IIC 配置文件生成正确的 PDF/A的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Ghostscript 和 Ghostscript .NET 通过嵌入 IIC 配置文件生成正确的 PDF/A
Michael jackson歌曲Ghosts和Jam的歌词(要中文注解)
LeetCode 789. Escape The Ghosts