Простые изображения с высоким разрешением

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

Сегодня существует множество предложений по адаптивным изображениям, многие из которых предполагают значительные изменения для веб-разработчика. Атрибут srcset <img> стандартного трека сложно реализовать, особенно из-за сложности дополнительного выбора srcset на основе области просмотра:

banner-HD.jpeg 2x, banner-phone.jpeg 100w, banner-phone-HD.jpeg 100w 2x

Несмотря на то, что свойство CSS image-set использует только devicePixelRatio чтобы решить, какое изображение загружать, оно все равно заставляет разработчиков писать много дополнительной разметки для каждого изображения.

Другие предложения, такие как элемент <picture> , еще более многословны. Более того, они не соответствуют стандартам, поэтому их повсеместная доступность даже дальше, чем атрибут srcset. Единственная альтернатива — JavaScript и серверные решения, но у этих подходов есть свои недостатки, о которых говорится в других статьях .

В этой статье мы рассмотрим несколько вариантов использования изображений, часто встречающихся в Интернете, и предложим простые решения, которые работают как на экранах с высокой плотностью пикселей, так и на обычных. Для целей этого обсуждения любое устройство, которое сообщает window.devicePixelRatio больше 1, может считаться высоким DPI, поскольку это означает, что пиксели CSS не совпадают с пикселями устройства и что изображения масштабируются.

Вот краткое изложение:

  • Если возможно, используйте CSS/SVG, а не растровые изображения.
  • По умолчанию используйте изображения, оптимизированные для дисплеев с высокой плотностью изображения.
  • Используйте PNG для простых рисунков и пиксельной графики (например, логотипов).
  • Используйте сжатые файлы JPEG для изображений с различными цветами (например, фотографий).
  • Всегда устанавливайте явные размеры (с помощью CSS или HTML) для всех элементов изображения.

Простые рисунки и пиксель-арт

Маленьких изображений часто можно полностью избежать, используя функции CSS или SVG. Например, нет необходимости использовать изображения для закругленных углов, поскольку свойство CSS border-radius широко поддерживается. Аналогично, широко поддерживаются пользовательские шрифты, поэтому использование «изображенного» текста нецелесообразно.

Однако в некоторых случаях, например, в случае логотипов, изображение может быть единственным способом продвижения вперед. Например, этот логотип Chrome имеет естественный размер 256x256. На дисплее Retina вы можете увидеть сглаживание линий по диагоналям и кривым, что выглядит коренастым и некрасивым, особенно по сравнению с четко визуализированным текстом:

Хром 1x
PNG 1x

Естественные размеры: 256x256px , размер ресурса: 31 kB , формат: PNG

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

Хром 2x
JPEG 2x

Естественные размеры: 512x512px , размер ресурса: 13 kB , формат: JPEG

Для относительно небольших изображений следует использовать 2x PNG. Имейте в виду, что разница в размере между PNG 1x и 2x обычно довольно велика (в данном случае 52 КБ). Однако в случае с логотипом это лицо вашего сайта и первое, что увидят ваши посетители. Если слишком экономить на качестве в обмен на размер, это будет последнее, что увидят ваши посетители!

Вот логотип Chrome во всей красе, уменьшенный вдвое от естественных размеров для 2x дисплеев:

Хром 2x
PNG 2x

Естественные размеры: 512x512px , размер ресурса: 83 kB , формат: PNG

Разметка для выполнения приведенного выше рендеринга следующая:

<img src="chrome2x.png" style="width: 256px; height: 256px;"/>

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

Одна из возможных оптимизаций, которая может сработать, — уменьшить 24-битный PNG до 8-битного с палитрой. Это работает для изображений с небольшим количеством цветов, включая логотип Chrome. Чтобы выполнить эту оптимизацию, вы можете использовать такой инструмент, как http://pngquant.org/ . Здесь вы можете увидеть небольшие полосы, но размер этого файла составляет всего 13 КБ, что означает колоссальную экономию в 6 раз по сравнению с исходным PNG размером 512x512.

Хром 2х8бит
PNG 2х8бит

Естественные размеры: 512x512px , размер ресурса: 13 kB , формат: PNG, 8-bit palette

