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

Использование SVG в качестве Placeholder’a

image

Генерация SVG из изображений может использоваться для Placeholder’ов.

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

В последние дни я сталкивался с некоторыми методами загрузки, которые используют SVG, и я хотел бы описать их в этом посте.

В этом посте мы рассмотрим следующие темы:

  • Обзор различных типов Placeholder’ов
  • Placeholder на основе SVG (контуры, фигуры и силуэты)
  • Автоматизация процесса.


Перевод выполнен при поддержке компании EDISON Software [1], которая профессионально занимается созданием корпоративных сайтов на WordPress [2], а так же дизайнит персонажей для фирменного стиля [3].


Обзор различных типов Placeholder’ов

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

image

Несколько вариантов заполнения области изображения перед его загрузкой.

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

  • Placeholder: Представьте, что мы показываем изображение профиля пользователя. Мы могли бы отобразить силуэт на месте изображения. Он отображается не только при загрузке основного изображения, но также и при неудачном выполнении запроса или когда пользователь вообще не установил изображение профиля. Эти изображения, как правило, основаны на векторах, и из-за их небольшого размера являются хорошим кандидатом, который должен быть встроен.
  • Solid colour: возьмите цвет из изображения и используйте его в качестве цвета фона для Placeholder’а. Это может быть доминирующим цветом, наиболее ярким… Идея состоит в том, что он основан на загружаемом изображении и должен помочь сделать переход между “без изображения” на изображение более плавным.
  • Размытое изображение: также называется техникой размытия. Вы создаете малую версию изображения, а затем переходите к полной. Начальное изображение маленькое как в пикселях, так и в размерах. Для удаления артефактов изображение масштабируется и размывается. Ранее я писал об этом в этих статьях How Medium does progressive image loading [4], Using WebP to create tiny preview images [5] и More examples of Progressive Image Loading [6].
  • Оказывается, есть много других вариантов, и многие умные люди разрабатывают другие методы создания Placeholder’ов.

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

image

Использование градиентов в качестве фона. Скриншот от Gradify, который больше не в сети. Код на GitHub [7].

Другой метод — использование SVG на основе изображения.

Placeholder’ы на основе SVG

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

Контуры

В предыдущем посте [8] я объяснил, как узнать контуры в изображении и создать анимацию. Моя первоначальная цель состояла в том, чтобы попытаться нарисовать области, векторизируя изображение, но я не знал, как это сделать. Я понял, что использование контуров также может быть инновационным, и я решил оживить их, создав эффект «рисования».

image

Codepen [9]

Drawing images using edge detection and SVG animation [8]

Формы

SVG также может использоваться для рисования областей из изображения без использования контуров / границ. В некотором смысле, мы будем векторизовать растровое изображение для создания Placeholder’a.

Когда-то я пытался сделать что-то подобное с треугольниками. Вы можете увидеть результат в моих беседах в CSSConf [10] и Render Conf [11].

image

Codepen выше [12] является доказательством концепции Placeholder’ов на основе SVG, состоящий из 245 треугольников. Генерация треугольников основана на триангуляции Делоне [13] с использованием polyserver Поссана. [14] Как и ожидалось, чем больше треугольников использует SVG, тем больше размер файла.

Primitive и SQIP, метод LQIP на основе SVG

Тобиас Балдауф работает над другим методом низкого качества изображения, используя SVG, называемый SQIP [15]. Прежде чем копаться в SQIP, я дам обзор Primitive [16], библиотеки, на которой основан SQIP.

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

Primitive генерирует изображение, основанное на таких фигурах, как треугольники, прямоугольники и круги (и несколько других). На каждом шаге он добавляет новую. Чем больше шагов, тем результирующее изображение выглядит ближе к исходному. Если у вас на выходе SVG, это также означает, что размер выходного кода будет больше.

Чтобы понять, как работает Primitive, я провел его через пару изображений. Я сгенерировал SVG для художественной работы, используя 10 фигур и 100 фигур:

image

к картинкам(Обработка этого изображения с помощью Primitive, используя 10 Фигур и 100 фигур.)

image

При использовании 10 фигур в изображении мы начинаем понимать исходное изображение. В контексте placeholder’a изображений существует возможность использовать этот SVG в качестве placeholder’a. На самом деле, код для SVG с 10 фигурами очень мал, около 1030 байт, который снижается до ~ 640 байт при передаче вывода через SVGO.

