Skip to content
Назад к блогу
Руководства

Сжатое изображение стало больше? Три реальные причины

Средство сжатия, которое увеличивает файл, не сломано: canvas браузера перекодирует картинку в 32-битный RGBA. Мы измерили 83 реальных PNG — выросли все 83. Сожмите бесплатно в браузере.

14 мин чтения

Сжатое изображение стало больше? Три реальные причины

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

Первая причина: любой инструмент, который сжимает через элемент canvas браузера, выбрасывает color type исходного PNG и заново кодирует каждый пиксель как 32-битный RGBA. Мы прогнали через canvas.toBlob('image/png') в Chrome 151.0.0.0 все 83 PNG-карточки Open Graph этого сайта. Все 83 стали больше. Медианный рост — +76,6%, минимальный — +35,6%, максимальный — +237,2%.

Вторая причина: JPEG на входе уже сжат. Прогоните его пять раз подряд с качеством 0.8, и размер перестанет меняться после второго прохода, хотя каждый проход продолжит портить картинку.

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

Ни один из этих случаев не лечится сдвигом ползунка качества вниз. Лечение — другой формат или другой кодировщик. Те же 83 PNG, сконвертированные в WebP с качеством 0.8, уменьшились все до одного, медиана — −94,2%.

Как получены эти числа. Chrome 151.0.0.0 под управлением Playwright, macOS 26.5.2, Node v25.8.2, upng-js 2.1.0, ImageMagick. Набор из 83 файлов — это все PNG в каталоге public/og этого сайта, а не выборка из них. Еще четыре контрольных файла размером 1200×630 и 800×600 покрывают по отдельности случаи фотографии, графики, палитры и JPEG.

1. Сжатие не работает: диагностика за тридцать секунд

Найдите свою строку и переходите к разделу, на который она указывает.

Что подали на входЧто получилиПервопричинаЧитать
PNG-скриншот или графикаБольше оригиналаcanvas перекодировал его в 32-битный RGBAРаздел 2
JPEG-фотографияБольше оригиналаФайл сохранили как PNGРаздел 2
JPEG-фотографияПочти без измененийРазмер уже вышел на платоРаздел 3
PNG, уже прошедший через сжатиеБез изменений или чуть большеЗапаса не осталосьРаздел 4
Любой файлМеньше, но размыто или с искаженным цветомПотери поколений или срезанный ICC-профильРазделы 3 и 6

Строки не исключают друг друга. JPEG-фотография, брошенная в PNG-экспортер на основе canvas, попадает сразу в первые две, и именно так файл на 47 828 байт превращается в файл на 809 415 байт.

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

2. Причина первая: canvas браузера всегда пишет 32-битный RGBA

Что canvas.toBlob() делает с PNG

В прогоне через canvas нет шага сжатия. Есть декодирование и повторное кодирование, а между ними теряется всё, что не является значением пикселя.

Нарисуйте изображение на canvas — и браузер декодирует его в плоский буфер RGBA: четыре байта на пиксель. Палитра, пониженная глубина цвета и метаданные до этого буфера не доходят. Затем HTMLCanvasElement.toBlob() кодирует этот буфер с нуля. Спецификация PNG описывает шесть color types, и кодировщик волен выбрать самый дешевый из них, который способен представить изображение. Кодировщик canvas в Chrome не выбирает. Он всегда выдает color type 6.

Color type на входеЧто возвращает canvas.toBlob('image/png')
RGB (color type 2)RGBA (color type 6)
Палитра (color type 3)RGBA (color type 6)
JPEG (у него нет PNG color type)RGBA (color type 6)

Это читается прямо из байтов. 25-й байт PNG-файла — глубина цвета, 26-й — color type, оба лежат внутри чанка IHDR:

xxd -s 24 -l 2 -p suspect.png
# 0806  ->  глубина 8 бит, color type 6 (RGBA)

