Преобразование изображения в оттенки серого в HTML/CSS

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

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

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

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

Ответ 1

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

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/">

Ответ 2

В ответ на ответ 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 */
}

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

Ответ 3

Для 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-запрос.

Ответ 4

Обновление: Я сделал это в полном репозитории GitHub, включая JavaScript polyfill для 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%);
}

Ответ 5

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

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

Ответ 6

Сегодня у нас такая же проблема. Я изначально использовал решение 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: gray:" в стандартном режиме совместимости, поэтому для переключения режима совместимости в заголовках необходимо работать:

<meta http-equiv="X-UA-Compatible" content="IE=9" />

Ответ 7

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

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

Ответ 8

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

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

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

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

Ответ 9

Для людей, которые спрашивают об игнорируемой поддержке 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>

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

Ответ 10

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

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>

Ответ 11

Возможно, этот способ поможет вам

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

w3schools.org

Ответ 12

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

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

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

Ответ 13

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

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

Ответ 14

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

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

Ответ 15

Здесь есть mixin для 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);
    }
}

Ответ 16

Вам не нужно использовать так много префиксов для полного использования, потому что если вы выберете префикс для старого 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%);
}

Ответ 17

Простейший способ сделать это

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

}

Ответ 18

На основе ответа robertc:

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

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 (red-green-blue-alpha).

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

Ответ 19

В дополнение к другим ответам, можно обесцветить изображение на полпути на 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>

Ответ 20

Одно ужасное, но работоспособное решение: визуализируйте изображение с помощью Flash-объекта, который затем дает вам все возможные преобразования во Flash.

Если ваши пользователи используют браузеры с краткими границами и , если Firefox 3.5 и Safari 4 поддерживают его (я не знаю, что это делать/будет), вы можете отрегулируйте атрибут цветового профиля CSS для изображения, установив его в URL-адрес профиля ICC в оттенках серого. Но это много, если!

Ответ 21

Если вы или кто-то другой, столкнувшийся с подобной проблемой в будущем, открыты для PHP. (Я знаю, что вы сказали HTML/CSS, но, возможно, вы уже используете PHP в бэкэнд) Вот PHP-решение:

Я получил его из библиотеки PHP GD и добавил некоторую переменную для автоматизации процесса...

<?php
$img = @imagecreatefromgif("php.gif");

if ($img) $img_height = imagesy($img);
if ($img) $img_width = imagesx($img);

// Create image instances
$dest = imagecreatefromgif('php.gif');
$src = imagecreatefromgif('php.gif');

// Copy and merge - Gray = 20%
imagecopymergegray($dest, $src, 0, 0, 0, 0, $img_width, $img_height, 20);

// Output and free from memory
header('Content-Type: image/gif');
imagegif($dest);

imagedestroy($dest);
imagedestroy($src);

?>

Ответ 22

be Альтернативой для более старого браузера может быть использование маски, создаваемой псевдоэлементами или встроенными тегами.

Абсолютное позиционирование, наведение img (или текстовая область, для которой не требуется клик и выбор) может точно имитировать эффекты цветовой шкалы, через rgba() или translucide png.

Он не даст ни одной цветовой гаммы, но оттеняет цвет вне диапазона.

тест на ручке кода с 10 различными цветами через псевдоэлемент, последний серый. http://codepen.io/gcyrillus/pen/nqpDd (перезагрузка для переключения на другое изображение)

Ответ 23

Вы можете использовать одну из функций jFunc - использовать функцию "jFunc_CanvasFilterGrayscale" http://jfunc.com/jFunc-functions.aspx

Ответ 24

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

$("#myImageID").tancolor();

Есть интерактивная демонстрация . Вы можете играть с ним.

Ознакомьтесь с документацией по использованию, это довольно просто. docs

Ответ 25

Для оттенков серого в процентах в Firefox используйте фильтр насыщения вместо: (поиск "насыщенный" )

filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='saturate'><feColorMatrix in='SourceGraphic' type='saturate' values='0.2' /></filter></svg>#saturate"