Преобразование изображения в оттенки серого в HTML / CSS - PullRequest
595 голосов
/ 04 марта 2009

Есть ли простой способ отобразить цветное растровое изображение в оттенках серого с помощью HTML/CSS?

Он не должен быть IE-совместимым (и я полагаю, что не будет) - если он работает в FF3 и / или Sf3, для меня этого достаточно.

Я знаю, что могу сделать это и с SVG, и с Canvas, но сейчас кажется, что это большая работа.

Есть ли действительно ленивый способ сделать это?

Ответы [ 26 ]

6 голосов
/ 02 марта 2015

В современных браузерах уже некоторое время доступен новый способ сделать это.

background-blend-mode позволяет получить некоторые интересные эффекты, одним из которых является преобразование в оттенках серого

Значение яркость , установленное на белом фоне, позволяет это сделать. (чтобы увидеть его серым цветом)

.test {
  width: 300px;
  height: 200px;
    background: url("http://placekitten.com/1000/750"), white; 
    background-size: cover;
}

.test:hover {
    background-blend-mode: luminosity;
}
<div class="test"></div>

Яркость берется из изображения, цвет берется из фона. Поскольку он всегда белый, цвет отсутствует.

Но это позволяет гораздо больше.

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

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

Теперь все, что нужно, это переместить градиент, чтобы получить этот эффект динамическим: (наведите курсор, чтобы увидеть его в цвете)

div {
    width: 600px;
    height: 400px;
}

.test {
    background: url("http://placekitten.com/1000/750"), 
linear-gradient(0deg, white 33%, black 66%), url("http://placekitten.com/1000/750"); 
    background-position: 0px 0px, 0px 0%, 0px 0px;
    background-size: cover, 100% 300%, cover;
    background-blend-mode: luminosity, multiply;
    transition: all 2s;
}

.test:hover {
    background-position: 0px 0px, 0px 66%, 0px 0px;
}
<div class="test"></div>

ссылка

матрица совместимости

4 голосов
/ 03 мая 2016

Может быть, таким образом вам поможет

img {
    -webkit-filter: grayscale(100%); /* Chrome, Safari, Opera */
    filter: grayscale(100%);
}

w3schools.org

3 голосов
/ 28 марта 2018
img {
    -webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
    filter: grayscale(100%);
}
3 голосов
/ 04 марта 2009

На самом деле это проще сделать с помощью IE, если я правильно помню, используя собственное свойство CSS. Попробуйте это FILTER: Gray из http://www.ssi -developer.net / css / visual-filters.shtml

Метод Ax просто делает изображение прозрачным и имеет черный фон за ним. Я уверен, что вы могли бы утверждать, что это в оттенках серого.

Хотя вы не хотели использовать Javascript, я думаю, вам придется использовать его. Для этого вы также можете использовать язык на стороне сервера.

2 голосов
/ 19 октября 2010

Если вы хотите использовать Javascript, то вы можете использовать холст для преобразования изображения в оттенки серого. Поскольку Firefox и Safari поддерживают <canvas>, он должен работать.

Итак, я гуглил «Оттенки серого», и первый результат был http://www.permadi.com/tutorial/jsCanvasGrayscale/index.html, который, кажется, работает.

2 голосов
/ 09 ноября 2013

Вот миксин для LESS, который позволит вам выбрать любую непрозрачность. Заполните переменные для простого CSS с разными процентами.

Здесь есть подсказка , для матрицы используется тип насыщенности, поэтому вам не нужно делать что-то необычное, чтобы изменить процент.

.saturate(@value:0) {
    @percent: percentage(@value);

    filter: url("data:image/svg+xml;utf8,<svg%20xmlns='http://www.w3.org/2000/svg'><filter%20id='grayscale'><feColorMatrix%20type='saturate'%20values='@value'/></filter></svg>#grayscale"); /* Firefox 3.5+ */
    filter: grayscale(@percent); /* Current draft standard */
    -webkit-filter: grayscale(@percent); /* New WebKit */
    -moz-filter: grayscale(@percent);
    -ms-filter: grayscale(@percent);
    -o-filter: grayscale(@percent);
}

Тогда используйте это:

img.desaturate {
    transition: all 0.2s linear;
    .saturate(0);
    &:hover {
        .saturate(1);
    }
}
2 голосов
/ 26 января 2015

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

Так что для полноценного использования достаточно использовать этот код:

img.grayscale {
    filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale"); /* Firefox 10+, Firefox on Android */
    filter: gray; /* IE6-9 */
    -webkit-filter: grayscale(100%); /* Chrome 19+, Safari 6+, Safari 6+ iOS */
}

img.grayscale.disabled {
    filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'1 0 0 0 0, 0 1 0 0 0, 0 0 1 0 0, 0 0 0 1 0\'/></filter></svg>#grayscale");
    filter: none;
    -webkit-filter: grayscale(0%);
}
2 голосов
/ 16 мая 2012

добавлена ​​поддержка собственных CSS-фильтров в webkit с текущей версии 19.0.1084.46

so -webkit-filter: grayscale (1) будет работать, и это проще, чем SVG-подход для webkit ...

1 голос
/ 18 сентября 2014

В качестве дополнения к ответам других, можно обесцветить изображение на половине FF без матрицы головной боли SVG:

<feColorMatrix type="saturate" values="$v" />

Где $v находится между 0 и 1. Это эквивалентно filter:grayscale(50%);.

Пример из жизни:

.desaturate {
    filter: url("#desaturate");
    -webkit-filter: grayscale(50%);
}
figcaption{
    background: rgba(55, 55, 136, 1);
    padding: 4px 98px 0 18px;
    color: white;
    display: inline-block;
    border-top-left-radius: 8px;
    border-top-right-radius: 100%;
    font-family: "Helvetica";
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
  <filter id="desaturate">
  	<feColorMatrix type="saturate" values="0.4"/>
  </filter>
</svg>

<figure>
  <figcaption>Original</figcaption>
  <img src="http://www.placecage.com/c/500/200"/>
  </figure>
<figure>
  <figcaption>Half grayed</figcaption>
  <img class="desaturate" src="http://www.placecage.com/c/500/200"/>
</figure>

Ссылка на MDN

1 голос
/ 14 сентября 2013

На основании ответа Роберта :

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

0.3333 0.3333 0.3333 0 0
0.3333 0.3333 0.3333 0 0
0.3333 0.3333 0.3333 0 0
0      0      0      1 0

Вы должны использовать конверсионную матрицу так:

0.299 0.299 0.299 0
0.587 0.587 0.587 0
0.112 0.112 0.112 0
0     0     0     1

Это должно хорошо работать для всех типов изображений на основе модели RGBA (красный-зеленый-синий-альфа).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...