跳转到内容
getnextpdf.com

生产印刷就绪的 CMYK 与专色

屏幕颜色是 RGB。印刷颜色不是。当一台印刷机或一个打样 RIP 消费你的 PDF 时,它想要的是印刷油墨(CMYK)、偶尔出现的命名油墨(一个专色或 Separation 颜色),以及一份它应当假设的生产条件声明。本示例展示 NextPDF 为那群受众提供的三条颜色写出路径:

  • 设备 CMYK 填充和描边 —— setFillColorCmyk() / setDrawColorCmyk()
  • 以某个色调绘制的专色 / Separation 油墨 —— registerSpotColor() 然后 setSpotFillColor() / setSpotDrawColor()
  • 一个为整个文档声明 RGB 工作/输出条件的 ICC 输出意图 —— Config::withOutputColorProfile()。随附的配置文件是 RGB 工作空间;这不声明一个真正的 CMYK 印刷机 / PDF/X 印刷条件。

先把范围说在前面:这是颜色写出。NextPDF 写出你要的 CMYK 数值、Separation 空间和输出意图声明。它不运行颜色管理变换 —— 它不会把你的 RGB 美术稿重新渲染进某个目标 CMYK 色域、做软打样,或保证视觉匹配。请提供已经为你的条件指定好的颜色。

Terminal window
composer require nextpdf/core:^3

无需任何可选扩展。颜色 API 自 1.2.0 起就一直稳定,并在 8.1–8.4 backport 矩阵上运行。

CMYK 是胶印和数字印刷的默认:四个通道,cyan / magenta / yellow / black(即“key”)。设置填充或描边颜色,然后照常绘制。

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->addPage();
// Components are percentages, 0–100 (cyan, magenta, yellow, key).
$doc->setFillColorCmyk(0, 95, 100, 0); // a process "red"
$doc->rect(20, 30, 60, 40, 'F');
$doc->setDrawColorCmyk(100, 0, 0, 0); // pure cyan rule
$doc->setLineWidth(1.0);
$doc->rect(20, 30, 60, 40, 'S');
$doc->setTextColorCmyk(0, 0, 0, 100); // rich-free 100% K text
$doc->setFont('helvetica', '', 12);
$doc->text(20, 85, 'Process CMYK');
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/cmyk.pdf');

每次调用都会向内容流写出一个 DeviceCMYK 颜色运算符:k 用于非描边(填充/文字)颜色,K 用于描边颜色,四个分量会被缩放到 PDF 内部使用的 0.0–1.0 范围。ISO 32000-2 §8.6.8(颜色运算符,Table 73)把 kK 定义为 DeviceCMYK 颜色设置运算符;§8.6.4.4 定义 DeviceCMYK 颜色空间本身。

底层的值对象是 NextPDF\Graphics\Color。如果你直接构建颜色,Color::cmyk($c, $m, $y, $k) 接收同样的 0–100 百分比,且每个 …Cmyk 文档方法都会调用它。

以某个色调绘制的专色 / Separation 油墨

标题为“以某个色调绘制的专色 / Separation 油墨”的章节

一个专色是单个命名油墨 —— 一个 Pantone、一个 HKS、一道上光油、一块模切“切割”版 —— 印刷机把它作为自己独立的版上机,而不是用印刷油墨配出来。在 PDF 里它是一个 Separation 颜色空间:一个色料名加上一个替代空间(这里是 DeviceCMYK)和一个把 [0, 1] 内的色调值映射到替代空间的色调变换,让非专色渲染器仍能显示一个近似。

把油墨连同它的 CMYK 回退注册一次,然后以某个色调百分比把它设为填充或描边颜色:

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->addPage();
// Register the ink and its CMYK fallback (percentages, 0–100).
$doc->registerSpotColor('PANTONE 485 C', 0, 95, 100, 0);
// Full-strength fill.
$doc->setSpotFillColor('PANTONE 485 C'); // tint defaults to 100
$doc->rect(20, 30, 50, 30, 'F');
// 40% tint of the same ink.
$doc->setSpotFillColor('PANTONE 485 C', 40);
$doc->rect(80, 30, 50, 30, 'F');
// Same ink as a stroke at 75%.
$doc->setSpotDrawColor('PANTONE 485 C', 75);
$doc->setLineWidth(1.5);
$doc->line(20, 75, 130, 75);
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/spot.pdf');

