Технічна стаття

Перетворення 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, також залишаються як є на рівні операторів. Перетворення їх без читання їхнього профілю змінило б вигляд сторінки, а не зберегло б його, а перепофарбування, чиє все обіцянке полягає у збереженні, не може почати вгадувати профілі

Градієнти перетворюються разом зі своїми зупинками

Градієнт — це колірний простір плюс функція, що породжує кольори в ньому, і перетворення одного без іншого дає нісенітницю — перетворений градієнт, чиї зупинки залишилися, читається як канал, помилково прийнятий за рівень сірого, що на сторінці виглядає як смуга зовсім неправильного кольору. Колірний простір градієнта та зупинки за ним переміщуються разом

Градієнти знаходять там, де вони живуть: у власному об'єкті, усередині патерну, що їх малює, або в ресурсах затінення сторінки. Це охоплення важливе, бо інструменти дизайну розподіляють їх по-різному, і конвертер, що обробляв би лише одне розташування, залишив би документ наполовину перетвореним без очевидної закономірності у відмовах

Два типи навмисно залишаються як є. Градієнт, побудований із функції sampled або 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-профіль, не враховує наміренції рендерингу й не симулює умови друкарського станка. Для роботи, що має вразити контрактний proof, рішенням є профільно-орієнтований робочий процес, а перепофарбування — щонайбільше крок, що зводить усе в один простір спочатку

Своє місце воно заробляє на звичайній виробничій проблемі: подача, що має бути сірою і приходить із RGB-логотипом; внутрішній документ, що не повинен друкуватися в кольорі; партія файлів, яку треба звести до одного простору, перш ніж крок префлайта її прийме. Поєднайте його з перевіркою — нотатки про префлайт PDF/A та PDF/UA і про верстат відповідності та підписання описують запуск вердикту як частину того ж завдання

Якщо документ також потребує векторної графіки на предмет перевірки, а не перетворення, нарис векторної графіки, шейдерів та градієнтів описує, як ці об'єкти будуються з самого початку, що є корисним контекстом для розуміння, чого перепофарбування може, а чого не може сягнути

PDFlibPas — це рідна Pascal-бібліотека PDF для Delphi, C++Builder та Lazarus без зовнішнього рутайму, тож крок нормалізації кольору працює всередині вашої власної служби, а не покликається на зовнішній конвертер — дивіться сторінку продукту PDFlibPas щодо повного API обробки документів