CSS-градационный фильтр и фоновый режим в одно и то же время?

Я пытаюсь обрабатывать изображение так же, как в файле фотошопа, - обесцветяя изображение в оттенки серого, а затем применяя наложение цвета с режимом многократного смешивания. С этой целью я создаю фоновое изображение CSS с помощью...

.someclass
{
    /* grayscale */
    -webkit-filter: grayscale(1); 
    filter: gray; 
    filter: grayscale(1);
    filter: url(desaturate.svg#greyscale);

    /* multiply */
    background-color: rgba(190, 50, 50, 0.65);
    background-blend-mode: multiply;
}

Проблема заключается в том, что фильтр в оттенках серого заканчивается обесцвечивающим красным цветом для режима наложения. Другими словами, умножение происходит сначала, а затем в градациях серого. Как переключить его так, чтобы сначала применялся оттенок серого, а затем накладывался режим наложения?

Я создал скрипку (http://jsfiddle.net/g54LcoL1/1/) для кода и скриншота (сделанного в Photoshop) того, что я ожидаю от результата скрипта. Нижняя часть изображения, div.grayscale.multiply, должна быть окрашена в красный цвет.

enter image description here

Ответы

Ответ 1

Вы не можете сделать это с фильтром, но вы можете сделать это, оставаясь в режиме смешивания для всего

эквивалент оттенков серого в смеси - светимость, с изображением в качестве источника и сплошной белой в качестве фона

Таким образом, фоновые изображения снизу вверх:

  1. белый (как фоновый цвет)
  2. ваше изображение
  3. сплошной красный (на данный момент он должен быть указан как градиент)

и режимы наложения - светимость и умножение

.test {
  width: 400px;
  height: 400px;
  background-image: linear-gradient(0deg, red, red), url("http://cuteoverload.files.wordpress.com/kitteh_puddle-1312.jpg");
  background-color: white;
  background-blend-mode: multiply, luminosity;
  background-size: cover;
}
<div class="test"></div>

Ответ 2

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

Существует функция filter() для ссылок на изображения, поэтому теоретически вы должны иметь возможность применять фильтр к любому изображению при его загрузке. Я думаю, что это идея:

.someclass {
    background-image: filter(cat.jpg, grayscale(100%));
    background-color: red;
    background-blend-mode: multiply;
}

К сожалению, я не думаю, что это реализовано где-то еще, это только в черновом варианте спецификации Filters.

В общем, порядок операций с точки зрения этих типов эффектов "пост-обработки" CSS определяется в том же порядке, что и для SVG: сначала выполняется фильтрация, затем отсечение, затем маскировка, затем смешивание.

(См. Specing Blending & Compositing.) Итак, я ничего не могу сделать с точки зрения изменения этого, я боюсь.

Ответ 3

Как упоминал Джоэл в своем комментарии в соответствии с принятым ответом, это можно сделать с помощью mix-blend-mode.

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

Также я собираюсь использовать "экранный" режим смешивания вместо "умножить", потому что он более четко демонстрирует удаление цвета.

С удалением цвета:

.image-wrapper {
    background: red;
    display: inline-block;
}

.image-wrapper img {
    mix-blend-mode: screen;
    filter: grayscale(100%);
}
<div class="image-wrapper">
    <img src="https://static.decalgirl.com/assets/designs/large/clrkit.jpg" alt="Colorful cats"/>
</div>