Все три типа входных данных выше дали depth=8 type=6. Изображение с палитрой из 64 цветов хранит один байт на пиксель плюс небольшую таблицу; после прогона оно хранит четыре байта на пиксель, а таблицы больше нет. Deflate отыгрывает часть этой разницы, но никогда не всю.

Повторить это в своем браузере можно консольным сниппетом: он выбирает файл, прогоняет его через canvas и печатает оба размера вместе с color type:

const input = document.createElement('input');
input.type = 'file';
input.accept = 'image/png,image/jpeg';
input.onchange = async () => {
  const file = input.files[0];
  const bitmap = await createImageBitmap(file);
  const canvas = document.createElement('canvas');
  canvas.width = bitmap.width;
  canvas.height = bitmap.height;
  canvas.getContext('2d').drawImage(bitmap, 0, 0);
  const blob = await new Promise((r) => canvas.toBlob(r, 'image/png'));
  const head = new Uint8Array(await blob.slice(0, 26).arrayBuffer());
  console.log(file.name, file.size, '->', blob.size);
  console.log('bit depth', head[24], 'color type', head[25]);
};
input.click();

Аргумент качества у toBlob для image/png игнорируется. PNG — формат без потерь, обменивать число качества здесь не на что, и ползунок, который в инструменте на основе canvas будто бы управляет сжатием PNG, не управляет ничем.

Измерено 83 файла: каждое сжатое изображение вернулось больше оригинала

Весь прогон, без отбора удобных случаев:

ПоказательЗначение
Проверено файлов83 (все PNG в public/og, оба color type — RGB и палитра)
Файлов стало больше83 / 83 (100%)
Минимальный прирост+35,6%
Медианный прирост+76,6%
Максимальный прирост+237,2%

Один файл для наглядности: aes-decrypt.png вырос с 505 516 B до 898 014 B, прирост +77,6%. Тот же файл, закодированный в WebP с качеством 0.8, весит 27 188 B, −94,6%.

Границы выборки здесь важны. Эти 83 файла — карточки Open Graph: 1200×630, плоские фоны, крупный текст, несколько фирменных цветов. Это ровно та графика, с которой хороший PNG-кодировщик справляется отлично, и именно поэтому прогон через canvas бьет по ней так сильно. Результат убедителен для PNG графического типа; это не утверждение, что любой PNG на свете растет после прогона через canvas. Фотографический PNG, который и так хранился полным RGBA, теряет куда меньше.

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

Почему JPEG, сохраненный как PNG, растет в 16,9 раза

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

ФайлХарактерОригиналcanvas PNGИзменениеJPEG q92JPEG q80WebP q80
og-a.pngГрафика, 2 351 цвет, RGB306 302607 481+98,3%56 45937 69513 852
quantized.pngПалитра из 64 цветов59 843184 856+208,9%78 38844 44216 046
photo.pngФото, 479 373 цвета498 639867 763+74,0%77 32145 05024 068
photo.jpgJPEG q8247 828809 415+1 592% (16,9×)58 762 (+22,9%)47 15223 862

В последней строке: на входе 47 828 байт, на выходе 809 415 байт.

Механизм здесь объясняет целое семейство жалоб вида «сжатие сделало файл больше». JPEG — кодек с потерями, работающий в частотной области: он переводит блоки 8×8 в коэффициенты DCT, агрессивно их квантует и хранит выживших. PNG — кодек без потерь, работающий в пространственной области: он предсказывает каждый пиксель по соседям и сжимает остатки алгоритмом deflate. Декодируйте JPEG — и получите пиксели, которые несут все артефакты, внесенные квантователем: звон у краев, блочность в плавных градиентах, едва заметный шум там, где в оригинале его не было.

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

Это происходит везде, где перед фотографией стоит умолчание «сохранить как PNG»: инструменты для скриншотов, экспорт из дизайн-редакторов, мессенджеры, некоторые виджеты загрузки.

Те же пиксели, разница в 3,46 раза, оба варианта без потерь

Кодировщик canvas измеримо слаб. Возьмем буфер пикселей из og-a.png и закодируем его двумя способами, оба полностью без потерь:

