Счётчик Яндекс Метрики

Пересохранили одно фото в JPEG 200 раз: после девятого сохранения файл перестал меняться, а обрезка на пиксель превратила его в кашу

Проверили расхожее правило «каждое сохранение JPEG портит фото». Двести сохранений с одними настройками дали почти ту же картинку, что и первое, а двадцать обрезок по одному пикселю испортили снимок сильнее, чем сохранение с качеством 10 из 100. Показываем замеры, объясняем почему и как не испортить свои снимки.

Многие боятся лишний раз нажать «Сохранить»: кажется, что JPEG тает с каждым разом, как ксерокопия с ксерокопии. Мы пересохранили одну фотографию двести раз, и файл замер на девятом круге, а дальше не изменился ни на байт. Но стоило перед каждым сохранением обрезать у той же фотографии один пиксель, и через двадцать кругов фон поплыл разводами. По замерам это хуже, чем одно сохранение с качеством 10 из 100.

📋 Что мы намеряли

Мы взяли три тестовые фотографии без сжатия и пересохраняли каждую в JPEG по двести раз пятью способами. С одними и теми же настройками почти вся потеря приходится на первое сохранение, а после восьмого-девятого файл больше не меняется. Если перед каждым сохранением менять качество, снимок медленно мутнеет. А обрезка всего на один пиксель разрушает картинку быстрее всего: уже после пяти кругов ошибка на попугаях такая же, как после одного сохранения с качеством 30, а к двухсотому кругу от фото остаётся цветной шум. Виновата сетка квадратов 8×8, на которую JPEG режет снимок: обрезка эту сетку сдвигает.

Шесть фотокарточек с попугаем в ряд: каждая следующая сильнее рассыпается на квадраты и цветной шум, рядом ножницы и линейка
Оглавление

Как мы проверяли

Нам нужен был исходник, который до нас никто не сжимал, иначе мы бы мерили чужие потери вместе со своими. Поэтому взяли снимки из набора Kodak: 24 фотографии размером 768×512 точек, которые компания выложила в свободный доступ, и с тех пор это стандартный набор для проверки алгоритмов сжатия. Мы выбрали три разных сюжета: попугаев с гладким зелёным фоном, разноцветные шляпы и горную речку с камнями, где мелких деталей больше всего.

Каждый снимок сохраняли в JPEG программой на Python с библиотекой Pillow, которая использует libjpeg-turbo — ту же, что стоит в Chrome, Firefox и в редакторах фото. Качество — 75 из 100, как по умолчанию у большинства программ. Сохранили, открыли получившийся файл, сохранили снова — и так двести раз. Сценариев было пять:

  • просто пересохранение с одними и теми же настройками;
  • поворот на 90 градусов, сохранение и поворот обратно;
  • каждый раз случайное качество от 70 до 95, как бывает, когда фото проходит через разные программы;
  • уменьшение на 10% и возврат к прежнему размеру перед каждым сохранением;
  • обрезка одного пикселя сверху и слева перед каждым сохранением.

Потери мерили в цифрах. Цвет каждой точки на экране задаётся тремя числами — красным, зелёным и синим, каждое от 0 до 255. Мы сравнивали эти числа с оригиналом точка за точкой и считали типичное отклонение (среднеквадратичное, если по-научному). Ошибка в 3–4 ступени на глаз незаметна, 10 ступеней видно при увеличении, а при 50 картинку уже трудно узнать.

200 сохранений подряд: портит только первое

На фото с попугаями первое сохранение дало ошибку 3,6 ступени. Столько стоит сжатие: из 1,2 МБ несжатой картинки получается файл на 42 КБ. Второе сохранение добавило совсем чуть-чуть, а дальше ошибка дошла до 3,9 и там остановилась. Десятое сохранение совпало с девятым до байта, и вплоть до двухсотого файл больше не менялся. На шляпах и на речке вышло то же: ошибка подросла с 3,7 до 3,9 и с 7,6 до 7,7, а файл замирал после восьмого-девятого раза.

С поворотом получилось так же: двести раз повернули, сохранили, повернули обратно, и итог совпал с обычным пересохранением в пределах десятой доли ступени. Сохранение с высоким качеством 90 сходилось медленнее: файл переставал меняться только на 21-м круге у речки и на 39–40-м у двух других снимков. Но и там после остановки ничего не накапливалось.