Изображения с различными цветами

Я написал статью на HTML5Rocks , в которой рассмотрел ряд различных методов адаптивного изображения , а также провел небольшое исследование сжатия 1x и 2x JPEG и сравнения полученных размеров и визуального качества. Вот одна из таких плиток из статьи выше:

Плитка.

Я пометил изображения, указав уровень сжатия (обозначенный качеством JPEG), их размер (в байтах) и мое субъективное мнение об их сравнительной визуальной точности (ранжирование по цифрам). Интересно здесь то, что сильно сжатое изображение 2x (помечено 3) меньше по размеру и выглядит лучше , чем несжатое изображение 1x (помечено 4). Другими словами, между изображениями 4 и 3 нам удалось улучшить качество изображения, удвоив каждое измерение и значительно увеличив сжатие, одновременно уменьшив размер на 2 КБ.

Сжатие, размеры и визуальное качество

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

Гипотеза

При достаточном сжатии изображение с увеличением 2x будет выглядеть эквивалентно тому же изображению с размером 1x при другом (более низком) сжатии. Однако в этом случае сильно сжатое изображение 2x будет меньше по размеру, чем изображение 1x.

Процесс

  • Учитывая изображение 2x, сгенерируйте изображение 1x.
  • Сжимайте оба изображения на разных уровнях.
  • Создайте тестовую страницу, на которой оба набора изображений будут показаны рядом.
  • Найдите в двух наборах место, где изображения эквивалентны.
  • Обратите внимание на эквивалентные размеры изображений и уровни сжатия.
  • Попробуйте это как на дисплее 1x, так и на дисплее 2x.

Я создал приложение для параллельного сравнения изображений, похожее на представление сравнения в Lightroom . Цель состоит в том, чтобы показать изображения с увеличением 1x и 2x рядом друг с другом, а также позволить вам увеличивать любую часть изображения, чтобы получить более подробную информацию. Вы также можете выбрать форматы JPEG и WebP и изменить качество сжатия, чтобы сравнить размер файла и качество изображения. Идея состоит в том, чтобы настроить параметры нескольких изображений, выяснить, какое качество сжатия, масштабирование и формат по сравнению с качеством изображения вам удобно, и использовать эти настройки для всех ваших изображений.

Скриншот сравнения

Сам инструмент доступен для игры . Вы можете увеличить изображение , выбрав подобласть для увеличения.

Анализ

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

Поигравшись с зуммером изображения, мне быстро стали очевидны некоторые вещи. Во-первых, я предпочитаю изображения quality=30 dpr=2x изображениям quality=90 dpr=1x для увеличения детализации. Эти изображения также сопоставимы по размеру файла (в плоском случае сжатое изображение 2x имеет размер 76 КБ, тогда как несжатое изображение 1x — 80 КБ).

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

Изображения WebP выглядят намного чище, чем JPEG, особенно при низких уровнях сжатия. Эта цветовая полоса кажется гораздо меньшей проблемой. Наконец, изображения WebP намного компактнее.

Предостережения и плавник

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

Я сознательно избегал этой темы «художественного направления», чтобы сосредоточиться только на изображениях с высоким разрешением. Эту проблему можно решить несколькими различными способами: с помощью медиа-запросов и фоновых изображений, с помощью JavaScript, с помощью некоторых новых функций, таких как image-set , или на сервере. Эта тема рассматривается в разделе «Изображения с высоким разрешением и переменной плотностью пикселей» .

Подпишусь с несколькими открытыми вопросами:

  • Влияние высокого сжатия на производительность. Каковы последствия декодирования сильно сжатых изображений?
  • Каковы потери производительности при уменьшении размера изображения при загрузке изображения с увеличением 2x на дисплей с разрешением 1x?

Подводя итог, выберите CSS и SVG вместо использования растровых изображений. Если растровые изображения строго необходимы, используйте PNG для изображений с ограниченной палитрой и множеством сплошных цветов и используйте JPEG для изображений с множеством цветов и градиентов. Самое замечательное в этом подходе то, что ваша разметка практически не меняется. Все, что требуется от веб-разработчика, — это сгенерировать 2x-ресурсы и правильно изменить размер изображений в DOM.

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