КодировщикВыходColor type
Chrome canvas toBlob('image/png')607 481 BRGBA (принудительное расширение)
upng-js encode(..., cnum=0)175 491 BRGB (исходный color type сохранен)

3,46× на идентичных пикселях. Утверждение про отсутствие потерь мы проверили, а не приняли на веру: декодирование вывода upng-js при cnum=0 возвращает буфер, побайтово совпадающий с исходным буфером RGBA. Эти 3,46× не стоили ничего.

Это ответ на вопрос, который задают постоянно: почему два онлайн-сервиса сжатия, оба бесплатные, оба обещающие одно и то же, дают несопоставимые результаты? Потому что «сжатие в браузере» описывает две совершенно разные реализации. Одна отдает пиксели в canvas.toBlob и отгружает то, что вернулось. Другая несет в себе настоящий PNG-кодировщик и управляет color type. Тот же вход, тот же браузер, разница в 3,46 раза.

3. Причина вторая: вашему JPEG больше нечего отдавать

Пять раундов пересжатия, и размер перестает двигаться

Возьмем photo.jpg, уже сохраненный с качеством 82, и пересожмем его с качеством 0.8 пять раз подряд, подавая каждое поколение на вход следующему:

ПоколениеБайтыК предыдущему
0 (оригинал, q82)47 828
147 152−1,4%
247 164+0,0%
347 156−0,0%
447 1560,0%
547 1560,0%

Первый проход дает 1,4%. Начиная со второго поколения размер файла заперт в полосе ±12 байт, а поколения 4 и 5 совпадают по размеру с третьим байт в байт.

Вот так выглядит «сжатие не работает», когда на входе JPEG. Инструмент отработал. Кодировщик отработал. Убирать было просто нечего: таблицы квантования на качестве 80 обнуляли примерно те же коэффициенты, которые качество 82 оставило. Однажды исчезнувший коэффициент нельзя убрать повторно.

Проверить это можно локально:

cp photo.jpg gen0.jpg
for i in 1 2 3 4 5; do
  magick "gen$((i-1)).jpg" -quality 80 "gen$i.jpg"
done
stat -f%z gen0.jpg gen1.jpg gen2.jpg gen3.jpg gen4.jpg gen5.jpg

В Linux вместо этого нужен stat -c%s. Точные значения в байтах зависят от того, с каким кодировщиком слинкована сборка ImageMagick, так что не ждите, что таблица выше воспроизведется цифра в цифру, — важна форма кривой. Одно осмысленное падение, дальше прямая линия.

Поднять число качества — это не сжатие

Посмотрите еще раз на строку photo.jpg в разделе 2. Пересжатие этого оригинала с качеством 82 на качестве 92 дало 58 762 байта: +22,9%.

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

Отсюда правило: никогда не пересжимайте JPEG с качеством выше того, с которым он был сохранен. Если это значение неизвестно, не пересжимайте вовсе. Вернитесь к исходнику.

Потери поколений: та потеря качества при пересжатии JPEG, которую не видно

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

Ущерб проявляется не там, где его ищут. В размере миниатюры пятое поколение неотличимо от первого. Увеличьте до 100% и проверьте места, где JPEG сдает первым: резкие края на плоском фоне, текст и плавные градиенты, где блочность видна как плитки 8×8. В сборочном пайплайне, который пересжимает на каждом деплое, это молча копится месяцами.

Здесь мы измеряли размеры файлов, а не воспринимаемое качество, поэтому цифру PSNR или SSIM для пяти поколений мы не приведем. Мы ее не измеряли. Данных по размеру и без того достаточно: начиная со второго поколения вся цена платится качеством, а выгода равна нулю.

Сдвиг цвета — отдельная поломка с тем же спусковым крючком. Canvas не переносит метаданные, поэтому прогон через toBlob выбрасывает блок EXIF, а вместе с ним и ICC-профиль. Изображение с меткой Display P3 или Adobe RGB на входе выходит без метки, и просмотрщики истолкуют его как sRGB. Значения пикселей не изменились. Изменилась инструкция, как их читать.