<path fill=”#817c70" d=”M0 0h1024v1024H0z”/><path fill=”#03020f” d=”M178 994l580 92L402–62"/><path fill=”#f2e2ba” d=”M638 894L614 6l472 440"/><path fill=”#fff8be” d=”M-62 854h300L138–62"/><path fill=”#76c2d9" d=”M410–62L154 530–62 38"/><path fill=”#62b4cf” d=”M1086–2L498–30l484 508"/><path fill=”#010412" d=”M430–2l196 52–76 356"/><path fill=”#eb7d3f” d=”M598 594l488–32–308 520"/><path fill=”#080a18" d=”M198 418l32 304 116–448"/><path fill=”#3f201d” d=”M1086 1062l-344–52 248–148"/><path fill=”#ebd29f” d=”M630 658l-60–372 516 320"/>

Изображения, сгенерированные с 100 фигурами, больше, как и ожидалось, весом ~ 5 КБ после SVGO (ранее 8КБ). Они имеют большой уровень детализации с небольшой полезной нагрузкой. Решение о том, сколько треугольников использовать, будет во многом зависеть от типа изображения (например, контраста, количества цветов, сложности) и уровня детализации.

Можно было бы создать скрипт, похожий на cpeg-dssim [17], который изменяет количество используемых фигур до тех пор, пока не будет достигнут порог структурного подобия [18] (или максимального количества фигур в худшем случае).

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

SQIP

По словам Тобиаса [15]:

SQIP-это попытка найти баланс между этими двумя крайностями: использование Primitive [16] для генерации SVG, состоящего из нескольких простых фигур, которые приближают основные объекты, видимые внутри изображения, оптимизирует SVG с помощью SVGO [19] и добавляет к нему фильтр Gaussian Blur. Это производит SVG placeholder, который весит всего ~800-1000 байт, выглядит гладко на всех экранах и обеспечивает визуальную реплику содержимого изображения.

Результат аналогичен использованию крошечного изображения Placeholder’a для технологии размытия (что делают Medium [4] и другие сайты [6]). Разница заключается в том, что вместо использования растрового изображения, например JPG или WebP, Placeholder является SVG.

Если мы запустим SQIP против исходных изображений, мы получим следующее:

image

Выходные изображения с использованием SQIP для первого [20] изображения и второго [21].

Выходной SVG составляет ~ 900 байт, и, проверяя код, мы можем обнаружить фильтр feGaussianBlur, применяемый к группе фигур:

image

SQIP также может выводить тег изображения с содержимым SVG Base 64 encoded:

<img width="640" height="640" src="example.jpg” alt="Add descriptive alt text" style="background-size: cover; background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAw…<stripped base 64>…PjwvZz48L3N2Zz4=);">

Силуэты

Мы просто посмотрели на использование SVG для контуров и примитивных фигур. Другая возможность заключается в векторизации изображений, «прорисовывая» их. Несколько дней назад Mikael Ainalem [22] поделился codepen’он, указав, как использовать 2-цветный силуэт в качестве placeholder’a. Результат очень красивый:

image

SVG в этом случае были нарисованы вручную, но техника быстро породила интеграцию с инструментами для автоматизации процесса.

  • Gatsby [23], статический генератор сайта, использующий React, поддерживает эти прорисованные SVG сейчас. Он использует JS PORT potrace [24] для векторизации изображений.
    image
  • Craft 3 CMS [25], который также добавил поддержку силуэтов. Он использует PHP Port of potrace [26].
    image
  • image-trace-loader [27], загрузчик Webpack, который использует potrace для обработки изображений.
    image

Также интересно посмотреть сравнение вывода между загрузчиком Webpack от Emil (основано на potrace) и отрисованными вручную SVG от Mikael.

image

Я предполагаю, что вывод, генерируемый potrace, использует параметры по умолчанию. Однако их можно настроить. Проверьте параметры для Image-trace-loader [28], которые в основном передаются в potrace [29].

Итого

Мы рассмотрели различные инструменты и методы для генерации SVG из изображений и использования их в качестве placeholder’a. Также WebP — фантастический формат для эскизов [5], SVG также интересный формат для использования в placeholder’ах. Мы можем контролировать уровень детализации (и, следовательно, размер), он очень сжимается и легко управляется с помощью CSS и JS.

