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

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

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

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

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

Ответы [ 26 ]

698 голосов
/ 23 декабря 2011

В Webkit появилась поддержка CSS-фильтров. Итак, теперь у нас есть кросс-браузерное решение.

img {
  filter: gray; /* IE6-9 */
  -webkit-filter: grayscale(1); /* Google Chrome, Safari 6+ & Opera 15+ */
  filter: grayscale(1); /* Microsoft Edge and Firefox 35+ */
}

/* Disable grayscale on hover */
img:hover {
  -webkit-filter: grayscale(0);
  filter: none;
}
<img src="http://lorempixel.com/400/200/">

А как насчет Internet Explorer 10?

Вы можете использовать полифилл как серый .

126 голосов
/ 27 октября 2010

Исходя из ответа brillout.com , а также ответа Романа Нурика и несколько ослабив требование «без SVG», вы можете обесцветить изображения в Firefox, используя только один SVG-файл и немного CSS.

Ваш SVG-файл будет выглядеть так:

<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1"
     baseProfile="full"
     xmlns="http://www.w3.org/2000/svg">
    <filter id="desaturate">
        <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>

Сохраните это как resources.svg, теперь его можно использовать повторно для любого изображения, которое вы хотите изменить на оттенки серого.

В вашем CSS вы ссылаетесь на фильтр, используя специфичное для Firefox свойство filter:

