跳转到内容
getnextpdf.com

颜色、配置文件,以及为什么你的红不是我的红

Spec: ISO 32000-2, §8.6Spec: ISO 15930, PDF/X

PDF 中的一种颜色并不是一个固定的感官体验。它是一条指令,而这条指令在你的笔记本电脑、一部手机,以及一台印刷机上是否产出同一种红,完全取决于这种颜色当初是如何被描述的。本页讲的,正是“一种颜色只是告诉设备该做什么”与“一种颜色说出了它实际应当看起来如何”之间的区别。

挑一个品牌红。设定一次。现在把它放到一台廉价办公显示器上看,再放到明亮房间里的一部 OLED 手机上看,然后从一台胶印机上取下来看。三种红。有时是三种明显不同的红。没有人改动过那个数值;那个数值从来就不是故事的全部。

对于一份随手生成的文档,这只是耸耸肩的小事。但对于一个标志、一张受监管的标签、一份目录中的照片,或一份意在存续数十年的记录而言,一种会漂移的颜色就是一处缺陷。这代价并不抽象:它是一次重印、一次被退回的打样,或是一份其页面不再与原件一致的归档。解决之道并不是一个更好的数值,而是把这个数值的真正含义如实说出来。

  • 设备颜色用设备所接收的控制值来命名一种颜色,于是结果就是该设备对这些值的任意呈现(Spec: ISO 32000-2, §8.6.4)。DeviceRGBDeviceCMYKDeviceGray 都是设备颜色空间。同样的数值,不同的硬件,不同的颜色。
  • 经校准的、基于 ICC 的颜色通过一个嵌入的配置文件,把这些数值绑定到一个经过测量的、与设备无关的参考之上(Spec: ISO 32000-2, §8.6.5.5)。如今,这份文档便携带了足够的信息来再现那个意图中的颜色,而不只是一份控制值的配方。
  • 一个 ICC 配置文件就是那个经过测量的映射:一台设备的数值——或者某个标准颜色空间或输出条件的数值——如何与人眼会感知到的颜色相对应,并锚定到一个与设备无关的连接空间之上。
  • 一个渲染意图是一项策略,规定当一种颜色超出某台设备的能力范围时该怎么办,因为没有任何设备能显示出每一种颜色。
  • 一个输出意图是文档预先声明它当初所面向的输出条件(Spec: ISO 32000-2, §14.11.5)。印刷级(PDF/X)与归档(PDF/A)工作流都依赖它。

先从这个问题的诚实版本说起。DeviceRGB 并不包含一种颜色。它包含三个介于 0 与 1 之间的数值,以及一个未曾言明的假设:某块屏幕会把它们变成光。两块拥有不同背光、不同面板、不同校准的屏幕,会把同样的三个数值变成肉眼可见地不同的光。这不是 PDF 的缺陷。这正是“设备颜色”的含义,而标准对此直言不讳:设备颜色空间是由设备所接收的值来定义的,而不是由某种绝对的外观来定义的(Spec: ISO 32000-2, §8.6.4)。

经校准的颜色通过添加一个参考来弥合这道鸿沟。一个 ICC 配置文件,是对一台设备或一个颜色空间——一台显示器、一台打印机、一台印刷机,或诸如 sRGB 这样的标准空间——进行特性刻画的结果,它记录了该设备的原始数值如何与一个近似人类视觉的、与设备无关的连接空间中的颜色相对应。嵌入那个配置文件,数值便不再是一种私有方言;它们变成了一项锚定于人人都能认同之物的陈述。这恰恰就是一个基于 ICC 的颜色空间所携带的内容(Spec: ISO 32000-2, §8.6.5.5):颜色,外加那个说明它含义的、经过测量的映射。

还有第二道无可回避的褶皱。一台印刷机能印出的颜色集合,不等于一部手机能显示的集合,而这两者也都不是人眼能看见的完整集合。当一种颜色落在一台目标设备所能再现的范围之外时,就必须作出某种抉择:把它裁切到最接近的可达颜色,或者把一整段颜色一起平移,以便它们之间的关系保持完整。那个抉择就是渲染意图——一项为了任务而刻意挑选的策略,而不是舍入时的偶然产物。一张照片和一个企业标志往往想要不同的意图,因为一个在意平滑的渐变,另一个在意命中一个确切的色样。

最后,一份要去往某个特定去处的文档可以把这一点说出来。一个输出意图就是文件声明它当初所面向的输出条件——通常是一个嵌入的 ICC 目标配置文件,用以指明某种印刷条件或设备(Spec: ISO 32000-2, §14.11.5)。这是“把一个文件递给印刷商”与“递给他们一个写明‘我是为这台印刷机而构建的’的文件”之间的区别。印刷交换配置文件让它成为强制项:一个 PDF/X 文件(ISO 15930 族系)必须携带一个输出意图(Spec: ISO 15930, PDF/X),而 PDF/A 也依赖同一套机制,好让一份归档文件的设备相关颜色在遥远的未来——在最初的生成环境早已不复存在之后——仍然是可被解读的。

  1. Name the colourChoose a colour space. DeviceRGB/CMYK/Gray name control values; an ICC-based space anchors them to a device-independent reference (ISO 32000-2 §8.6).
  2. Anchor it (optional but decisive)Embed an ICC profile so the numbers carry their measured meaning, not just a device recipe (ISO 32000-2 §8.6.5.5).
  3. Reconcile to the deviceA rendering intent decides what happens to colours the target device cannot reproduce — clip the nearest, or shift the range to preserve relationships.
  4. Declare the destinationAn output intent states the output condition the document was prepared for, as PDF/X and PDF/A workflows require (ISO 32000-2 §14.11.5).
