Home » Уменьшение размера PDF файла в Linux
Уменьшение размера PDF файла в Linux

Уменьшение размера PDF файла в Linux

Пока разбираешься с логами на сервере, анализируешь конфигурации или готовишь отчёты, то и дело натыкаешься на толстые PDF-файлы. Конечно, можно закрыть на это глаза, но когда дело доходит до бэкапов, автоматизации или работы с большими объёмами документов, размер имеет значение. Особенно если твои VPS-ки не резиновые по дисковому пространству.

Сегодня разберём, как правильно сжимать PDF в Linux без потери функциональности. Покажу несколько способов – от простых однострочников до продвинутых скриптов для автоматизации. Плюс затронем подводные камни, которые могут поджидать в продакшене.

Как это работает под капотом

PDF – это не просто картинки в обёртке. Внутри творится много интересного: векторная графика, шрифты, метаданные, JavaScript (да-да!), сжатие объектов и прочие радости. Когда мы говорим о сжатии PDF, то работаем с несколькими направлениями:

  • Компрессия изображений – самый очевидный способ, обычно даёт максимальный эффект
  • Удаление метаданных – убираем лишнюю информацию о создании файла
  • Оптимизация шрифтов – встроенные шрифты можно заменить на системные
  • Дедупликация объектов – избавляемся от дублирующихся элементов
  • Перепаковка структуры – оптимизируем внутреннюю организацию данных

Большинство утилит в Linux работают с Ghostscript в качестве движка, который умеет все эти трюки.

Ghostscript: швейцарский нож для PDF

Начнём с классики. Ghostscript есть практически в любом дистрибутиве, и если нет – доставляется одной командой:

# Ubuntu/Debian
sudo apt install ghostscript

# CentOS/RHEL/Fedora
sudo yum install ghostscript
# или для новых версий
sudo dnf install ghostscript

# Arch Linux
sudo pacman -S ghostscript

Базовая команда для сжатия выглядит так:

gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.pdf input.pdf

Но лучше сразу разобраться с параметрами, чтобы не получить кашу вместо документа:

Настройка Качество Размер Применение
/screen Низкое (72 dpi) Минимальный Предпросмотр, веб
/ebook Среднее (150 dpi) Средний Чтение на устройствах
/printer Высокое (300 dpi) Большой Печать, архивы
/prepress Максимальное (300+ dpi) Максимальный Полиграфия

Для серверных задач обычно хватает `/ebook` – золотая середина между качеством и размером.

Практические примеры и кейсы

Давайте на конкретных примерах посмотрим, что получается:

# Стандартное сжатие для архивирования
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook \
   -dNOPAUSE -dQUIET -dBATCH -sOutputFile=compressed.pdf original.pdf

# Агрессивное сжатие для веб-превью
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen \
   -dNOPAUSE -dQUIET -dBATCH -sOutputFile=preview.pdf original.pdf

# Продвинутая настройка с ручным контролем качества
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 \
   -dNOPAUSE -dQUIET -dBATCH \
   -dColorImageResolution=150 \
   -dGrayImageResolution=150 \
   -dMonoImageResolution=300 \
   -sOutputFile=custom.pdf original.pdf

Положительный кейс: PDF-отчёт с графиками размером 25MB сжался до 3MB с настройкой `/ebook`, при этом графики остались читаемыми.

Отрицательный кейс: Документ с мелким текстом после `/screen` стал нечитаемым. Пришлось использовать `/printer` и смириться с размером.

qpdf: современный подход к оптимизации

Если Ghostscript – это кувалда, то qpdf – скальпель. Особенно хорош для структурной оптимизации без потери качества:

# Установка
sudo apt install qpdf  # Ubuntu/Debian
sudo dnf install qpdf  # Fedora

# Базовая оптимизация
qpdf --optimize-images --compress-streams=y input.pdf output.pdf

# Линеаризация для веб (быстрая загрузка)
qpdf --linearize input.pdf output.pdf

# Удаление метаданных и аннотаций
qpdf --suppress-recovery --remove-unreferenced-resources input.pdf output.pdf

qpdf отлично подходит для тонкой настройки и не ломает сложные PDF с формами или JavaScript.

Скрипт для массовой обработки

Написал универсальный скрипт для обработки папок с PDF. Сохраняешь в `pdf_compress.sh` и радуешься:

#!/bin/bash

# Настройки
QUALITY=${1:-/ebook}
INPUT_DIR=${2:-./}
OUTPUT_DIR=${3:-./compressed}

# Проверяем наличие Ghostscript
if ! command -v gs &> /dev/null; then
    echo "Ghostscript не найден. Установите: sudo apt install ghostscript"
    exit 1
fi

# Создаём выходную папку
mkdir -p "$OUTPUT_DIR"

# Функция сжатия
compress_pdf() {
    local input_file="$1"
    local output_file="$2"
    local original_size=$(stat -c%s "$input_file")
    
    gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 \
       -dPDFSETTINGS=$QUALITY -dNOPAUSE -dQUIET -dBATCH \
       -sOutputFile="$output_file" "$input_file"
    
    local compressed_size=$(stat -c%s "$output_file")
    local ratio=$(echo "scale=1; $compressed_size * 100 / $original_size" | bc -l)
    
    echo "$(basename "$input_file"): $(($original_size/1024))KB -> $(($compressed_size/1024))KB ($ratio%)"
}

# Обработка всех PDF в папке
find "$INPUT_DIR" -name "*.pdf" -type f | while read -r pdf_file; do
    filename=$(basename "$pdf_file")
    output_file="$OUTPUT_DIR/$filename"
    
    if [[ -f "$output_file" ]]; then
        echo "Пропускаем $filename (уже существует)"
        continue
    fi
    
    compress_pdf "$pdf_file" "$output_file"
