Раздражающая ситуация
Вы бывали в такой ситуации. Коллега присылает вам PDF-отчёт на 50 МБ. Вы считаете его слишком большим для отправки по электронной почте, поэтому кладёте его в 7-Zip, выкручиваете сжатие на «ультра» и ждёте. Результат? Архив на 49 МБ. Вы отправляете его всё равно, получатель распаковывает его, а файл по-прежнему 50 МБ — ни одного байта меньше.
Это не случайность. Возьмите уже сжатый MP4, JPG или PDF, засуньте его в ZIP-файл, и размер едва сдвинется. Но прогоните тот же 7-Zip по папке с сырыми TXT-, BMP- или CSV-файлами, и архив может сжаться до десятой части исходного размера.
Почему такая разница? Ответ кроется в различии, которое большинству людей так и не удаётся усвоить: архивное сжатие и сжатие содержимого — фундаментально разные операции. Поймите разницу, и вы перестанете тратить время на архивирование файлов, которые отказываются уменьшаться, — и начнёте тянуться к нужному инструменту в нужной ситуации.
Архивное сжатие: искусство контейнера
Архивное сжатие работает на уровне контейнера. Оно делает две вещи: объединяет несколько файлов в один контейнер и применяет алгоритм сжатия без потерь, чтобы устранить статистическую избыточность в потоке байтов.
Знакомые архивные форматы — ZIP, 7Z, TAR.GZ, RAR — все под капотом опираются на похожие алгоритмы. ZIP по умолчанию использует DEFLATE, который объединяет LZ77 и кодирование Хаффмана. LZ77 находит повторяющиеся последовательности байтов и заменяет их ссылками «расстояние-длина»; кодирование Хаффмана затем назначает более частым символам более короткие двоичные коды, а более редким — более длинные. Формат 7Z от 7-Zip по умолчанию использует LZMA, который расширяет LZ77 диапазонным кодированием и поддерживает гораздо более крупные окна словаря, обычно достигая лучших коэффициентов, чем DEFLATE.
Вот ключевой момент: архивное сжатие никогда не изменяет содержимое файлов. Оно относится к каждому файлу как к непрозрачному потоку байтов и охотится за статистическими закономерностями внутри этого потока. Когда вы распаковываете ZIP-архив, файлы возвращаются идентичными оригиналам байт-в-байт — ни один пиксель не меняется.
Это объясняет сценарий из начала. PDF уже сжал свои потоки изображений и шрифтов с помощью DEFLATE внутренне. JPG сам по себе сжатый формат. MP4 использует H.264 или H.265 для сжатия видеокадров. Эти файлы уже избавились от избыточности, поэтому архивным алгоритмам почти не на чем работать. Напротив, BMP-битмапы, несжатый звук WAV и текстовые CSV-файлы полны сжимаемых повторов — именно там архивное сжатие блистает.
Где архивное сжатие по-настоящему преуспевает, так это в устранении избыточности между несколькими файлами. Допустим, папка содержит 100 скриншотов, каждый с одним и тем же водяным знаком-логотипом и похожей панелью инструментов. Большой словарь LZMA способен распознать эти межфайловые повторы и добиться гораздо лучшего сжатия, чем при сжатии каждого файла по отдельности. Именно поэтому объединение файлов в один архив эффективнее, чем сжимать их по одному.
Здесь стоит разобраться в роли словаря сжатия. И DEFLATE, и LZMA поддерживают скользящее окно недавно увиденных данных — словарь, — с которым сопоставляются новые байты. Окно DEFLATE фиксировано на 32 КБ, что ограничивает дальность поиска повторов. LZMA позволяет настраивать словари на 64 МБ и более, а значит, шаблон, появившийся в первом файле пакета, всё ещё может быть использован, когда он снова возникает в последнем файле. Поэтому один большой архив множества похожих файлов сжимается куда лучше, чем множество маленьких архивов: у словаря больше материала, и межфайловая избыточность захватывается. Когда каждый файл упакован отдельно, каждый архив стартует с пустым словарем, и избыточность между файлами теряется полностью.
Сжатие содержимого: перестройка изнутри
Сжатие содержимого идёт другим путём. Ему неважно, сколько у вас файлов, и ничего не объединяет. Вместо этого оно погружается во внутреннюю структуру одного файла и оптимизирует данные в соответствии с конкретным типом этого файла.
Методы полностью зависят от типа файла:
Изображения можно пересэмплировать (уменьшить оригинал 4000×3000 до 1920×1080), перекодировать (преобразовать PNG в WebP или AVIF) или уменьшить разрядность цвета (24-битное в 8-битное индексированное). 8-МБ фото с телефона при разумной корректировке разрешения и качества обычно сжимается до 500 КБ без видимой глазу разницы.
PDF можно обработать так: даунсэмплинг встроенных изображений, преобразование несжатых потоков шрифтов в подмножества CFF, удаление объектов без ссылок и слияние дубликатов XObject. 50-МБ дизайнерский документ, полный высок-resolution иллюстраций, после сжатия содержимого часто сжимается до 5-8 МБ.
PDF — особенно показательный пример, потому что по сути сами являются контейнерами. PDF хранит каждое изображение как потоковый объект, каждый шрифт как ещё один поток, а текст как закодированные потоки содержимого. Большинство производителей уже применяют DEFLATE к текстовым и шрифтовым потокам, а JPEG или DCT — к фотографическим изображениям. Поэтому PDF, отданный архивному инструменту, едва уменьшается — лёгкие плоды уже сорваны. Сжатие содержимого вместо этого заново исследует каждый поток: даунсэмплирует изображения, разрешение которых превышает потребности целевого дисплея, преобразует потоки изображений без потерь в JPEG там, где это допустимо, отбрасывает метаданные вроде встроенных миниатюр и скрытых слоёв, и сглаживает дублирующиеся форм-XObject. Результат — не более тонкая обёртка вокруг тех же данных, а фундаментально более лёгкий документ.
Шрифты можно превратить в подмножества, сохранив лишь те несколько десятков глифов, что реально используются в документе, вместо поставки целого файла шрифта с десятками тысяч символов.
Видео и аудио можно перекодировать более эффективными кодеками — например, переход с H.264 на H.265 примерно вдвое снижает битрейт при сопоставимом качестве.
У сжатия содержимого есть определяющая характеристика: оно изменяет внутренние данные файла и часто с потерями. Сжатое изображение нельзя восстановить до оригинальных пикселей; шрифт-подмножество нельзя собрать обратно в полную гарнитуру. Расплата в том, что файл становится меньше у источника — распаковка не нужна, он готов к использованию как есть.
Наглядное сравнение
Приведённая ниже диаграмма иллюстрирует фундаментальную разницу в рабочем процессе между двумя подходами:
Левый путь — это цикл «объединить–передать–распаковать–восстановить», где содержимое файлов никогда не меняется. Правый путь — однонаправленный процесс «проанализировать–оптимизировать–сгенерировать», где сам файл перестраивается.
Примеры кода: увидеть разницу
Python делает различие предельно наглядным.
Архивное сжатие с помощью zipfile
import zipfile
import os
# Архивное сжатие: объединить несколько файлов в один zip
source_files = ['report.pdf', 'photo.jpg', 'data.csv']
archive_name = 'bundle.zip'
with zipfile.ZipFile(archive_name, 'w', zipfile.ZIP_DEFLATED) as zf:
for file in source_files:
zf.write(file)
# Измерить результат
original = sum(os.path.getsize(f) for f in source_files)
packed = os.path.getsize(archive_name)
print(f"Original total: {original / 1024 / 1024:.2f} MB")
print(f"Archive size: {packed / 1024 / 1024:.2f} MB")
print(f"Ratio: {packed / original * 100:.1f}%")
# Типичный вывод (файлы уже в сжатых форматах):
# Original total: 58.30 MB
# Archive size: 57.10 MB
# Ratio: 97.9%
Обратите внимание на коэффициент — почти без изменений. Поскольку эти файлы уже в сжатых форматах, архивное сжатие бессильно.
Сжатие содержимого с помощью PIL
from PIL import Image
import os
# Сжатие содержимого: оптимизировать сами данные изображения
src = 'photo.jpg'
dst = 'photo_optimized.jpg'
img = Image.open(src)
before = os.path.getsize(src)
# Трёхстороннее сжатие содержимого
img.thumbnail((1920, 1080)) # снизить разрешение
img.save(dst, 'JPEG',
quality=75, # понизить качество
optimize=True, # оптимизировать таблицы Хаффмана
progressive=True) # прогрессивное кодирование
after = os.path.getsize(dst)
print(f"Original size: {before / 1024 / 1024:.2f} MB")
print(f"Optimized size: {after / 1024:.2f} KB")
print(f"Ratio: {after / before * 100:.1f}%")
# Типичный вывод:
# Original size: 8.20 MB
# Optimized size: 480.50 KB
# Ratio: 5.7%
Одно и то же слово — «сжатие» — однако одно превращает 58 МБ в 57 МБ, а другое 8 МБ в 480 КБ. Разрыв возникает из-за того, к чему каждое из них прикасается: первое лишь перетасовывает контейнер, второе переписывает содержимое.
Сравнение в двух словах
| Параметр | Архивное сжатие | Сжатие содержимого |
|---|---|---|
| Что делает | Объединяет файлы и устраняет избыточность | Оптимизирует внутренние данные файла |
| Объект | Контейнер файлов (многофайловый уровень) | Содержимое файла (уровень данных) |
| Метод | DEFLATE / LZMA и другие алгоритмы без потерь | Пересэмплинг / транскодирование / подмножество |
| Потери | Без потерь; полностью восстанавливается при распаковке | В основном с потерями; необратимо |
| Использование | Требует распаковки перед применением | Используется напрямую, без распаковки |
| Типичный сценарий | Передача нескольких файлов, резервное копирование | Уменьшение размера, веб-оптимизация, вложения |
| Эффективность | Зависит от избыточности; почти нулевая на предсжатых файлах | Может достигать коэффициентов сжатия 10x и выше |
Пример из практики: две судьбы 50-МБ PDF
Возьмите реальный 50-МБ PDF (несколько страниц высок-resolution сканированных изображений) и сравните:
Подход A: архивное сжатие
- Инструмент: 7-Zip, LZMA2 ультра
- Результат: 50 МБ → 49,2 МБ
- Почему: внутренние потоки изображений PDF уже сжаты в JPEG с DCTDecode, а потоки шрифтов используют FlateDecode. Архивное сжатие не находит избыточности, которую можно было бы использовать.
Подход B: сжатие содержимого
- Операции: даунсэмплинг встроенных изображений до 150 DPI, снижение качества JPEG до 75, подмножество шрифтов, удаление объектов без ссылок
- Результат: 50 МБ → 6,8 МБ
- Почему: сжатие нацелено на основную массу PDF — высок-resolution сканы. При 150 DPI чтение с экрана выглядит практически идентично, но файл в семь раз меньше.
Два «сжатия» дают разницу в 7x. Если ваша цель — отправить этот PDF по почте, ответом будет Подход B; Подход A лишь тратит усилия впустую.
Выбор правильного подхода
Имея оба инструмента под рукой, решение становится простым. Спросите себя, чего вы пытаетесь достичь:
- Нужно переместить много файлов за раз? Беритесь за архивное сжатие. Оно за один шаг объединяет, считает контрольные суммы и выжимает межфайловую избыточность — идеально для резервных копий, распространения исходного кода и передачи структур папок.
- Нужно, чтобы один файл стал меньше? Беритесь за сжатие содержимого. 50-МБ PDF, предназначенный для почты, не уменьшится в ZIP, но радикально уменьшится, как только его внутренние изображения пройдут даунсэмплинг.
- Нужно и то и другое? Сначала примените сжатие содержимого к каждому файлу, затем объедините результаты архивным сжатием. Порядок не подлежит обсуждению: оптимизация содержимого должна происходить, пока внутренности файла ещё доступны, до того как они окажутся запечатаны внутри архива.
Полезная мысленная модель: архивное сжатие снижает стоимость транспортировки, тогда как сжатие содержимого снижает стоимость хранения. Если ваш файл уже достаточно мал для транспортировки, но постоянно живёт на сервере, сжатие содержимого окупается за счёт экономии полосы пропускания при каждом скачивании. Если вы просто одноразово отправляете партию файлов, архивное сжатие — более лёгкий вариант.
Часто задаваемые вопросы
В1: Почему 7-Zip едва уменьшает PDF, JPG или MP4?
Потому что эти файлы уже являются сжатыми форматами. PDF сжимает потоки изображений и шрифтов внутренне с помощью DEFLATE; JPG сжимает данные изображения DCT-преобразованиями; MP4 сжимает видеокадры с помощью H.264/H.265. Архивные алгоритмы сталкиваются с уже выжатыми данными, поэтому статистической избыточности для удаления не остаётся. Архивное сжатие эффективно на сырых, несжатых данных — BMP, WAV, обычный текст.
В2: Сжатие содержимого теряет качество? Как сбалансировать размер и качество?
Большинство сжатий содержимого — с потерями, но степень потерь контролируема. Для изображений вы обмениваете размер на чёткость, регулируя разрешение и качество — 72-96 DPI при качестве 75 обычно достаточно для экранов, тогда как печать требует 300 DPI. Подмножество шрифтов выполняется без потерь и не влияет на отображение. Главное — подбирать уровень сжатия под конкретный случай использования, а не применять универсальную настройку.
В3: Можно ли использовать архивное сжатие и сжатие содержимого вместе?
Да, и часто так и делают. Типичный рабочий процесс: сначала применить сжатие содержимого, чтобы уменьшить каждый файл у источника, затем применить архивное сжатие, чтобы объединить меньшие файлы для передачи. Порядок важен — сначала содержимое, потом архив. Обратный порядок запирает структуру файла внутри архива, блокируя вмешательство сжатия содержимого. Сначала оптимизируйте содержимое, затем объединяйте — и вы получите преимущества обоих подходов.
Заключение
Архивное сжатие и сжатие содержимого оба носят имя «сжатие», но работают на разных слоях. Архивное сжатие действует на уровне контейнера — объединяет и устраняет избыточность без потерь, с ограниченным эффектом на уже сжатые файлы. Сжатие содержимого действует на уровне данных — перестраивает внутренности файла, часто с потерями, но уменьшает его у источника.
В следующий раз, когда обнаружите себя перед «сжатым» файлом, который не стал меньше, спросите себя: я сжимаю контейнер или содержимое? Выберите правильный слой, и сжатие наконец-то сделает своё дело.
Связанные статьи:
- Полное руководство по сжатию файлов: принципы и методы сжатия PDF/изображений/видео/документов
- Сжатие без потерь vs сжатие с потерями
Нужно сжать файлы? Попробуйте SmartSlim
На базе собственного движка сжатия на Rust поддерживается 10 основных категорий и 40+ форматов, включая PDF/изображения/видео/Office/OFD. Локальная обработка — данные не покидают вашу инфраструктуру.