Техническая статья

Преобразование PDF в одно цветовое пространство в Delphi

RecolorDocument переводит весь PDF в одно цветовое пространство, а RecolorPage делает то же для отдельной страницы. Оба принимают 1 для серого, 2 для RGB и 3 для CMYK и возвращают, сколько цветов было преобразовано. Геометрия, текст и изображения остаются точно там, где были; меняется только цвет

Это та операция, что нужна перед отправкой работы в печатную машину, ожидающую одно пространство, или когда цветной документ должен стать серым без повторной генерации. Альтернатива — пересборка документа из исходных данных в целевом пространстве — доступна, только если исходные данные всё ещё у вас, а для всего полученного извне их нет

Что преобразуется и в каком порядке

Сначала цветовые операторы: заливки и обводки, которые страница задаёт при отрисовке. Цвет, уже находящийся в целевом пространстве, остаётся нетронутым, поэтому страница, чьи цвета менять не нужно, сохраняет исходные байты, а не переписывается на идентичные значения. Это свойство важнее, чем кажется на больших документах, потому что нетронутые объекты остаются нетронутыми и в файле

Затем идут изображения, и это та часть, что прежде отсутствовала. Документ, переведённый в серое с преобразованием только операторов, по-прежнему показывал цветные картинки на серых страницах, что хуже любого из крайних вариантов. Изображение преобразуется, когда оно несёт восемь бит на компонент, имеет аппаратное цветовое пространство и либо не сжато, либо использует обычный Flate

Индексные изображения преобразуются через их цветовую таблицу: палитра переводится, а каждый сэмпл сохраняет индекс, который уже имел. Это покрывает палитровые изображения, в которые обычно сохраняется скриншот или диаграмма, и преобразует их независимо от того, как упакованы или сжаты их сэмплы, потому что сами сэмплы не меняются

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;

Почему JPEG остаётся нетронутым?

Потому что преобразование его цветов означало бы перекодирование, а перекодирование — это другая операция с другими последствиями. JPEG или факсимильное изображение сохраняет собственные байты: декодирование, преобразование и рекомпрессия изменили бы сами данные изображения, внесли второе поколение артефактов сжатия с потерями и изменили размер файла способами, о которых вызывающий код не просил

Мягкие маски и трафаретные маски остаются нетронутыми по другой причине. Обе читаются как покрытие, а не как цвет, и преобразование одной из них привело бы к тому, что страница показывала бы маску как картинку — маска прозрачности, отрисованая как серое изображение поверх содержимого, форму которого она должна была определять. Оставить их нетронутыми — не ограничение, которое надо обходить; это правильный результат

Цвета, заданные через пространство ICCBased, Separation, Indexed или Pattern, на уровне операторов также остаются как есть. Преобразование их без чтения профиля изменило бы внешний вид страницы, а не сохранило его, а проход перекраски, всё обещание которого — сохранение, не может пускаться в догадки о профилях

Градиенты преобразуются вместе с точками за ними

Градиент — это цветовое пространство плюс функция, производящая в нём цвета, и преобразование одного без другого даёт бессмыслицу: преобразованный градиент, чьи точки остались позади, читается как канал, принятый за уровень серого, что на странице выглядит как полоса совершенно неправильного цвета. Цветовое пространство градиента и точки за ним перемещаются вместе

Градиенты находятся там, где бы они ни жили: заданные как самостоятельный объект, записанные внутри шаблона, который их рисует, или расположенные в затеночных ресурсах страницы. Такое покрытие важно, потому что инструменты дизайна распределяют их по-разному, а конвертер, обрабатывающий лишь одно размещение, оставил бы документ наполовину преобразованным без очевидной закономерности в провалах

Два типа намеренно остаются как есть. Градиент, построенный из выборочной или PostScript-функции, сохраняет собственное определение, как и типы mesh, которые несут свои цвета в потоке, а не в функции. Переписывание любого из них — операция, отличная от преобразования цвета, и молчаливое выполнение её внутри прохода перекраски было бы неожиданностью

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

Где перекраска уместна перед подачей в печать

Используйте её как шаг нормализации, а не как управление цветом. Перекраска преобразует значения между аппаратными пространствами; она не применяет ICC-профиль, не учитывает интент воспроизведения и не имитирует условия печатной машины. Для работы, которая должна попасть в контрактный цветопробный оттиск, ответ — управляемый профилем рабочий процесс, а перекраска — в лучшем случае шаг, приводящий всё в одно пространство

Где она себя окупает — так это в обычной производственной задаче: подача, которая должна быть серой и приходит с RGB-логотипом, внутренний документ, который не должен печататься в цвете, пакет файлов, который должен быть в одном пространстве, прежде чем шаг предпечатной подготовки примет его. Дополняйте её проверкой: заметки о профилировании PDF/A и PDF/UA и о верстаке соответствия и подписания описывают, как прогнать вердикт в рамках того же задания

Если документ требует также исследования векторной графики, а не преобразования, разбор векторной графики, шейдеров и градиентов описывает, как эти объекты строятся изначально — это полезный контекст для понимания, чего проход перекраски может и чего не может достичь

PDFlibPas — нативная Pascal-библиотека PDF для Delphi, C++Builder и Lazarus без внешнего рантайма, поэтому шаг нормализации цвета выполняется внутри вашей службы, а не через вызов внешнего конвертера — см. страницу продукта PDFlibPas для полного API обработки документов