Pular para o conteúdo
getnextpdf.com

Produza cor CMYK e spot pronta para impressão

A cor de tela é RGB. A cor de impressão não é. Quando uma impressora ou um RIP de prova consome o seu PDF, ele quer tintas de processo (CMYK), a tinta nomeada ocasional (uma cor spot ou Separation) e uma declaração da condição de produção que ele deve assumir. Esta receita mostra os três caminhos de emissão de cor que o NextPDF oferece para esse público:

  • Preenchimentos e contornos em device CMYKsetFillColorCmyk() / setDrawColorCmyk().
  • Tintas spot / Separation em um tom — registerSpotColor() e depois setSpotFillColor() / setSpotDrawColor().
  • Um output intent ICC que declara uma condição de trabalho/saída RGB para o documento inteiro — Config::withOutputColorProfile(). Os perfis empacotados são espaços de trabalho RGB; isso não declara uma verdadeira condição de impressão CMYK / PDF/X.

Nota de escopo de antemão: isto é emissão de cor. O NextPDF escreve os números CMYK, o espaço Separation e a declaração de output intent que você pede. Ele não executa uma transformação de gerenciamento de cor — ele não vai re-renderizar a sua arte RGB para um gamut CMYK de destino, fazer soft-proof dela nem garantir uma correspondência visual. Forneça cores já especificadas para a sua condição.

Terminal window
composer require nextpdf/core:^3

Nenhuma extensão opcional é necessária. A API de cor está estável desde 1.2.0 e roda na matriz de backport 8.1–8.4.

CMYK é o padrão para impressão de processo offset e digital: quatro canais, cyan / magenta / yellow / black (a “key”). Defina a cor de preenchimento ou de contorno e depois desenhe como de costume.

<?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');

Cada chamada emite um operador de cor DeviceCMYK no content stream: k para a cor não estrocada (preenchimento/texto) e K para a cor estrocada, com os quatro componentes escalados para o intervalo 0.0–1.0 que o PDF usa internamente. A ISO 32000-2 §8.6.8 (Colour Operators, Table 73) define k e K como os operadores de definição de cor DeviceCMYK; §8.6.4.4 define o próprio espaço de cor DeviceCMYK.

O value object subjacente é NextPDF\Graphics\Color. Se você constrói cores diretamente, Color::cmyk($c, $m, $y, $k) recebe as mesmas porcentagens 0–100 e é o que todo método de documento …Cmyk chama.

Uma cor spot é uma única tinta nomeada — um Pantone, um HKS, um verniz, uma chapa de “corte” para faca — que a impressora carrega como sua própria chapa em vez de construir a partir de tintas de processo. No PDF, ela é um espaço de cor Separation: um nome de colorante mais um espaço alternativo (aqui DeviceCMYK) e um tint-transform que mapeia um valor de tom em [0, 1] para o alternativo, de modo que renderizadores sem suporte a spot ainda mostrem uma aproximação.

Registre a tinta uma vez com seu fallback CMYK e depois defina-a como a cor de preenchimento ou de contorno em uma porcentagem de tom:

<?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');