done

echo "Обработка завершена. Результаты в: $OUTPUT_DIR"

Использование:

# Сжать все PDF в текущей папке
./pdf_compress.sh

# Задать качество и папки
./pdf_compress.sh /screen /path/to/input /path/to/output

# Сделать исполняемым
chmod +x pdf_compress.sh

Альтернативы и специализированные утилиты

Кроме классических решений, есть несколько интересных альтернатив:

  • pdftk – мощный инструмент для работы с PDF, умеет сжимать и много чего ещё
  • mutool (из пакета mupdf-tools) – быстрый и эффективный для простых задач
  • cpdf – коммерческая утилита с отличными алгоритмами сжатия
  • ocrmypdf – если нужно одновременно сжать и добавить OCR

Пример с mutool:

# Установка
sudo apt install mupdf-tools

# Сжатие
mutool clean -ggggif input.pdf output.pdf

Особенно хорош для простых документов без сложной графики.

Автоматизация и интеграция

Сжатие PDF можно легко интегрировать в существующие workflow. Несколько идей:

Systemd watcher для автоматического сжатия:

# /etc/systemd/system/pdf-watcher.service
[Unit]
Description=PDF Compression Watcher
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/pdf_compress.sh /ebook /var/spool/pdf /var/spool/pdf/compressed
Restart=always
User=nobody

[Install]
WantedBy=multi-user.target

Интеграция с логrotate:

/var/log/reports/*.pdf {
    daily
    rotate 30
    compress
    delaycompress
    postrotate
        find /var/log/reports -name "*.pdf" -mtime +1 -exec /usr/local/bin/pdf_compress.sh {} \;
    endscript
}

Хук для Git (если храните документацию в репозитории):

#!/bin/bash
# .git/hooks/pre-commit

# Сжимаем PDF перед коммитом
find . -name "*.pdf" -newer .git/COMMIT_EDITMSG 2>/dev/null | while read pdf; do
    gs -sDEVICE=pdfwrite -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH \
       -sOutputFile="${pdf}.tmp" "$pdf" && mv "${pdf}.tmp" "$pdf"
done

Мониторинг и статистика

Для серверных задач полезно отслеживать эффективность сжатия. Простой скрипт для статистики:

#!/bin/bash
# pdf_stats.sh

total_original=0
total_compressed=0
files_processed=0

for original in "$1"/*.pdf; do
    compressed="$2/$(basename "$original")"
    
    if [[ -f "$compressed" ]]; then
        orig_size=$(stat -c%s "$original")
        comp_size=$(stat -c%s "$compressed")
        
        total_original=$((total_original + orig_size))
        total_compressed=$((total_compressed + comp_size))
        files_processed=$((files_processed + 1))
    fi
done

if [[ $files_processed -gt 0 ]]; then
    echo "Обработано файлов: $files_processed"
    echo "Размер до: $(($total_original/1024/1024))MB"
    echo "Размер после: $(($total_compressed/1024/1024))MB"
    echo "Экономия: $(($total_original - $total_compressed))"
    echo "Процент сжатия: $(echo "scale=1; $total_compressed * 100 / $total_original" | bc -l)%"
fi

Подводные камни и рекомендации

Несколько важных моментов, которые стоит учесть:

  • Всегда делайте бэкап оригинала – сжатие необратимо
  • Тестируйте на критичных документах – некоторые PDF могут сломаться
  • Учитывайте лицензии – qpdf Apache 2.0, Ghostscript AGPL
  • Следите за производительностью – сжатие CPU-интенсивно

Для продакшена рекомендую настроить очередь обработки, чтобы не нагружать сервер:

# Простая очередь через at
echo "/usr/local/bin/pdf_compress.sh /ebook /tmp/input /tmp/output" | at now + 1 minute

Интересные факты и нестандартные применения

PDF-сжатие можно использовать не только для экономии места:

  • Анонимизация – удаление метаданных через `-dPrinted=false -dShowAds=false`
  • Стандартизация – приведение документов к единому формату
  • Оптимизация для CDN – уменьшение времени доставки контента
  • Форензика – иногда в сжатом PDF всплывают скрытые объекты

Забавный факт: Ghostscript может извлекать изображения из PDF. Полезно для анализа:

gs -sDEVICE=jpeg -o page-%03d.jpg -r150 input.pdf

Производительность и сравнение

Тестировал на VPS с 2CPU/4GB RAM. Результаты обработки 100 PDF файлов (~500MB):

Утилита Время выполнения Итоговый размер Совместимость
Ghostscript (/ebook) 3м 45с 125MB Отлично
qpdf 1м 20с 180MB Превосходно
mutool 2м 10с 140MB Хорошо

Для высоких нагрузок имеет смысл рассмотреть выделенный сервер – там можно развернуть полноценную очередь обработки.

Заключение и рекомендации

Сжатие PDF в Linux – это просто, если знать правильные инструменты. Для большинства задач хватает Ghostscript с настройкой `/ebook`. Если нужна тонкая настройка или работа с формами – берите qpdf.

Рекомендую такой подход:

  • Разработка/тестирование – qpdf для бережного сжатия
  • Архивирование – Ghostscript `/ebook` для баланса размера и качества
  • Веб-превью – Ghostscript `/screen` для минимального размера
  • Массовая обработка – скрипты на базе Ghostscript

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


В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.

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

Leave a reply

Your email address will not be published. Required fields are marked