.target {
    filter: url(resources.svg#desaturate);
}

При необходимости добавьте проприетарные MS, примените этот класс к любому изображению, которое вы хотите преобразовать в оттенки серого (работает в Firefox> 3.5, IE8) .

edit : Вот хороший пост в блоге , в котором описано использование нового свойства CSS3 filter в ответе SalmanPK в сочетании с описанным здесь подходом SVG. Используя этот подход, вы получите что-то вроде:

img.desaturate{
    filter: gray; /* IE */
    -webkit-filter: grayscale(1); /* Old WebKit */
    -webkit-filter: grayscale(100%); /* New WebKit */
    filter: url(resources.svg#desaturate); /* older Firefox */
    filter: grayscale(100%); /* Current draft standard */
}

Дополнительная информация о поддержке браузера здесь .

85 голосов
/ 30 ноября 2012

Для Firefox вам не нужно создавать файл filter.svg, вы можете использовать схему URI данных .

Взяв код css первого ответа, вы получите:

filter: url("data:image/svg+xml;utf8,<svg%20xmlns='http://www.w3.org/2000/svg'><filter%20id='grayscale'><feColorMatrix%20type='matrix'%20values='0.3333%200.3333%200.3333%200%200%200.3333%200.3333%200.3333%200%200%200.3333%200.3333%200.3333%200%200%200%200%200%201%200'/></filter></svg>#grayscale"); /* Firefox 3.5+ */
filter: grayscale(100%); /* Current draft standard */
-webkit-filter: grayscale(100%); /* New WebKit */
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%); 
-o-filter: grayscale(100%);
filter: gray; /* IE6+ */

Позаботьтесь о том, чтобы заменить строку "utf-8" на кодировку вашего файла.

Этот метод должен быть быстрее другого, потому что браузеру не нужно будет делать второй HTTP-запрос.

26 голосов
/ 01 ноября 2012

Обновление: Я сделал это в полном репозитории GitHub, включая полифилл JavaScript для IE10 и IE11: https://github.com/karlhorky/gray

Первоначально я использовал ответ SalmanPK , но затем создал вариант ниже, чтобы исключить дополнительный HTTP-запрос, необходимый для файла SVG. Встроенный SVG работает в Firefox версий 10 и выше, а версии ниже 10 больше не занимают даже 1% мирового рынка браузеров.

С тех пор я постоянно обновляю решение в этом сообщении в блоге , добавив поддержку угасания цвета, поддержку IE 10/11 с SVG и частичную шкалу серого в демонстрационной версии.

img.grayscale {
  /* Firefox 10+, Firefox on Android */
  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");

  /* IE 6-9 */
  filter: gray;

  /* Chrome 19+, Safari 6+, Safari 6+ iOS */
  -webkit-filter: grayscale(100%);
}

img.grayscale.disabled {
  filter: none;
  -webkit-filter: grayscale(0%);
}
14 голосов
/ 08 декабря 2010

Если вы можете использовать JavaScript, то этот скрипт может быть тем, что вы ищете. Это работает кросс-браузер и работает нормально для меня до сих пор. Вы не можете использовать его с изображениями, загруженными из другого домена.

http://james.padolsey.com/demos/grayscale/

11 голосов
/ 05 марта 2012

У меня сегодня такая же проблема. Сначала я использовал SalmanPK решение , но обнаружил, что эффект отличается между FF и другими браузерами. Это потому, что матрица преобразования работает только на яркость, а не на яркость, как фильтры в Chrome / IE. К моему удивлению, я обнаружил, что альтернативное и более простое решение в SVG также работает в FF4 + и дает лучшие результаты:

<svg xmlns="http://www.w3.org/2000/svg">
  <filter id="desaturate">
    <feColorMatrix type="saturate" values="0"/>
  </filter>
</svg>

С css:

img {
    filter: url(filters.svg#desaturate); /* Firefox 3.5+ */
    filter: gray; /* IE6-9 */
    -webkit-filter: grayscale(1); /* Google Chrome & Safari 6+ */
}

Еще одно предостережение: IE10 больше не поддерживает «filter: grey:» в режиме соответствия стандартам, поэтому для работы требуется переключатель режима совместимости в заголовках:

<meta http-equiv="X-UA-Compatible" content="IE=9" />
10 голосов
/ 04 ноября 2016

Простейший способ получить оттенки серого исключительно с помощью CSS - через свойство filter.

img {
    -webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
    filter: grayscale(100%);
}

Свойство по-прежнему не полностью поддерживается и все еще требует свойство -webkit-filter для поддержки во всех браузерах.

7 голосов
/ 11 июня 2009

Не похоже, что это возможно (пока), даже с CSS3 или проприетарными -webkit- или -moz- свойствами CSS.

Однако я нашел это сообщение с июня прошлого года , в котором использовались фильтры SVG для HTML. Не доступно ни в одном текущем браузере (демонстрация намекает на пользовательскую сборку WebKit), но очень впечатляет в качестве доказательства концепции.

7 голосов
/ 26 октября 2010

В Internet Explorer используйте свойство фильтра.

В webkit и Firefox в настоящее время нет способа обесцветить изображение исключительно с помощью CSS. поэтому вам потребуется использовать canvas или SVG для решения на стороне клиента.

Но я думаю, что использование SVG более элегантно. проверьте мой блог для SVG-решения, которое работает как для Firefox, так и для webkit: http://webdev.brillout.com/2010/10/desaturate-image-without-javascript.html

И, строго говоря, поскольку SVG - это HTML, решение - это чистый html + css: -)

7 голосов
/ 28 апреля 2013

Для людей, которые спрашивают о игнорируемой поддержке IE10 + в других ответах, просмотрите этот фрагмент CSS:

img.grayscale:hover {
    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");
}

svg {
    background:url(http://4.bp.blogspot.com/-IzPWLqY4gJ0/T01CPzNb1KI/AAAAAAAACgA/_8uyj68QhFE/s400/a2cf7051-5952-4b39-aca3-4481976cb242.jpg);
}

svg image:hover {
    opacity: 0;
}

Применяется к этой разметке:

<!DOCTYPE HTML>
<html>
<head>

    <title>Grayscaling in Internet Explorer 10+</title>

</head>
<body>

    <p>IE10 with inline SVG</p>
    <svg xmlns="http://www.w3.org/2000/svg" id="svgroot" viewBox="0 0 400 377" width="400" height="377">
      <defs>
         <filter id="filtersPicture">
           <feComposite result="inputTo_38" in="SourceGraphic" in2="SourceGraphic" operator="arithmetic" k1="0" k2="1" k3="0" k4="0" />
           <feColorMatrix id="filter_38" type="saturate" values="0" data-filterid="38" />
        </filter>
      </defs>
      <image filter="url(&quot;#filtersPicture&quot;)" x="0" y="0" width="400" height="377" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://4.bp.blogspot.com/-IzPWLqY4gJ0/T01CPzNb1KI/AAAAAAAACgA/_8uyj68QhFE/s1600/a2cf7051-5952-4b39-aca3-4481976cb242.jpg" />
    </svg>

</body>
</html>

Для большего количества демонстраций, ознакомьтесь с разделом Графика CSS3 IE testdrive и этим старым блогом IE http://blogs.msdn.com/b/ie/archive/2011/10/14/svg-filter-effects-in-ie10.aspx

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