Você precisa fazer registerSpotColor() antes de selecioná-la; um nome não registrado lança uma PageLayoutException. O registro escreve o recurso Separation e o tint transform; setSpotFillColor() / setSpotDrawColor() então emitem /CS_<token> cs <tint> scn para um preenchimento (ou a forma de contorno em maiúsculas /CS_<token> CS <tint> SCN) contra aquele recurso Separation registrado. Dois nomes distintos estão em jogo aqui, e o engine os trata separadamente:

  • A CHAVE de recurso — o token /CS_… que o operador do content stream referencia e sob o qual o dicionário /Resources /ColorSpace da página é indexado — é derivada do nome da tinta substituindo cada caractere não-palavra por _, então 'PANTONE 485 C' seleciona o recurso /CS_PANTONE_485_C. (Para nomes de tinta que contêm um _ literal, um hífen ou outra pontuação, um curto sufixo determinístico é anexado para manter a chave livre de colisões, de modo que dois nomes quase idênticos nunca compartilhem um espaço de cor.)
  • O próprio nome de colorante Separation — o nome carregado dentro do array de espaço de cor [/Separation /<name> …] — é mantido como está e codificado pelo writer como um objeto name do PDF, fazendo hex-escape (#XX) de qualquer delimitador ou byte não imprimível. Ele não é achatado para o token CS_…; a chave de recurso e o nome de colorante são calculados de forma independente.

O argumento de tom que você passa é uma porcentagem, 0 (papel) a 100 (tinta cheia), mas o operando escrito no content stream é o valor normalizado 0.0–1.0, então um tom 40 emite /CS_PANTONE_485_C cs 0.400000 scn. A ISO 32000-2 §8.6.6.4 cobre os espaços de cor Separation e seu tint transform.

O tint transform padrão é uma interpolação linear de [0 0 0 0] (papel no tom 0) para o fallback CMYK registrado (tinta cheia no tom 1). Isso está correto para tintas spot comuns; uma tinta não linear ou um perfil medido precisa de um transform customizado, o que está além desta receita.

O PDF pode carregar uma declaração em nível de documento da condição de cor para a qual suas cores foram preparadas — um output intent: um dicionário que nomeia a condição de produção, com o perfil ICC de destino incorporado como um stream ICCBased. Em um verdadeiro fluxo de impressão/PDF-X isso é uma condição de impressão CMYK (um perfil FOGRA coated ou GRACoL, por exemplo). Os perfis que o NextPDF empacota, porém, são espaços de trabalho RGB — então o que Config::withOutputColorProfile() declara é uma condição de saída de visualização / espaço de trabalho RGB, não um destino CMYK. Veja a nota abaixo do exemplo antes de confiar nisso para saída de impressão.

O NextPDF expõe isso por meio do Config do documento. Escolha um dos perfis de espaço de trabalho empacotados, construa o config e crie o documento a partir dele:

<?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 é um enum de espaços de trabalho para os quais o engine empacota um perfil. Todos os casos com perfil são espaços de trabalho RGB de três componentes; DeviceRGB é o sentinela padrão e não emite output intent. Não há perfil de destino CMYK empacotado:

  • DeviceRGB — o padrão. Nenhum output intent é emitido: nenhuma condição de saída em nível de PDF é declarada, e o pipeline PDF/A (se ativo) mantém o controle exclusivo do array /OutputIntents. Use isto quando você não quer declarar um. (Conteúdo PDF DeviceRGB sem output intent é dependente de dispositivo — ele não é um sRGB declarado.)
  • Srgb — emite um dicionário de output intent incorporando o sRGB.icc empacotado, com o identificador de condição padrão sRGB IEC61966-2.1.
  • DisplayP3, Rec2020, A98RGB, ProphotoRGB — espaços de trabalho RGB de gamut amplo, cada um incorporando seu perfil ICC empacotado sob um identificador de condição customizado (NextPDF wide-gamut …).

Qualquer caso que não seja DeviceRGB faz o writer emitir um dicionário de output intent referenciando o stream ICCBased incorporado (com sua contagem de componentes /N 3). A ISO 32000-2 §14.11.5 define o dicionário de output intent; §8.6.5.5 define o espaço de cor ICCBased que carrega o perfil incorporado. No engine atual, esse dicionário é escrito com o subtipo de output intent PDF/X /GTS_PDFX independentemente de qual perfil empacotado você escolher (o caminho de arquivamento PDF/A usa seu próprio subtipo /GTS_PDFA1 e é emitido separadamente).

A ressalva importante: como todos os perfis empacotados são RGB, isto declara o espaço de trabalho RGB do documento e a intenção de visualização — não é um perfil de destino CMYK, e não transforma nada em CMYK. O engine não permite que você forneça um ICC de destino CMYK customizado por meio de withOutputColorProfile(). Um verdadeiro output intent CMYK de impressão/PDF-X requer um fluxo que incorpore o seu próprio perfil ICC CMYK como destino; para um output intent de arquivamento conectado ao mesmo array /OutputIntents, consulte Saída PDF/A-4.

  • Device CMYK — o padrão para qualquer arte destinada a uma impressora de processo. Especifique suas cores em CMYK desde o início para que nenhum chute de RGB→CMYK aconteça mais adiante.
  • Spot / Separation — cores de marca que precisam acertar uma tinta exata, além de chapas fora de processo (verniz, branco, metálico, faca de corte, foil). Registre uma vez, pinte em qualquer tom.
  • Output intent — defina-o quando você quer que o arquivo seja autodescritivo sobre sua condição de trabalho/saída RGB, ou quando um consumidor (um visualizador, um RIP com gerenciamento de cor, um validador) espera uma condição de saída declarada. Os perfis empacotados declaram apenas uma condição de trabalho/saída RGB; eles não declaram uma verdadeira condição de impressão CMYK / PDF/X.
  • Os componentes CMYK são porcentagens (0–100), não 0–1. Os métodos de documento …Cmyk e Color::cmyk() recebem cada canal como uma porcentagem 0–100 e dividem por 100 ao escrever o operador; o operando do content stream é o valor normalizado 0.0–1.0. Passe 100 para tinta cheia, não 1.0 (que o engine trataria como 1% de tinta).
  • Registre antes de selecionar uma spot. setSpotFillColor() / setSpotDrawColor() lançam se o nome nunca foi registrado. Os nomes casam exatamente, incluindo maiúsculas/minúsculas e espaços.
  • O estado de cor persiste. Uma cor CMYK ou spot permanece em vigor até você mudá-la. Redefina antes de um bloco não relacionado.
  • O fallback CMYK é uma aproximação. O tint transform de Separation existe para que renderizadores sem suporte a spot possam mostrar algo; ele não é a saída de impressão. A tinta real é o que a chapa nomeada produz.
  • Um output intent é uma declaração, não uma conversão. Declarar OutputColorProfile::Srgb não transforma suas cores em sRGB; ele declara a condição pretendida. A precisão de cor é responsabilidade sua mais acima no fluxo.

Cada seleção de cor é um único operador de content stream; uma spot também escreve um recurso Separation por tinta registrada. Um perfil de output intent incorporado é escrito uma vez por documento. Todos os caminhos ficam bem dentro do orçamento de 2000 ms / 64 MB.

Esta receita emite apenas as cores e o perfil que o seu código especifica. Ela não analisa nenhuma entrada não confiável e não faz nenhum acesso de rede. Se nomes de colorante ou componentes CMYK vierem de dados externos, valide-os: limite os componentes a 0–100 e rejeite caracteres de controle em nomes de spot (um byte NUL em um nome Separation é rejeitado pelo engine).

AfirmaçãoSpecCláusula
k e K são os operadores de cor que definem a cor não estrocada / estrocada DeviceCMYK.ISO 32000-2§8.6.8
DeviceCMYK é o espaço de cor de processo subtrativo de quatro componentes.ISO 32000-2§8.6.4.4
Um espaço de cor Separation nomeia um colorante cujo tom mapeia para um espaço alternativo via um tint transform.ISO 32000-2§8.6.6.4
Um espaço de cor ICCBased incorpora um stream de perfil ICC com uma contagem de componentes /N.ISO 32000-2§8.6.5.5
Um output intent declara a condição de produção alvo; GTS_PDFX nomeia o subtipo de impressão.ISO 32000-2§14.11.5

Perfil de reprodutibilidade — structural. A emissão de cor não tem entropia própria, mas todo documento salvo carrega um /ID de trailer e átomos de data, e um stream ICC incorporado é estável em bytes apenas para um perfil empacotado fixo. A afirmação suportada é a igualdade estrutural após a normalização com qpdf. Esta receita descreve como o NextPDF produz a estrutura; ela não afirma conformidade geral com a ISO 32000-2.

Não se aplica. Device CMYK, cor spot/Separation e a declaração de output intent são capacidades da Core sem nenhum gate Premium. A Core suporta a declaração de output intent RGB empacotada mostrada aqui; fluxos com ICC de condição de impressão CMYK customizado não são reivindicados por esta receita.