交换 .eps 文件中的图像?

Swap an image in an .eps file?

我想弄清楚如何将嵌入在 .eps 文件中的图像与 jpeg 交换。我的 "template" .eps 文件包含几个看起来像这样的部分,每个部分代表不同的图像:

Adobe_AGM_Image/AGMIMG_fl cf /ASCII85Decode fl /RunLengthDecode filter ddf
<<
/T 1
/W 4773 
/H 273 
/M[4773 0 0 -273 0 273 ]
/BC 8 
/D[0 1 0 1 0 1 0 1 ]
/DS [
[AGMIMG_fl 4773 string /rs cvx /pop cvx] cvx
[AGMIMG_fl 4773 string /rs cvx /pop cvx] cvx
[AGMIMG_fl 4773 string /rs cvx /pop cvx] cvx
[AGMIMG_fl 4773 string /rs cvx /pop cvx] cvx
]
/O 3
>>
%%BeginBinary: 1
img
[image data]~>

%%EndBinary

据我所知,图像文件是 ASCII85 编码的,但我还没有找到一种方法来编码 jpeg 图像,以便我可以将其换出。

为了澄清情况,我同时拥有 .eps 和原始文件。 ASCII85 解码 .eps 中的图像块与 jpeg 中的信息不匹配,反之亦然。

[更新]

我的最终目标是在不使用 adobe 脚本语言的情况下创建带有图层的 .eps。我们为我们的客户创建决赛,然后我们需要将其添加到我们的打印机给我们的模板(.eps 文件)中。所有的决赛应该是相同的,并包含相同的配色方案 (CMYK)。

在.eps 文件中,其中一层(Adobe Illustrator 可以读取)包含需要打印的图稿;另一层包含 "spot color" 中的切割线,打印机将其用作切割机的说明。我的目标是使模板制作过程自动化,这样我们就不需要为打印机手动创建 .eps 文件。

一个简单的 find/replace 似乎是实现我的目标的最简单的方法,但我并不认同这个想法。 imagemagick、graphicsmagick 和 pillow 等图像库至今都让我失望。

[更新]

根据要求,这是模板的图片: 有四个不同的黑色图像,正如您所猜测的那样,它们在切割线之间的中点相遇。在 "templating process"(可能是措辞不当)期间,我们将为我们的客户生成的艺术品 - 决赛 - 并将其放置在黑色图像所在的位置。整个过程是手动的、乏味的,并且应该可以自动化 - 这就是我正在尝试做的。

实际上你不应该尝试替换图像。

PostScript 是一种编程语言,除非您打算处理的 所有 EPS 文件都是由同一个应用程序生成的,并且实际上是该应用程序的完全相同版本,那么程序的确切语义可能会有所不同。如果语义不同,则搜索和替换将失败。

您提供的部分不完整,看起来像是 CMYK 格式的 4 色图像 space(因为它有 4 个读取数据的过程,解码数组可能有 8 个元素)但是没有尝试设置颜色 space,您也不知道有效的 CTM。除非具有相同的行数和列数,否则很难缩放不同的图像以适应同一区域。

图像数据不是简单的 ASCII85 编码,它也是 运行 长度编码(在 运行 长度编码后应用 ascii85),数据以交错栅格形式提供。一行青色接着一行洋红色,接着一行黄色和一行黑色。为了让图像应用程序读取它,您将必须读取一组 4 个光栅,撤消 ascii85 编码,然后撤消 运行-length 编码,然后分别从每个光栅中获取样本并将它们交错以产生4 行 CMYKCMYKCMYK... 数据。 (请注意,很少有图像应用程序可以处理 CMYK 数据)。

为了替换图像数据,假设替换的尺寸精确相同,您需要将图像数据解码为图像样本(即撤消 JPEG 压缩).将其分解为C、M、Y、K平面,运行对平面进行长度编码,然后对每个光栅进行ascii85编码,然后将图像数据一次写入一个光栅线。

