Що насправді відбувається під час стиснення PDF
PDF123 Compress перестискає потоки й пакує об’єкти через qpdf, але не зменшує роздільність зображень, не перекодовує растр у JPEG із втратами й не субсетує шрифти. Лінеаризація майже не змінює розмір файлу.

Два PDF можуть виглядати на екрані однаково й різнитися на три порядки: 50 КБ проти 50 МБ. Розрив майже ніколи не в текстових операторах. У договорі на двадцять сторінок ці оператори зазвичай займають кілька десятків кілобайтів, а все інше — це відліки зображень, повністю вбудований шрифт і те, наскільки щільно спаковані потоки та об’єкти.
Звідси висновок, який варто зробити одразу: «стиснути PDF» — це не одна дія, а чотири. Вони зменшують різне й коштують по-різному, а якщо змішати їх в одне, досвід виходить суперечливий: файл стиснули, а він не зменшився, або зменшився, але сторінки попливли.
Розмір задають зображення, шрифти й пакування
Більшість випадків «чому цей PDF такий величезний?» починаються зі скану або фотографії високої роздільності, вбудованих у початковому розмірі. Арифметику варто зробити один раз: сторінка формату Letter 8,5 × 11 дюйма за 300 DPI — це приблизно 2550 × 3300 пікселів, а за трьох байтів на піксель виходить близько 25 МБ без стиснення. Двадцять таких сторінок часто важать 60–80 МБ ще до того, як хтось візьметься за стиснення.
Друге джерело — шрифти. PDF може вбудувати цілу шрифтову програму, щоб текст однаково відображався на будь-якій машині, і ціна залежить від розміру таблиць гліфів, а не від того, скільки тексту реально прочитано. Тому субсетування шрифтів — окремий важіль розміру.
Третє — саме пакування. Той самий вміст можна зберігати з марнотратними налаштуваннями стиснення, а об’єкти можуть бути розкидані файлом, кожен зі своїми службовими витратами. Це не змінює жодного пікселя чи гліфа, і саме до цієї частини дістається перестиснення потоків.
«Стиснення» — це чотири різні важелі
На розмір діють чотири важелі; вони працюють на різних рівнях, а їхня ціна майже не перетинається. Вибір не того — найчастіша причина, чому стиснення ніби нічого не робить.
| Важіль | Що зачіпає | Виграш у розмірі | Ціна |
|---|---|---|---|
| Перестиснення потоків і об’єктні потоки | Як стиснуто потоки вмісту, як зберігаються й пакуються об’єкти | Залежить від того, наскільки пухким був оригінал | Вигляд сторінок не змінюється |
| Зменшення роздільності зображень | Кількість пікселів, тобто роздільність | Великий | Роздільність знижується назавжди |
| Перекодування зображень із втратами | Байтове подання растра | Великий | Якість зображення знижується |
| Субсетування шрифтів | Вбудовані таблиці гліфів | Помірний | Невикористані гліфи більше не редагуються |
| Лінеаризація | Порядок об’єктів | Майже нульовий | Натомість дає час завантаження першої сторінки |
Перші чотири рядки огульно називають «стисненням», але лише перший не торкається вмісту. У нього ж найлегше недооцінити віддачу: у скані, чий розмір — це переважно необроблені відліки зображення, йому майже нічого усувати, а суттєво скоротити його могли б зменшення роздільності та перекодування з втратами, ціною безповоротної втрати роздільності й якості.
Який із чотирьох важелів використовує PDF123 Compress
Стиснути PDF (POST /api/v1/misc/compress-pdf) робить лише перший рядок. Він запускає qpdf зі стисненням нестиснених потоків (--compress-streams=y), повторним проходом по вже стиснених потоках Flate (--recompress-flate) і пакуванням об’єктів в об’єктні потоки (--object-streams=generate).
Він не зменшує роздільність зображень, не перекодовує растр у JPEG нижчої якості й не субсетує шрифти. Сторінки мають виглядати так само, а економія надходить від перестиснення Flate та пакування об’єктів.
Умова відмови заслуговує такої ж ясності. Якщо розмір файлу — це переважно вже стиснені дані JPEG, Flate нема чого стискати, бо ці байти лежать поза дією трьох ключів вище. Тому пакет сканів може повернутися меншим лише на кілька відсотків, тоді як текстовий PDF схожого розміру виграє помітно більше.
Зворотний шлях — Розпакувати PDF: він розгортає потоки для огляду (--qdf, об’єктні потоки вимкнено) і так само не змінює вигляду сторінок.
Коли потрібен інший шлях, а не Compress
| Що вам потрібно | Який шлях обрати |
|---|---|
| Ідентичний вигляд, лише прибрати накладні витрати пакування | Compress |
| Пакет сканів справді завеликий, і втрата якості прийнятна | Зменшення роздільності або перекодування з втратами, але не цей Compress |
| Потрібна редагованість, але наступний символ не друкується | Інші налаштування експорту або вихідний файл, див. субсетування шрифтів |
| Браузер має показати першу сторінку раніше | Лінеаризація вирішує першу отрисовку, а не розмір |
| Файл узагалі не відкривається | Repair, це структурна проблема, а не проблема розміру |
В останньому рядку ховається пастка: Лінеаризувати PDF тут не окрема реалізація, а псевдонім Compress. Обидва вказують на ту саму операцію, канонічний id — misc/compress-pdf, а linearize-pdf лише псевдонім; портал для цього інструмента завжди надсилає linearize=true та optimizeLevel=1, сервер не читає жодного з цих полів, а qpdf ніколи не отримує --linearize. Лінеаризує файл та операція, яка його шифрує, — Protect.
Отже, якщо вам потрібен той самий вигляд у меншому файлі, Compress — це вся відповідь. Якщо потрібне зменшення зображень із втратами або субсетування шрифтів, цей шлях — не той важіль. Файл повертається одразу, без облікового запису. А щоб побачити, де насправді живуть об’єкти, потоки й таблиця перехресних посилань, читайте Що всередині PDF.