Четыре одинаковых фрагмента фото с попугаем: оригинал, после 200 сохранений с одними настройками, после 200 сохранений с разным качеством и после 200 обрезок по пикселю Один и тот же фрагмент, увеличен вдвое. Двести сохранений с одними настройками на глаз неотличимы от оригинала, а обрезка на пиксель превратила попугая в шум. Замер «Техпросто»

Так что правило «никогда не пересохраняйте JPEG» не работает. Если вы открыли фото, ничего в нём не меняли и десять раз нажали «Сохранить» в той же программе, вы потеряли почти столько же, сколько за первый раз.

Почему JPEG перестаёт портиться

JPEG режет снимок на квадраты 8×8 точек и каждый описывает не цветами точек, а набором узоров — от плавной заливки до мелкой ряби. Затем у каждого узора округляет силу, причём мелкую рябь округляет грубее, потому что глаз её почти не замечает. Это округление и есть потеря качества, а заодно главный способ сжать файл: грубо округлённые числа записываются коротко.

Повторное округление ничего не отнимает. Представьте, что вы округляете цену до десятков: 1234 рубля превращаются в 1230, и сколько ни округляй 1230 дальше, останется 1230. При повторном сохранении квадрат уже собран из округлённых узоров: программа раскладывает его на те же узоры и округляет до тех же чисел. Если ничего не менять, новых потерь почти не возникает.

Небольшая добавка в первые сохранения всё же набегает. Когда файл открывают, узоры снова превращаются в точки, и цвет каждой точки приходится округлять до целого числа от 0 до 255, а цвета на краях диапазона ещё и обрезать. Эти мелкие погрешности чуть сдвигают узоры, и следующее сохранение округляет их иначе. Через несколько кругов сдвиг становится меньше шага округления, и файл перестаёт меняться. При качестве 90 шаг мельче, поэтому сдвигов хватает дольше и файл замирает позже.

Что на самом деле портит фото

Потери копятся, если между сохранениями сдвигается сетка квадратов или меняются настройки качества.

Хуже всего вышло с обрезкой на один пиксель. На попугаях ошибка после пяти кругов выросла до 5,5 ступени — столько же даёт одно сохранение с качеством 30. После двадцати кругов набралось 10,3 ступени, а это уже больше, чем после одного сохранения с качеством 10 из 100, где на вид сплошные квадраты. К двухсотому кругу ошибка дошла до 57 ступеней на попугаях, 61 на шляпах и 84 на речке, и от снимков остался цветной шум, в котором угадываются контуры.

Фрагмент фото с попугаем после 5, 20, 50 и 100 кругов «обрезка на пиксель плюс сохранение» После пяти кругов разница ещё незаметна, после двадцати фон покрывается разводами, к сотому краски уплывают. Замер «Техпросто»

Со случайным качеством от 70 до 95 ошибка росла понемногу на каждом круге: 5 ступеней после десяти сохранений, 8,8 после пятидесяти и 13 после двухсот. Уменьшение на 10% с возвратом размера сначала смягчает картинку, а потом почти перестаёт вредить: на попугаях и шляпах ошибка остановилась на 4,7. Речка с мелкими камнями так и продолжала размываться до 16 ступеней, потому что каждое уменьшение заново съедает мелкие детали.

График: как растёт ошибка пикселя при 200 пересохранениях четырьмя способами Шкала сохранений логарифмическая. Синяя и бирюзовая линии почти лежат, жёлтая ползёт вверх, красная уходит вверх круто. Замер «Техпросто»

🔢 Типичная ошибка пикселя на фото с попугаями (ступеней из 255)
Сценарий 1 раз 10 раз 50 раз 200 раз
Одни и те же настройки 3,6 3,9 3,9 3,9
Поворот и обратно 3,5 3,9 3,9 3,9
Уменьшение на 10% и обратно 3,7 4,4 4,7 4,7
Каждый раз другое качество 3,6 5,0 8,8 13,2
Обрезка на 1 пиксель 3,5 7,3 18,5 56,8

Для сравнения, одно сохранение того же оригинала с качеством 90 даёт 2,7, с качеством 30 — 5,5, с качеством 10 — 9,2.

Испорченный файл ещё и тяжелее. Снимок с попугаями после двухсот обрезок стал меньше на 200 точек по каждой стороне, а весил 60 КБ вместо 42. Цветной шум сжимается хуже гладкой картинки, поэтому испорченный файл занимает больше места.

📲 Проверяем, а не верим на слово