如果颜色 space、尺寸、每个组件的位数或编码有任何差异,那么您还需要替换读取图像数据并将其按摩成适合的形式的程序部分传递给解释器,这将是一项艰巨的任务,需要您学习 PostScript 编程语言。

'img' 过程(将在程序的前面定义)获取字典数据并将其转换为图像字典以提供给 PostScript 图像运算符或将其转换为等效的 1 级操作数如果解释器非常旧且仅支持级别 1,则提供给图像操作员。

一般来说,处理 EPS 文件的唯一方法是使用完整的 PostScript 解释器,例如 Ghostscript(由 ImageMagick 使用,我推测是 GraphicsMagick)。因为你真的需要解释程序。您可以对符合 EPS 规范的程序进行有限的更改,但批量替换图像数据不是预期目的之一。

我不知道你所说的 'layers' 是什么意思。 PostScript 中没有层的概念,因为它是一种页面描述语言;不需要 'layer'。也许如果你能解释你想要实现的目标,也许可以提供不同的解决方案。

[补充]

好的,在这种情况下,'normal' 的处理方法是生成带有 'template' 的 PostScript,以便它包含来自客户的内容。

通常,客户内容将以 EPS(现在可能是 PDF)的形式提供,为打印机创建输出的工具将生成 PostScript(不是 EPS,一个完整的 PostScript 程序)并将 EPS 嵌入到程序。这就是 EPS 的意义所在,您将其包含在 PostScript 程序中。

EPS 文件不是真正可编辑的,也不是为了改变,事实上改变它们可能会使 BoundingBox 信息无效。理解 PostScript 程序做什么的唯一方法是解释它,这就是为什么尝试搜索和替换并不是真正面向未来的解决方案的原因。

我也有点担心您似乎在打印环境中使用 JPEG 压缩图像! JPEG(通常)是一种有损压缩方法,因此 JPEG 压缩图像会有伪影,我通常认为它不适合您在这里暗示的那种过程。

现在我可以看到几种不涉及编辑 EPS 文件的解决问题的方法。假设您知道每个 'boxes' 在 EPS 中的大小和位置,并且您的客户内容是 EPS 格式,您只需将文件连接在一起,根据需要生成位置信息。

PostScript 有一个不透明的成像模型,这意味着如果您从 'template' 开始,然后正确设置 CTM,您可以包含整个 EPS 文件,使其在渲染时完全覆盖您要替换的区域。

为此,您需要知道 EPS 应覆盖的精确大小和位置(我假设您知道这一点)以及 EPS 覆盖的确切区域,您可以从 %%BoundingBox 评论中获得EPS 文件。然后添加缩放和平移操作以便 EPS 正确调整大小和定位是一件微不足道的事情。

这是我的意思的概要:

%!PS

%!PS-Adobe-2.0 EPSF-1.2
%%Creator: Adobe Illustrator
%%Title: Template
%%BoundingBox: 0 0 612 792
....
....
%%EOF

% execute a save of the graphics state so the EPS doesn't change anything
gsave

% Reposition customer EPS file to first location in the template
% and scale it up (Lets pretend the first slot is at x=0, y=200
% and we need to double the size of the EPS so it fits.
0 200 moveto
2 2 scale

%!PS-Adobe-2.0 EPSF-1.2
%%Creator: Adobe Illustrator
%%Title: customer content file #1
%%BoundingBox: 0 0 100 100
....
....
%%EOF

% Now execute a grestore so everythgin goes back to the state it was in
% before we ran the EPS
grestore

% Repeat for each EPS file

showpage

我假设您的客户内容是作为 EPS 而不是图像(位图)数据提供的。如果它确实是 JPEG 图像,那么您可以编写 PostScript 代码以在上面的代码中包含 JPEG 代替 EPS。

我不清楚你现有的流程是如何运作的,我不清楚你定位客户端内容的手动流程是什么。