RecolorDocument move um PDF inteiro para um único espaço de cor, e RecolorPage faz o mesmo para uma única página. Ambas recebem 1 para cinzento, 2 para RGB e 3 para CMYK, e devolvem quantas cores foram convertidas. A geometria, o texto e as imagens ficam exatamente onde estavam; só a cor muda
Esta é a operação pretendida antes de enviar trabalho para uma impressora que espera um único espaço, ou quando um documento a cor tem de se tornar um documento a cinzento sem ser regenerado. A alternativa — reconstruir o documento a partir dos dados de origem no espaço de destino — só está disponível quando ainda tem os dados de origem, o que para qualquer coisa recebida do exterior não acontece
O que é convertido, e em que ordem
Primeiro os operadores de cor: os preenchimentos e os traços que uma página define ao desenhar. Uma cor já no espaço de destino é deixada em paz, pelo que uma página cujas cores não precisam de mudança mantém os seus bytes originais em vez de ser reescrita para valores idênticos. Essa propriedade importa mais do que parece num documento grande, porque os objetos intocados ficam intocados no ficheiro
De seguida vêm as imagens, e são a parte que costumava estar em falta. Um documento tornado cinzento apenas com os operadores convertidos continuava a mostrar imagens a cor em páginas a cinzento, o que é pior do que qualquer dos extremos. Uma imagem é convertida quando transporta oito bits por componente, um espaço de cor de dispositivo, e ou sem compressão ou Flate simples
As imagens indexadas convertem através da sua tabela de cores: a paleta é convertida e cada amostra mantém o índice que já tinha. Isso cobre as imagens em paleta em que uma captura de ecrã ou um gráfico costumam ser guardadas, e converte-as seja qual for a forma como as amostras são empacotadas ou comprimidas, porque as amostras nunca mudam
var
Lib: TPDFlib;
Converted: Integer;
begin
Lib := TPDFlib.Create;
try
Lib.LoadFromFile('brochure.pdf', '');
Converted := Lib.RecolorDocument(1); // 1 grey, 2 RGB, 3 CMYK
Log(Format('%d colours converted', [Converted]));
Lib.SaveToFile('brochure-grey.pdf');
finally
Lib.Free;
end;
end;
Porque razão é que um JPEG é deixado em paz?
Porque converter as suas cores significaria recodificá-lo, e recodificar é uma operação diferente com consequências diferentes. Uma imagem JPEG ou fax mantém os seus próprios bytes: descodificar, converter e recomprimir mudaria os dados da própria imagem, introduziria uma segunda geração de artefactos com perdas, e alteraria o tamanho do ficheiro de formas que o chamador não pediu
As máscaras suaves e as máscaras de estêncil são deixadas em paz por uma razão diferente. Ambas são lidas como cobertura e não como cor, e converter uma delas deixaria a página a mostrar a máscara como uma imagem — uma máscara de transparência renderizada como arte a cinzento por cima do conteúdo que se supunha modelar. Deixá-las não é uma limitação a contornar; é o resultado correto
As cores definidas através de um espaço ICCBased, Separation, Indexed ou Pattern também são deixadas como estão ao nível do operador. Convertê-las sem ler o seu perfil mudaria o aspeto da página em vez de o preservar, e uma passagem de recoloração cuja promessa toda é a preservação não pode começar a adivinhar perfis
Os gradientes convertem com as paragens que estão por trás
Um gradiente é um espaço de cor mais uma função que produz cores nele, e converter um sem o outro produz nonsense — um gradiente convertido cujas paragens fossem deixadas para trás lê-se como um canal confundido com um nível de cinzento, o que numa página se parece com uma faixa da cor errada. O espaço de cor do gradiente e as paragens por trás dele movem-se em conjunto
Os gradientes são encontrados onde quer que vivam: como um objeto próprio, escritos dentro do padrão que os pinta, ou sentados nos recursos de sombreado de uma página. Essa cobertura importa porque as ferramentas de desenho os distribuem de forma diferente, e um conversor que só tratasse de uma colocação deixaria um documento meio convertido sem qualquer padrão evidente nas falhas
Dois tipos são deliberadamente deixados como estão. Um gradiente construído a partir de uma função amostrada ou PostScript mantém a sua própria definição, e o mesmo acontece com os tipos mesh, que transportam as suas cores num stream em vez de numa função. Reescrever qualquer um deles é uma operação diferente de converter uma cor, e fazê-lo silenciosamente dentro de uma passagem de recoloração seria uma surpresa
// Convert a single page - useful when only the cover needs to change
Lib.SelectPage(1);
Lib.RecolorPage(3); // this page to CMYK
Lib.SaveToFile('cover-cmyk.pdf');
Onde a recoloração se encaixa antes da submissão para impressão
Use-a como um passo de normalização, não como gestão de cor. A recoloração converte valores entre espaços de dispositivo; não aplica um perfil ICC, não honra uma intenção de renderização nem simula uma condição de impressão. Para um trabalho que tem de atingir uma prova contratual, o fluxo orientado por perfil é a resposta e a recoloração é no máximo o passo que põe tudo num único espaço primeiro
Onde ganha o seu lugar é no problema de produção comum: uma submissão que tem de ser a cinzento e chega com um logótipo RGB, um documento interno que não pode ser impresso a cor, um lote de ficheiros que tem de estar num único espaço antes de um passo de preflight os aceitar. Junte-lhe uma verificação — as notas sobre preflight PDF/A e PDF/UA e sobre a bancada de conformidade e assinatura cobrem a execução do veredito como parte do mesmo trabalho
Se o documento também precisar de ter a sua arte vetorial examinada em vez de convertida, o guia de gráficos vetoriais, sombreadores e gradientes aborda como esses objetos são construídos em primeiro lugar, o que é contexto útil para perceber o que uma passagem de recoloração consegue e não consegue alcançar
O PDFlibPas é uma biblioteca PDF nativa em Pascal para Delphi, C++Builder e Lazarus sem qualquer runtime externo, pelo que um passo de normalização de cor corre dentro do seu próprio serviço em vez de invocar um conversor — veja a página do produto PDFlibPas para a API completa de processamento de documentos