Градиентный заполнитель для предварительного просмотра изображения

Градиентный заполнитель для предварительного просмотра изображения

От автора: не было бы здорово отображать предварительный просмотр изображений, пока они еще загружаются? И без каких-либо дополнительных HTTP-запросов, и с небольшим количеством CSS? Введите градиентные заполнители изображения. Или GIP для краткости. Произносится как jipp, чтобы не путать с форматом изображения GIF, который (нет двух мнений об этом!) произносится как «gif».

Как в этом случае будет выглядеть тег изображения?

<img src="https://example.org/image.jpg" style="background:linear-gradient(135deg, #cbc6c2 0%, #5d5347 100%)" width="300" height="450"
/>

Это хорошая идея?

Прогрессивный рендеринг === хорошо. По крайней мере, это распространенное предположение, но проведем определенные исследования. Фактически, у нас есть одно исследование, которое показывает, что прогрессивный рендеринг может увеличить когнитивную нагрузку на пользователя, и, следовательно, это плохо. Хотя обоснованность исследования под вопросом. Итак, мы вернулись к исходной точке.

Если вы согласны, что прогрессивный рендеринг помогает воспринимаемой производительности (что?, как?), то читайте дальше!

Добро пожаловать в семью

Технология GIP относится к тому же семейству, что и заполнители изображений в низком качестве (LQIP) и SQIP (SVG-версия LQIP). Заполнители в низком качестве существуют уже давно. Я лично заметил, что Picassa делал это еще в 2009 году, кто знает, как задолго до этого.

И SQIP, и LQIP могут создавать изображения размером до 400 байт после сжатия. Преимущество SQIP заключается в том, что изображения SVG могут быть встроены без дополнительных HTTP-запросов или дополнительных затрат на base64.

GIP также не требует никаких HTTP-запросов, а количество добавленных байтов составляет около 60 до сжатия, скорее всего, полезная нагрузка будет еще меньше, учитывая повторение строк, background, linear-gradient, to bottom и т. д.
Недостатком является то, что заполнители GIP не так детализированы, как SQIP, но имеет ли это значение? Я на самом деле затрудняюсь ответить.

Инструменты?

Некоторое время назад я размышлял над техникой GIP и придумал простой инструмент для создания, который разместил в Twitter. И люди указали мне на то, что это уже существовало — grade.js. Grade.js берет два наиболее заметных цвета изображения и рисует между ними диагональный градиент. Хорошо, это неплохое начало, но можно еще немного улучшить.

Также в последнем выпуске календаря я увидел статью Тобиаса, в которой был подозрительно знакомый скриншот, гораздо ближе к тому, что я имел в виду. Он указал мне на инструмент под названием gradifycss.com, который теперь уже на домене мертв, но код все еще существует, и, фактически, демо-версия все еще может использоваться благодаря archive.org (и ура программированию на стороне клиента!).

Я думал, что пришло время стереть мою старую демо-версию и улучшить ее. Результаты очень похожи на то, что делает gradify. Иногда он мне нравится больше, иногда нет. Существует возможность для экспериментов.

Как вычисляется градиент?

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

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

(Подождите, зачем устанавливать 4 основных цвета, а затем выбирать только первый? Что ж, когда вы выполняете квантование, количество цветов в указанной палитре влияет на результаты. Экспериментально я обнаружил, что размер палитры 4, кажется, дает наиболее удовлетворительные результаты. Хотя в коде есть константа PALETTESIZE, с которой вы можете поэкспериментировать и написать мне, что у вас получилось.)

Затем я нахожу два наиболее удаленных друг от друга цвета и рисую между ними градиент. Таким образом, CSS-градиент может быть в одном из 4-х направлений:

to bottom (сверху вниз),

to right (слева направо),

135deg (диагональ сверху слева вниз направо),

45deg (диагональ слева внизу вверх направо).

(Подождите, почему сверху вниз, но не снизу вверх, например? Ну, так как два цвета одинаковы, направление не имеет значения.)

Инструменты!

Модуль Node и CLI

Чтобы интегрировать технику GIP в инструменты сборки, вы можете использовать совсем свежий модуль NPM под названием cssgip. Установка …

npm i -g cssgip

… и использование CLI:

gip test.png

Это выдает что-то вроде:

background: #3f8cc4; background: linear-gradient(to bottom, #0f7ad2 0%, #b0adbe 100%)

Как вы можете видеть, инструмент также дает вам общий цвет фона, если вы:

беспокоитесь о браузерах, которые не понимают градиенты

предпочитаете использовать один цвет, вместо градиента

Этот модуль, конечно, может быть использован без CLI:

const gip = require('cssgip');
const result = await gip('./image.jpg');

В результате получается объект с тремя свойствами, такими как:

css: "background: #ab9f92; background: linear-gradient(135deg, #cbc6c2 0%, #5d5347 100%)"
background: "#ab9f92"
gradient: "linear-gradient(135deg, #cbc6c2 0%, #5d5347 100%)"

Браузерная версия

Вы также можете использовать GIP в браузере. Скажем, автор статьи загружает изображение в CMS, и вы тут же узнаете цвета.

Версия для браузера также доступна в виде модуля NPM и технически имеет 0 зависимостей, поскольку зависимости квантования встроены. Собранный, уменьшенный и заархивированный пакет занимает под 4K.

Использование

Старая школа…

<script src="gip.js"></script>
<script>
const result = gip(img);
</script>

… или новая школа import:

import gip from 'cssgip-browser';
const result = gip(img);

img может быть объектом, созданным с помощью нового Image() или document.createElement(‘image’) или найденным в DOM, например document.images[0] (говоря о старой школе!), или document.getElementsByTagName(‘image’)[0], или document.getElementById(‘the-logo’) и так далее.

Объект, возвращаемый функцией gip(img), имеет три свойства, например:

css: "background: #ab9f92; background: linear-gradient(135deg, #cbc6c2 0%, #5d5347 100%)"
background: "#ab9f92"
gradient: "linear-gradient(135deg, #cbc6c2 0%, #5d5347 100%)"

Вам решать, что делать с этими результатами.

Демо-версия

Наконец, есть демонстрационный сайт, где вы можете попробовать свои собственные изображения. Демо использует версию GIP для браузера (только на стороне клиента), поэтому ваши изображения не загружаются в The Cloud (ура конфиденциальности!).

После выбора изображения вы можете переключиться между изображением и градиентом:

Градиентный заполнитель для предварительного просмотра изображения

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

Дело за вами

Не стесняйтесь попробовать и затем применить технику GIP в своем инструменте сборки и CMS. Webpack, плагины для WordPress и т. д.

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

Еще раз инструменты:

И спасибо за внимание!

Автор: Stoyan Stefanov

Источник: https://calendar.perfplanet.com/

Редакция: Команда webformyself.