4. Причина третья: размер PNG не уменьшается, потому что его уже квантовали

Если PNG уже проходил через сжатие один раз, второму проходу работать не с чем. Это строка quantized.png — файл на 59 843 байта, уже сведенный к палитре из 64 цветов и прогнанный по трем разным путям:

ПутьРезультатК оригиналу
Перекодирование без потерь (upng cnum=0)61 377+2,6%
Квантование до 256 цветов61 366+2,5%
Квантование до 64 цветов61 366+2,5%

Каждый путь дал результат больше оригинала. Ненамного, но больше — включая квантование до 64 цветов файла, в котором и так было 64 цвета.

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

Практическое следствие: «сэкономлено 0%» на уже оптимизированном PNG — это правильный результат, а не сбой. Инструмент, который сообщает о небольшом приросте и оставляет исходный файл, ведет себя как надо. Инструмент, который всё равно отдает файл побольше, — нет.

5. Настоящий рычаг для PNG — квантование, а не перекодирование

Перекодирование без потерь против 256 цветов и против 64 цветов

Три файла, три стратегии:

ФайлОригиналБез потерь (cnum=0)256 цветов64 цвета
og-a.png306 302175 491 (−42,7%)110 772 (−63,8%)76 230 (−75,1%)
photo.png498 639587 863 (+17,9%)109 284 (−78,1%)61 397 (−87,7%)
quantized.png59 84361 377 (+2,6%)61 366 (+2,5%)61 366 (+2,5%)

Перекодирование без потерь — самый слабый доступный инструмент. На графике оно выиграло 42,7%, на фотографии отдало обратно 17,9%, на уже квантованном файле проиграло 2,6%. Фотографический материал побеждает даже грамотный PNG-кодировщик без потерь: палитру там не найти, а соседние пиксели плохо предсказывают друг друга.

Настоящее уменьшение дает квантование, и отрыв большой: 63,8% против 42,7% на той же графике при 256 цветах и 75,1% при 64. В командной строке:

magick logo.png -colors 64 PNG8:logo-64.png
magick logo.png -colors 256 PNG8:logo-256.png

Префикс PNG8: принудительно дает PNG с палитрой. Без него ImageMagick может сократить число цветов и всё равно записать truecolor-файл, а это съедает большую часть выигрыша.

Когда палитра безопасна, а когда появляются полосы

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

Безопасно: иконки, логотипы, скриншоты интерфейса, плоские иллюстрации, схемы — всё, где есть большие области однородного цвета и резкие границы. В таких изображениях обычно от силы несколько сотен различных цветов, поэтому палитра на 256 записей достается почти даром, а нередко выживают и 64.

Рискованно: фотографии, плавные градиенты, мягкие тени и полупрозрачные наложения. Сведение градиента к 64 ступеням дает видимые полосы, а dithering меняет эти полосы на шум, который потом отъедает часть выигрыша в размере. Частичная прозрачность поверх градиента — самый тяжелый случай из всех.

Прозрачность заслуживает отдельной проверки: сколько ее уцелеет, зависит от кодировщика, а не от самого квантования. PNG8: в ImageMagick пишет бинарную прозрачность — пиксель либо полностью непрозрачен, либо полностью прозрачен, и мягкий сглаженный край возвращается резким. Специализированный квантователь PNG сохраняет полный альфа-канал, а вместе с ним и мягкий край. Если в материале есть тень или растушеванные края, сравните оба варианта, прежде чем выбирать.

Проверяйте результат на 100%, а не в миниатюре. Полосы — тот самый артефакт, который уменьшенный предпросмотр надежно прячет.

6. Решение: менять формат, а не пересжимать

Таблица выбора формата