你必须在选择某个专色之前 registerSpotColor() 它;一个未注册的名字会抛出一个 PageLayoutException。注册会写出 Separation 资源和色调变换;setSpotFillColor() / setSpotDrawColor() 随后会针对那个已注册的 Separation 资源,为填充写出 /CS_<token> cs <tint> scn(或大写的描边形式 /CS_<token> CS <tint> SCN)。这里有两个不同的名字在起作用,引擎分别处理它们:

  • 资源 KEY —— 内容流运算符引用的、且页面 /Resources /ColorSpace 字典据以建键的那个 /CS_… 标记 —— 由油墨名通过把每个非单词字符替换为 _ 派生而来,因此 'PANTONE 485 C' 选择资源 /CS_PANTONE_485_C。(对于含有字面 _、连字符或其他标点的油墨名,会追加一个简短的确定性后缀来保持键不冲突,因此两个近乎相同的名字绝不会共用一个颜色空间。)
  • Separation 色料名本身 —— 携带在 [/Separation /<name> …] 颜色空间数组里的那个名字 —— 会原样保留,并由写入器编码为一个 PDF 名称对象,对任何定界符或不可打印字节做十六进制转义(#XX)。它不会被压平成 CS_… 标记;资源键和色料名是独立计算的。

你传入的色调参数是一个百分比,0(纸)到 100(满墨),但写进内容流的操作数是归一化后的 0.0–1.0 值,因此一个 40 色调会写出 /CS_PANTONE_485_C cs 0.400000 scn。ISO 32000-2 §8.6.6.4 涵盖 Separation 颜色空间及其色调变换。

默认的色调变换是一个从 [0 0 0 0](色调 0 处的纸)到已注册 CMYK 回退(色调 1 处的满墨)的线性插值。对于普通专色油墨这是正确的;一个非线性油墨或一份实测配置文件需要一个自定义变换,那超出本示例范围。

PDF 可以携带一份文档级的声明,说明它的颜色是为何种颜色条件而准备的 —— 一个输出意图:一个为生产条件命名的字典,目标 ICC 配置文件作为一个 ICCBased 流嵌入其中。在一个真正的印刷/PDF-X 工作流里,这是一个 CMYK 印刷机条件(例如一个涂布的 FOGRA 或 GRACoL 配置文件)。然而,NextPDF 随附的配置文件是 RGB 工作空间 —— 因此 Config::withOutputColorProfile() 所声明的是一个 RGB 观看 / 工作空间输出条件,而非一个 CMYK 目标。在依赖它做印刷输出之前,请先看示例下方的说明。

NextPDF 通过文档 Config 暴露这一点。挑一个随附的工作空间配置文件,构建 config,并据此创建文档:

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;
use NextPDF\Core\Document;
use NextPDF\Core\OutputColorProfile;
// Declare an explicit, embedded output intent for the document.
$config = (new Config())
->withOutputColorProfile(OutputColorProfile::Srgb);
$doc = Document::createStandalone($config);
$doc->addPage();
$doc->setFillColorCmyk(0, 95, 100, 0);
$doc->rect(20, 30, 60, 40, 'F');
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/with-intent.pdf');

OutputColorProfile 是一个枚举,列出引擎为之随附配置文件的工作空间。所有有配置文件支撑的枚举项都是三分量 RGB 工作空间;DeviceRGB 是默认的哨兵,且不发出输出意图。 不存在随附的 CMYK 目标配置文件:

  • DeviceRGB —— 默认。发出输出意图:不声明任何 PDF 级输出条件,且 PDF/A 流水线(若激活)保留对 /OutputIntents 数组的独占控制。当你不想声明一个时使用它。(无输出意图的 PDF DeviceRGB 内容是设备相关的 —— 它不是一个已声明的 sRGB。)
  • Srgb —— 发出一个输出意图字典,嵌入随附的 sRGB.icc,带标准条件标识符 sRGB IEC61966-2.1
  • DisplayP3Rec2020A98RGBProphotoRGB —— 广色域 RGB 工作空间,各自在一个自定义(NextPDF wide-gamut …)条件标识符下嵌入其随附的 ICC 配置文件。

任何 DeviceRGB 之外的枚举项都会让写入器发出一个引用嵌入的 ICCBased 流(带其 /N 3 分量计数)的输出意图字典。ISO 32000-2 §14.11.5 定义输出意图字典;§8.6.5.5 定义携带嵌入配置文件的 ICCBased 颜色空间。在当前引擎里,无论你挑哪个随附配置文件,这个字典都以 PDF/X 输出意图子类型 /GTS_PDFX 写出(PDF/A 归档路径使用它自己的 /GTS_PDFA1 子类型并单独发出)。

重要的告诫:因为所有随附配置文件都是 RGB,这声明的是文档的 RGB 工作空间和观看意图 —— 它不是一个 CMYK 目标配置文件,也不会把任何东西变换进 CMYK。引擎不允许你通过 withOutputColorProfile() 提供一个自定义的 CMYK 目标 ICC。一个真正的印刷/PDF-X CMYK 输出意图需要一个把你自己的 CMYK ICC 配置文件作为目标嵌入的工作流;关于接入同一个 /OutputIntents 数组的归档输出意图,参见 PDF/A-4 输出

  • 设备 CMYK —— 任何要送进印刷机的美术稿的默认。从一开始就用 CMYK 指定你的颜色,这样下游就不会有 RGB→CMYK 的猜测。
  • 专色 / Separation —— 必须命中确切油墨的品牌色,以及非印刷版(上光油、白墨、金属色、模切、烫金)。注册一次,以任意色调绘制。
  • 输出意图 —— 当你希望文件能自我描述它的 RGB 工作/输出条件时,或当某个消费者(一个查看器、一个颜色管理的 RIP、一个校验器)期望一份已声明的输出条件时,设置它。随附的配置文件只声明一个 RGB 工作/输出条件;它们不声明一个真正的 CMYK 印刷机 / PDF/X 印刷条件。
  • CMYK 分量是百分比(0–100),不是 0–1。 …Cmyk 文档方法和 Color::cmyk() 把每个通道当作一个 0–100 百分比接收,并在写运算符时除以 100;内容流操作数是归一化后的 0.0–1.0 值。满墨传 100,而不是 1.0(引擎会把后者当作 1% 油墨)。
  • 选用专色之前先注册。 如果名字从未注册,setSpotFillColor() / setSpotDrawColor() 会抛出。名字按精确匹配,包括大小写和空格。
  • 颜色状态会持续。 一个 CMYK 或专色颜色会一直有效,直到你改变它。在一个无关的块之前先重置。
  • CMYK 回退是一个近似。 Separation 色调变换的存在是为了让非专色渲染器能显示某种东西;它不是印刷机输出。真正的油墨是那块命名版所产生的。
  • 输出意图是一份声明,而非一次转换。 声明 OutputColorProfile::Srgb 不会把你的颜色变换进 sRGB;它陈述意图条件。颜色准确性由你在上游负责。

每次颜色选择都是单个内容流运算符;一个专色还会为每个已注册油墨写一个 Separation 资源。一个嵌入的输出意图配置文件每个文档写一次。所有路径都稳稳落在 2000 ms / 64 MB 预算之内。

本示例只写出你代码所指定的颜色和配置文件。它不解析任何不受信任的输入,也不进行网络访问。如果色料名或 CMYK 分量来自外部数据,请校验它们:把分量钳制到 0–100,并拒绝专色名里的控制字符(Separation 名里的 NUL 字节会被引擎拒绝)。

陈述规范条款
kK 是设置 DeviceCMYK 非描边 / 描边颜色的颜色运算符。ISO 32000-2§8.6.8
DeviceCMYK 是减色的四分量印刷颜色空间。ISO 32000-2§8.6.4.4
一个 Separation 颜色空间为一个色料命名,其色调通过一个色调变换映射到一个替代空间。ISO 32000-2§8.6.6.4
一个 ICCBased 颜色空间嵌入一个带 /N 分量计数的 ICC 配置文件流。ISO 32000-2§8.6.5.5
一个输出意图声明目标生产条件;GTS_PDFX 命名印刷子类型。ISO 32000-2§14.11.5

可重现性 profile —— structural。 颜色写出本身没有熵,但每个保存的文档都携带一个 trailer /ID 和日期原子,而一个嵌入的 ICC 流仅对一个固定的随附配置文件才字节稳定。所支持的主张是经 qpdf 归一化后的结构相等。本示例描述 NextPDF 如何产生该结构;它不断言笼统的 ISO 32000-2 合规性。

不适用。设备 CMYK、专色/Separation 颜色,以及输出意图声明都是 Core 能力,没有 Premium 门禁。Core 支持这里展示的随附 RGB 输出意图声明;自定义 CMYK 印刷条件 ICC 工作流不在本示例的主张之内。