- PVSM.RU - https://www.pvsm.ru -

Ресайз картинок в браузере. Все может стать еще хуже

Ресайз картинок в браузере. Все может стать еще хуже - 1 

Знакомьтесь, это Маня. Маню поразил страшный недуг и теперь она нуждается в вашей помощи. Маня росла обычной девочкой, жизнерадостным счастливым ребенком. Но чуть больше года назад врачи поставили ей страшный диагноз [1] — алиазинг. И она стала выглядеть вот так.

Ресайз картинок в браузере. Все может стать еще хуже - 2 Ресайз картинок в браузере. Все может стать еще хуже - 3

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

Что изменилось за этот год? Хорошие новости в том, что появился стандарт [2], призванный управлять качеством растеризации изображений на канвасе. Новости еще лучше: этот стандарт реализован в браузере: мобильном Сафари с версии 9.3 и десктопном с версии 9.1. И судя по получающимся результатам, значению high соответствует метод сверток [3] с бикубическим или очень похожим фильтром. Т.е. результат действительно очень хорош. Казалось бы, можно обернуть код [4], вымученный в предыдущей статье, в if ('imageSmoothingQuality' in context) и ждать появления этого же свойства в остальных браузерах. Но что-то пошло не так.

Ресайз картинок в браузере. Все может стать еще хуже - 4 Ресайз картинок в браузере. Все может стать еще хуже - 5

Что-то пошло не так и на маню напала другая напасть — Маня стала мыльной. Оказалось, что Гугл тоже готовит для Машеньки сюрприз, реализовав нужное свойство и пока что спрятав его за флагом chrome://flags/#enable-experimental-canvas-features. Вот только реализовано оно не добросовестно, а чем попало. Вместо правильных, четких, православных сверток, в нем для значения high используется техника, применяющаяся в играх: с помощью суперсэмплинга для изображения создаются mip-уровни [5], а потом ближайший по размеру уровень ресайзится все тем же дешевым методом с фиксированным количеством исходных точек.

Почему этот метод работает в играх? По двум причинам. Первая: в динамичной игре у вас нет времени рассматривать каждую текстуру по-отдельности, мыльная она или не очень. Гораздо больше на восприятие влияет общая картинка и спецэффекты, чем такие мелочи. Вторая: очень жесткие временные ограничения, для которых очень кстати приходится постоянная сложность этого метода относительно размеров конечного изображения (разрешения экрана в случае игр).

Почему этот метод не годится для ресайза в приложениях для работы с графикой? Да потому что это вообще не метод ресайза, алло. Это аппликация из двух решений, ни одно из которых не способно удовлетворить требования к качеству — а уж вдвоем и подавно. Оно не обладает ни математическим обоснованием, ни стабильностью результата относительно входных параметров. Например, картинка, отресайженая до 244 пикселей в ширину может получиться ничего так, а отресайженая до 243 вся будет в мыле. Тем более это не приемлемо для специально созданного по этому случаю свойства imageSmoothingQuality. Уж если я ставлю high, то наверное я имею в виду, что мне нужно именно хорошее качество. Зачем вообще реализовывать новое свойство, если оно дает результат хуже, чем можно добиться, повозившись с существующим решением? Вот, например, справа Маня отресайженая последовательными не кратными двум уменьшениями. Абсолютно здоровый и счастливый ребенок.

Ресайз картинок в браузере. Все может стать еще хуже - 6 Ресайз картинок в браузере. Все может стать еще хуже - 7

Если вы вдруг не испытываете сочувствия и симпатии к маленьким детям, то вот вам Манечкин друг, мандрил Пупуся. Его постигла та же беда. Слева направо:

  • заблюреная картинка после ресайза в Хроме с imageSmoothingQuality = 'high'
  • качественная картинки из Сафари
  • более-менее качественная картинка после ресайза в Хроме методом последовательных уменьшений без imageSmoothingQuality

Ресайз картинок в браузере. Все может стать еще хуже - 8 Ресайз картинок в браузере. Все может стать еще хуже - 9 Ресайз картинок в браузере. Все может стать еще хуже - 10

Как тут можно помочь? Ну например, пойти поставить звездочку в созданном для этого баг-репотре [6]. Не уверен, насколько это эффективно, но ничего другого придумать не могу.

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

Для получения использовались изображения раз [7] и два [8], тестовый стенд [9], а также виджет [10] для последовательных уменьшений.

Автор: homm

Источник [11]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/129918

Ссылки в тексте:

[1] врачи поставили ей страшный диагноз: https://habrahabr.ru/post/252175/

[2] появился стандарт: https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing

[3] метод сверток: https://habrahabr.ru/post/243285/#convolution

[4] обернуть код: https://github.com/uploadcare/uploadcare-widget/blob/0f21ae5aece475ef05edf505e54db017f89bab12/app/assets/javascripts/uploadcare/utils/image-processor.coffee#L131-L135

[5] mip-уровни: https://ru.wikipedia.org/wiki/MIP-текстурирование

[6] баг-репотре: https://bugs.chromium.org/p/chromium/issues/detail?id=618324

[7] раз: https://unsplash.com/photos/8k6tLpo8n0c

[8] два: http://www.johnloomis.org/ece563/notes/basics/components/mandrill/mandrill.html

[9] тестовый стенд: http://jsbin.com/sofigi/edit?output

[10] виджет: https://staging0.uploadcare.com/widget/configure/2.9.0/?shrink=true&shrinkX=257&shrinkY=257&shrinkQuality=100

[11] Источник: https://habrahabr.ru/post/302744/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best