МатериалЧто использоватьПочему
ФотографииWebP, а ради максимальной совместимости JPEGФотографиям нужно частотное кодирование с потерями
Скриншоты, графика интерфейсаКвантованный PNG или WebPПлоские цвета, резкие границы, небольшие палитры
Иконки и логотипыSVG, если вектор есть, иначе квантованный PNGУ векторов нет проблемы разрешения
Всё, где нужна прозрачностьWebP или PNGОба несут полный альфа-канал
АнимацияWebPОдин формат вместо GIF
Попиксельно точный архивPNG без потерьЕдинственный случай, где отсутствие потерь — требование

Это намеренно краткая версия. Эффективности кодирования и поддержке современных форматов в браузерах посвящена отдельная статья: WebP vs AVIF vs JPEG.

Что WebP сделал с теми же 83 файлами

Тот же набор из 83 файлов, который через canvas PNG рос в 100% случаев, сконвертированный вместо этого в WebP с качеством 0.8: 83 из 83 стали меньше, медиана −94,2%. Уже знакомый файл aes-decrypt.png уменьшился с 505 516 B до 27 188 B, −94,6%.

Контрольные файлы согласуются. og-a.png: 306 302 в PNG и 13 852 в WebP q80. photo.png: 498 639 в PNG и 24 068 в WebP q80. photo.jpg: 47 828 в JPEG и 23 862 в WebP q80.

К последнему сравнению одна оговорка. WebP с качеством 0.8 — формат с потерями, так что с PNG он соревнуется не на равных, а перекодирование существующего JPEG в WebP всё равно стоит одного поколения. Сравнивать надо с тем, что вы собирались выкладывать, а не с гипотетическим идеальным оригиналом.

Когда PNG всё же стоит оставить

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

Еще один вид «стало больше», не связанный со сжатием

Если встраивать изображения как data URI, размер в CSS или HTML — это не размер на диске. Base64 кодирует каждые 3 байта четырьмя символами плюс padding, поэтому текст арифметически на +33% больше самих байтов. И это еще до всякого сжатия на транспорте. Идеально оптимизированное изображение всё равно вырастает на треть в момент встраивания. Наше руководство по встраиванию через data URI разбирает, когда такой размен оправдан.

7. На практике: браузер, командная строка, сборочный пайплайн

В браузере

При выборе браузерного инструмента значение имеет одно различие: проходит ли PNG через canvas. В нашем бесплатном сжатии изображений — не проходит. PNG на входе квантуется до цветовой палитры и записывается обратно настоящим PNG с целым альфа-каналом, поэтому прозрачность и мягкие края выживают; ползунок качества отображается на размер палитры, а не на аргумент toBlob, который PNG всё равно проигнорировал бы. Качество 100 соответствует перекодированию без потерь. JPEG и WebP через canvas проходят — там параметр качества настоящий и делает ровно то, чего от него ждут.

Одно поведение выглядит багом, но им не является: если сжатый результат не меньше загруженного файла, инструмент выбрасывает собственный вывод и оставляет исходные байты. На уже оптимизированном PNG вы увидите «сэкономлено 0%». Это раздел 4, работающий как задумано.

Обработка идет в браузере, файлы никуда не уходят.

В командной строке

cwebp поставляется вместе с libwebp и быстрее всего позволяет проверить, решает ли смена формата вашу задачу:

# WebP с потерями, качество 0-100
cwebp -q 80 photo.png -o photo.webp

# WebP без потерь, уровень усилий сжатия 0-9
cwebp -z 9 logo.png -o logo.webp

ImageMagick 7 закрывает случаи конвертации и квантования:

# PNG в JPEG с выбранным качеством
magick photo.png -quality 80 photo.jpg

# Квантование в PNG с палитрой из 64 цветов
magick logo.png -colors 64 PNG8:logo-64.png

# Убрать EXIF и прочие метаданные
magick photo.jpg -strip photo-clean.jpg

В macOS утилита sips уже установлена и не требует зависимостей:

# Конвертация в JPEG; formatOptions принимает 0-100 или low/normal/high/best
sips -s format jpeg -s formatOptions 80 photo.png --out photo.jpg

# Ресайз до 1200 px по длинной стороне с сохранением пропорций
sips -Z 1200 photo.jpg --out photo-1200.jpg