Мы регулярно берём расхожие советы про технику и проверяем их опытом, а потом объясняем результат простыми словами. Подпишитесь на «Техпросто» в MAX, Telegram или Дзене, и новые эксперименты будут приходить сами.

Почему сдвиг на один пиксель вредит больше, чем двести обычных сохранений

Виновата сетка квадратов 8×8. Пока картинку не трогают, при каждом сохранении сетка ложится на те же места, и в каждый квадрат попадает то же содержимое, которое уже округлили. Обрезали пиксель слева — и вся сетка уехала на одну точку. Теперь каждый новый квадрат захватывает куски двух старых, в нём сочетаются узоры, которые ни разу не округлялись вместе, и формат округляет их заново.

Мы проверили эту догадку тем же опытом, только обрезали не по одному пикселю, а сразу по 16. Сетка в таком случае сдвигается на два квадрата и ложится на старые места. Двадцать таких обрезок дали на попугаях ошибку 3,6 ступени, как одно-единственное сохранение. А при обрезке по 8 пикселей ошибка выросла до 6,4: сетка яркости совпадает, а сетка цвета нет. Дело в том, что JPEG по умолчанию хранит цвет с половинной чёткостью — одним значением на квадрат 2×2 точки, поэтому цветные квадраты покрывают 16×16 точек снимка. Когда мы отключили эту экономию на цвете, обрезка по 8 пикселей тоже перестала портить фото.

Со сменой качества сетка остаётся на месте, зато меняется шаг округления: каждое новое качество — новый шаг, и число съезжает заново. Поворот на 90 градусов у нас прошёл безвредно, потому что стороны снимка, 768 и 512 точек, делятся на 16 без остатка и после поворота квадраты встают на те же места. Так выходит только с такими размерами, а у многих фотографий стороны на 16 не делятся, поэтому поворачивать их лучше без пересжатия (об этом ниже). Повышение качества от сдвига защищает лишь отчасти: обрезка на пиксель при качестве 90 за пятьдесят кругов дала на попугаях 14 ступеней против 18,5 при качестве 75, и порча всё равно сильная.

Как не испортить свои снимки

Фото портит цепочка «поправил — сохранил», повторённая десятки раз. Уберечься от неё просто.

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

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

Поворачивайте без пересжатия. На компьютере поворачивать JPEG без потерь умеют XnView MP и IrfanView (только Windows): они переставляют готовые квадраты и не пережимают картинку заново.

💡 Когда отправляете фото в мессенджер

Мессенджеры по умолчанию экономят трафик за ваш счёт: отправка «как фото» означает, что приложение уменьшит снимок и пережмёт его своими настройками. Если снимок нужен для печати или дальнейшей обработки, отправляйте его файлом, и до получателя дойдёт оригинал без изменений.

Повышать качество при каждом сохранении мало помогает: качество 90 от сдвига почти не защищает. Зато первое сохранение лучше делать с запасом. Одно сохранение с качеством 90 дало на попугаях ошибку 2,7 ступени против 3,6 при 75, а файл вырос с 42 до 77 КБ — для фото, которое вы будете ещё обрабатывать, это разумная цена. Где хранить архив оригиналов, чтобы они не съедали память телефона, мы разбирали в подборке облачных хранилищ и в гайде как перенести фото с телефона на компьютер.

⚠️ Где наш опыт не совпадает с жизнью

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

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

Портит ли фото простое копирование или перенос? Нет, если файл просто копируют: на флешку или на компьютер он переезжает байт в байт. А вот облако может пережать снимок при загрузке — у Google Фото за это отвечает режим «Экономия места», он уменьшает фото до 16 Мп. Для архива оригиналов выбирайте загрузку в исходном качестве.

А если упаковать фото в архив? Архив сжимает без потерь, и после распаковки файл совпадает с исходным до байта. Правда, места он тоже почти не экономит — это мы проверяли в эксперименте что на самом деле сжимает ZIP.

С видео то же самое? Видео тоже сжимают с потерями, поэтому каждое перекодирование ролика в новый формат или с новыми настройками отнимает часть качества. Сколько места экономят разные форматы, мы замеряли в опыте с H.264, HEVC и AV1.

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

Заведите папку с оригиналами и правьте только копии — этого достаточно, чтобы снимки не превратились в кашу.

Ластик
✏️ Автор: Ластик — лицо рубрики Техпросто.
За фактами, проверкой и качеством материалов следит живой редактор — журналист с публикациями на DNS Club и iChip.