首页 > 解决方案 > 交换 .eps 文件中的图像?

问题描述

我试图弄清楚如何用 jpeg 交换嵌入在 .eps 文件中的图像。我的“模板”.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 可以读取)包含需要打印的图稿;另一层包含“专色”的切割线,打印机将其用作切割机的说明。我的目标是自动化模板过程,这样我们就不需要为打印机手动创建 .eps 文件。

一个简单的查找/替换似乎是实现我的目标的最简单方法,但我并不认同这个想法。迄今为止,imagemagick、graphicsmagick 和pillow 等图像库都让我失望了。

[更新]

根据要求,这是模板的图像:打印机模板 有四个不同的黑色图像,正如您猜测的那样,它们在切割线之间的中点相遇。在“模板化过程”(可能是一个糟糕的词选择)期间,我们将为我们的客户生成的艺术品 - 决赛 - 并将其放置在黑色图像所在的位置。整个过程是手动的、乏味的,并且应该可以自动化——这就是我正在尝试做的事情。

标签: jpegepsascii85

解决方案


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

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

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

图像数据不是简单的 ASCII85 编码,它也是行程编码(在行程编码后应用 ascii85),并且数据作为交错光栅提供。一条青色线,然后是一条洋红色线,然后是一条黄色线和一条黑色线。为了让图像应用程序读取此内容,您必须读取一组 4 个光栅,撤消 ascii85 编码,然后撤消游程编码,然后从每个光栅中单独取样并交错生成 4 行 CMYKCMYKCMYK ... 数据。(请注意,很少有图像应用程序可以处理 CMYK 数据)。

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

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

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

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

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

[额外的]

好的,因此在这种情况下进行的“正常”方法是生成带有“模板”的 PostScript,以便它包含来自客户的内容。

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

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

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

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

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

为此,您需要知道 EPS 应覆盖的精确大小和位置(我假设您知道这一点)以及 EPS 覆盖的确切区域,您可以从 EPS 文件的 %%BoundingBox 注释中获得。然后,添加缩放和平移操作以使 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

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

我对您现有流程的工作方式很模糊,对我来说,您定位客户内容的手动流程是什么并不明显。


推荐阅读