# Прочитать размеры обратно
sips -g pixelWidth -g pixelHeight photo-1200.jpg

Сначала ресайз, потом сжатие. Кодировщики работают с пикселями, а самый дешевый пиксель — тот, которого нет.

В сборочном пайплайне

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

8. Пять убеждений, которые замеры не подтверждают

«Сжать дважды — станет меньше». Первое поколение дало 1,4%. Со второго по пятое держались в пределах ±12 байт, а картинка при этом продолжала деградировать. Второй проход — чистые издержки.

«PNG без потерь, значит, формат лучше». Отсутствие потерь — свойство, а не достоинство. Наша тестовая фотография весит 498 639 байт в PNG и 24 068 в WebP q80. Побитовое сохранение фотографии, которую всё равно будут смотреть только на экране, не дает ничего и стоит большей части файла.

«Качество 100 — безопасный выбор». Пересжатие JPEG с качеством 82 на качестве 92 дало +22,9% и картинку хуже. Выше исходного значения качества это число перестает означать «безопаснее» и начинает означать «больше».

«Файл большой, потому что высокое разрешение». Разрешение важно, но при одном и том же разрешении формат важнее. og-a.png в обоих случаях 1200×630: 607 481 байт как canvas PNG и 13 852 байта как WebP q80. Число пикселей идентично.

«Онлайн-сервисы сжатия все одинаковые». Те же пиксели, тот же браузер, оба без потерь: 607 481 байт из canvas и 175 491 из upng-js. Разброс в 3,46 раза между двумя инструментами, которые описывают себя одинаково.

9. Частые вопросы

Почему сжатое изображение больше оригинала?

Потому что инструмент не сжал его, а перекодировал. Вывод браузерного canvas — всегда 32-битный RGBA PNG: палитры отбрасываются, на пиксель уходит четыре байта. В нашем тесте на 83 реальных PNG выросли все 83, медианный прирост — +76,6%. Вместо этого конвертируйте в WebP или JPEG.

Почему PNG не уменьшается при сжатии?

PNG — формат без потерь, поэтому ползунку качества нечего обменивать. Реальное уменьшение дает сокращение числа цветов, а если файл уже квантован, сокращать нечего. Наш тестовый PNG на 64 цвета после повторного квантования до 64 цветов вернулся с приростом +2,5%.

Теряет ли JPEG качество при повторном сжатии?

Да, и взамен вы почти ничего не получаете. Пять раундов с качеством 0.8: 47 828 байт превратились в 47 152 на первом проходе, а следующие четыре держались в пределах 12 байт. Размер перестал двигаться, а каждый проход продолжал заново квантовать картинку. Храните оригиналы.

Что выбрать для уменьшения файла — PNG или JPEG?

Для фотографий — JPEG или WebP, без исключений. Наша тестовая фотография весит 498 639 байт в PNG, 45 050 в JPEG q80 и 24 068 в WebP q80. PNG оставьте для плоской графики, четкого текста и прозрачности, где работу по сжатию выполняет небольшая палитра.

Почему изображение стало размытым после сжатия?

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

Можно ли сжать изображение без потери качества?

Да, но ждите куда меньшего. Перекодирование без потерь всего лишь записывает те же самые пиксели эффективнее: с 306 302 до 175 491 байта на нашей графике, с проверкой побайтового совпадения после декодирования. Тот же подход на фотографии сработал в обратную сторону — +17,9%. Ради реальной экономии без видимых потерь берите WebP с качеством 80.

Почему PNG со скриншотом такой большой?

Снимки экрана сохраняются как полноценный RGBA PNG — четыре байта на пиксель до сжатия, — а Retina-дисплей удваивает число пикселей по каждой стороне. Плоское содержимое хорошо отзывается на сокращение палитры: наша графика карточки Open Graph похудела на 63,8% при 256 цветах и на 75,1% при 64.

Уменьшает ли ресайз размер файла сильнее, чем сжатие?

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

Теги: image-compression png jpeg webp canvas debugging

Похожие статьи

Все статьи