Дополнительные ресурсы

  • Geometrize [30] — это порт Primitive, написанный на Haxe. Существует также реализация на JS [31], которую вы можете попробовать прямо в своем браузере [32].
  • Primitive.js [33], который является портом Primitive в JS. Кроме того, primitive.nextgen [34], который представляет собой порт приложения Primitive для настольных компьютеров с использованием Primitive.js и Electron.
  • Есть несколько аккаунтов Twitter, где вы можете увидеть примеры изображений, созданных с помощью примитива и геометрии. Посмотрите @PrimitivePic [35] и @Geometrizer [36].
  • imagetracerjs [37], который является трассировщиком растрового изображения и векторизатором, написанным на JavaScript. Есть также порты для Java [38] и Android [39].

Автор: Влад

Источник [40]


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

Путь до страницы источника: https://www.pvsm.ru/razrabotka-sajtov/268751

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

[1] EDISON Software: https://www.edsd.ru/integratsiya-sistem-videonablyudeniya-axxon-next-i-sureview-immix

[2] созданием корпоративных сайтов на WordPress: https://www.edsd.ru/korporativnye-sajty-na-wordpress

[3] дизайнит персонажей для фирменного стиля: https://www.edsd.ru/kak-my-risuem-personazhej

[4] How Medium does progressive image loading: https://medium.com/@jmperezperez/how-medium-does-progressive-image-loading-fd1e4dc1ee3d

[5] Using WebP to create tiny preview images: https://medium.com/@jmperezperez/using-webp-to-create-tiny-preview-images-3e9b924f28d6

[6] More examples of Progressive Image Loading: https://medium.com/@jmperezperez/more-examples-of-progressive-image-loading-f258be9f440b

[7] Код на GitHub: https://github.com/fraser-hemp/gradify

[8] предыдущем посте: https://medium.com/@jmperezperez/drawing-images-using-edge-detection-and-svg-animation-16a1a3676d3

[9] Codepen: https://codepen.io/jmperez/pen/oogqdp

[10] CSSConf: https://jmperezperez.com/cssconfau16/#/45

[11] Render Conf: https://jmperezperez.com/renderconf17/#/46

[12] Codepen выше: https://codepen.io/jmperez/pen/BmaWmQ

[13] триангуляции Делоне: https://en.wikipedia.org/wiki/Delaunay_triangulation

[14] polyserver Поссана.: https://github.com/possan/polyserver

[15] SQIP: https://github.com/technopagan/sqip

[16] Primitive: https://github.com/fogleman/primitive

[17] cpeg-dssim: https://github.com/technopagan/cjpeg-dssim

[18] структурного подобия: https://en.wikipedia.org/wiki/Structural_similarity

[19] SVGO: https://github.com/svg/svgo

[20] первого: https://jmperezperez.com/assets/images/posts/svg-placeholders/pexels-photo-281184-square-sqip.svg

[21] второго: https://jmperezperez.com/svg-placeholders/%28/assets/images/posts/svg-placeholders/pexels-photo-618463-square-sqip.svg

[22] Mikael Ainalem: https://twitter.com/mikaelainalem

[23] Gatsby: https://www.gatsbyjs.org/

[24] JS PORT potrace: https://www.npmjs.com/package/potrace

[25] Craft 3 CMS: https://craftcms.com/

[26] PHP Port of potrace: https://github.com/nystudio107/craft3-imageoptimize/blob/master/src/lib/Potracio.php

[27] image-trace-loader: https://github.com/EmilTholin/image-trace-loader

[28] параметры для Image-trace-loader: https://github.com/EmilTholin/image-trace-loader#options

[29] передаются в potrace: https://www.npmjs.com/package/potrace#parameters

[30] Geometrize: https://github.com/Tw1ddle/geometrize-haxe

[31] реализация на JS: https://github.com/Tw1ddle/geometrize-haxe-web

[32] своем браузере: http://www.samcodes.co.uk/project/geometrize-haxe-web/

[33] Primitive.js: https://github.com/ondras/primitive.js

[34] primitive.nextgen: https://github.com/cielito-lindo-productions/primitive.nextgen

[35] @PrimitivePic: https://twitter.com/PrimitivePic

[36] @Geometrizer: https://twitter.com/Geometrizer

[37] imagetracerjs: https://github.com/jankovicsandras/imagetracerjs

[38] Java: https://github.com/jankovicsandras/imagetracerjava

[39] Android: https://github.com/jankovicsandras/imagetracerandroid

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