Превратить картинку в "псевдопиксельный ветер"? С CSS это так просто!

внешний интерфейс CSS
Превратить картинку в "псевдопиксельный ветер"? С CSS это так просто!

«Это 11-й день моего участия в ноябрьском испытании обновлений, ознакомьтесь с подробностями события:Вызов последнего обновления 2021 г."

Младшая сестра продукта сказала своему коллеге А Ян: «Если вы можете использовать CSS, чтобы превратить любовную картинку в像素风, Я обещаю встречаться с тобой сегодня. "

Я похлопал А Ян по плечу и многозначительно сказал: «Не волнуйся, старший тебе поможет».

Что такое пиксельный ветер?

像素风это以固定大小纯色像素方块В качестве базовой единицы создавайте творения, включая, помимо прочего,绘画,建筑,游戏Стиль искусства в каждой области.
Один из самых известных, конечно же, ранний电子游戏Пиксельный экран~

超级玛丽.jpg
[Пиксельное изображение «Марио» на ранней красно-белой машине]
Конечно, ранние видеоигры переняли像素风, на самом деле своего рода историческая беспомощность.Ограниченность аппаратных условий заставляет разработчиков игр выбирать именно такого рода变现力强,性能开销Низкий художественный стиль.

но,时至今日Пиксельный ветер по-прежнему актуален в различных областях, и ему было уделено больше внимания.审美а также复古по смыслу.

Анализ мыслей

Давайте взглянем на исходную картинку «любовной картинки», которая будет обработана на этот раз:

step2.png
[Любовная картинка]

Чтобы превратить такую ​​картинку в пиксели, мне в голову пришла первая идея:

Идея 1: Вырежьте и заполните холст

Используйте холст, чтобы разрезать картинку на N * N блоков, а затем вычислить медианное значение цвета для каждой области отдельно и заполнить ее сплошным цветом.Да, эта идея, несомненно, может решить проблему быстро и гибко.
Но при этом CSS не используется, мой коллега А Ян第一次约会Не будет ли он полностью истощен?
❌❌
Нет нет нет! Я должен передумать и использовать CSS для достижения этого!

Идея 2: Фильтр размытия по Гауссу большого радиуса для получения медианы

Основная идея заключается в следующем:

  1. Разделите изображение на N div, каждый div содержит часть изображения.
  2. Каждый div проходит css-фильтр один разblur(高斯模糊), визуально достигая取中值并填充divЭффект.

Согласно этой идее, на самом деле есть только одна трудность, как让每个div都持有图片的一部分?

О, это не может беспокоить меня.那颗帮助同事大心脏.

воплощать в жизнь

На самом деле это не сложно:

  1. Во-первых, мы используем 8 * 8, чтобы разделить div на 64 части, несомненно, в виде сетки.

grid-8-8.png
Код:

<style>
    .mask-group {
      width: 128px;
      height: 128px;
      display: grid;
      grid-template-columns: repeat(8,1fr);
      grid-template-rows: repeat(8,1fr);
    }
</style>
<script>
  const el = document.querySelector('.mask-group')
    for(let i = 0; i< 64; i++) {
      const itemEl = document.createElement('div')
      itemEl.className = 'mask-item'
      el.appendChild(itemEl)
    }
  }
</script>
  1. Затем мы устанавливаем фон в форме сердца для каждого элемента .mask-item.

Тогда эффект变成了这样, потому что фон каждого из них начинается с верхнего левого угла, так что это определенно не так, как ожидалось.

step-2.png
Далее: Нам нужно вставить такое предложение в обход js:

itemEl.style.backgroundPosition = `-${Math.floor(i%8) * 16}px -${Math.floor(i/8) * 16}px `

Цель этой строки кода — предоставить каждому элементу .mask-item отдельныйbackground-positionСтиль рассчитывается таким образом, что левый верхний угол фонового изображения всех элементов .mask-item перекрывается坐标点上.
Эффект показан на рисунке:

step3.png
3. Увеличьте интервал и размытие по Гауссу Как и предполагалось, нам нужно только дать div加上间隔, затем дайте高斯模糊, можно добиться эффекта. Итак, код выглядит следующим образом:

.mask-group {
  /* 以下为新增 */
  grid-row-gap: 2px;
  grid-column-gap: 2px;
}
.mask-item {
  /* 以下为新增 */
  filter: blur(8px)
}

Но эффект такой:

step4.png

В чем проблема?
高斯模糊на самом деле будет работатьinner-boxвне области! !

  1. маска-изображение ограничивает видимую область

Ни в коем случае, чтобы ограничить область эффекта размытия по Гауссу, я могу передать только маску-изображение.
Сначала получите чисто черный all-black.png файл размером 16*16 пикселей.
код показывает, как показано ниже:

.mask-item {
  /* 以下为新增 */
  -webkit-mask-image: url('./all-black.png');
  mask-image: url('./all-black.png');  
}

Изображение эффекта:

px.png

эй, это так сейчас, но因为被高斯Причина в том, что цвет сильно потускнел, ничего страшного, просто подкорректируйте.

  1. настроить цвет

код показывает, как показано ниже:

.mask-item {
  /* 以下为更改 */
  filter: blur(8px) contrast(400%) saturate(400%);
}

px-final.png
Готово! !

Окончание истории

Никогда не думал, что иностранный коллега или没能Завершите свидание с сестрой по продукту Мэй.
Причина на самом деле:
产品妹妹觉得我写代码的样子过于靓仔,非要和我约会!

814268e3gy1feeba43bswg205a04i7hl.gif
--Конец--