How a color travels from your code to a faithful result: it is named in a colour space, optionally anchored to a measured reference by an ICC profile, reconciled to the target device through a rendering intent, and interpreted against the output condition the document declares.

NextPDF 在这条链路中的职责是做到符合标准:以该格式所定义的方式去写出颜色空间、嵌入的配置文件以及输出意图,好让一个下游工具——一台印刷机的 RIP、一个归档验证器、一个阅读器——读到的恰恰就是当初所意图的内容。它生成那些声明;它并不假装自己就是那台设备。

下面的代码勾勒的是这个决策,而不是某个具体的 API。要点在于:去处是被明确说出的,而不是被猜测的。

<?php
declare(strict_types=1);
use NextPDF\Contracts\PdfDocumentInterface;
/**
* Prepare a print-bound document that declares its intended output condition.
*
* The colour numbers alone do not fix the appearance. Declaring the output
* intent — the print condition the file was built for — is what lets a press
* interpret those numbers faithfully (ISO 32000-2 §14.11.5).
*
* @param PdfDocumentInterface $doc A composed document.
* @param string $iccProfileBytes The destination ICC profile for the
* target print condition.
*
* @return string The document bytes, carrying a declared output intent.
*/
function prepareForPress(
PdfDocumentInterface $doc,
string $iccProfileBytes,
): string {
// Declare the output condition explicitly. The document now states the
// device/print condition it was prepared for, instead of leaving its
// device colours open to interpretation.
$doc->setOutputIntent(
identifier: 'Custom press condition',
iccProfile: $iccProfileBytes,
);
return $doc->output();
}

颜色并没有改变。改变的是:这个文件现在说出了它们当初意在看起来如何,而这正是一台印刷机或一个验证器唯一能据以行动的东西。

“它是同一个十六进制值,所以它是同一种颜色。”这个十六进制值是一组设备控制值。在没有配置文件或输出意图的情况下,它只是一份没有指定厨房的配方——它在每一间厨房里都会尝出不同的味道。两个文件可以携带完全相同的 RGB 数值,却如实地是不同的颜色,因为其中一个声明了那个赋予数值含义的上下文,而另一个则把它交给了运气。

第二个陷阱:假定 DeviceCMYK 自动就意味着“已准备好印刷”。它并不。CMYK 仍然是设备颜色;它是按印刷塑形的,但在某个配置文件或输出意图指明实际的印刷条件之前,它并未经过校准。

NextPDF 生成符合标准的颜色:它以该格式所定义的方式写出设备颜色空间与基于 ICC 的颜色空间,并为 PDF/X 风格与 PDF/A 工作流声明输出意图。这是这项工作中负责生成的那一半,也是一份文档能够自行掌控的那一半。

NextPDF 不是的,是一套颜色打样系统。它不会测量你的显示器、不会在屏幕上对一台印刷机进行软打样,也不会认证印刷出来的结果在某个容差范围内与一个意图中的色样相符。那些属于一条受颜色管理的打样链路,以及运行它的人。引擎让文件说出正确的内容;至于最终设备是否会兑现它,则由下游决定——由设备、由在场的各个 ICC 配置文件,以及——对于 PDF/X 和 PDF/A——由一个验证器决定,而不是由生产者决定。

  • PDF 究竟是什么 —— 这些颜色空间与输出意图所栖身的对象模型。
  • 归档与 PDF/A —— 为什么长期保存倚赖与设备无关的颜色与输出意图。
  • 标准全景 —— ISO 32000-2、PDF/X(ISO 15930)与 PDF/A(ISO 19005)彼此之间各居何处。
  • PDF 2.0:有何变化 —— 当前的格式版本如何框定颜色与符合性。
  • 设备颜色空间 —— 一种由设备所接收的控制值来命名的颜色(DeviceRGBDeviceCMYKDeviceGray);外观取决于进行解读的那台设备(ISO 32000-2 §8.6.4)。
  • 经校准的 / 基于 ICC 的颜色 —— 通过一个嵌入的 ICC 配置文件锚定到一个与设备无关的参考之上的颜色,使其意图中的外观可在各设备之间再现(ISO 32000-2 §8.6.5.5)。
  • ICC 配置文件 —— 一台特定设备的数值与一个近似人类视觉的、与设备无关的参考之间的、经过测量的映射。
  • 渲染意图 —— 处理目标设备无法再现的颜色时所采用的策略:裁切到最接近的可达颜色,或平移一整段颜色以保持颜色之间的关系。
  • 输出意图 —— 文档对它当初所面向的输出条件所作的声明,通常通过一个嵌入的目标 ICC 配置文件(ISO 32000-2 §14.11.5);PDF/X 要求它,PDF/A 使用它。
  • PDF/X —— PDF 的 ISO 15930 印刷交换配置文件族系;一个 PDF/X 文件必须携带一个指明其目标印刷条件的输出意图。