Перевод картинки в серый средствами CSS

Серое в CSS (92.76КиБ)

Экспериментировал в рамках прототипа для рабочего проекта с преобразованием изображения в серую гамму. Вообще, конечно, есть тег CANVAS, там это запросто, но интересно посмотреть появилось ли что-то в CSS со времён фильтров «Эксплорера». В IE с незапамятных времён (ещё с пятой версии) есть фильтр «gray», который даёт нужный эффект. Сейчас фильтры обзавелись префиксами и их рекомендуемый синтаксис иной, но суть та же:

.gray {
        filter: gray; /* IE 5+ */
        -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)"; /* new IE */
}

Я всё ждал когда же W3C «переизобретёт» микрософтские фильтры. Свершилось. Недавно появилась спецификация Filter Effects, которая, конечно, гораздо шире того, что когда-то предложили в «Микрософте», но основной смысл тот же, и даже некоторые фильтры похожи.

«Хром» включил в готовящуяся 18-ю версию эксперементальную поддержку этих фильтров:

.gray {
        -webkit-filter: grayscale(1); /* Chrome 18+ */
}

В «Опере» и «Файрфоксе» поддержки этих фильтров пока нет, но есть поддержка других — фильтров SVG. Можно, например, засунуть растровое изображение внутрь SVG и применить к нему нужный фильтр:

<svg style="width: 0; height: 0">
<filter id="gray">
<feColorMatrix type="saturate" values="0"/>
</filter>
</svg>

<!-- тут какой-то HTML код и вдруг понадобилась серая картика -->
<svg style="width:400px; height: 431px"><image xlink:href="/imgs/2008.11.27.jpg" width="100%" height="100%" filter="gray" /></svg>

Хорошие новости — SVG можно мешать с HTML. С версии 3.5 в «Файерфоксе» есть способ лучше — можно применять фильры SVG прямо к тегам HTML (и делать всякие другие чудесные штуки), правда все описания в документации почему-то относятся к XHTML или внешним ресурсам, но я обнаружил, что уже с четвёртой версии этот же трюк работает и с обычным HTML:

<style>
    .gray {
        filter: url(#gray);  /* Firefox 4+ */
    }
</style>

<svg style="width: 0; height: 0">
<filter id="gray">
<feColorMatrix type="saturate" values="0"/>
</filter>
</svg>

<body><img src="/imgs/2008.11.27.jpg" class="gray" /></body>

Добавлено позднее: в ходе дальнейших экспериментов оказалось, что в более ранних «Хромах» (нижнюю границу я пока не выяснил, но в моём 17-м работает), можно через CSS задавать фильтры для SVG, вот таким образом:

<style>
    .gray {
        -webkit-filter: url(#gray); /* Chrome ?? */
        -webkit-filter: grayscale(1); /* Chrome 18+ 
    }
</style>

<svg style="width: 0; height: 0">
<filter id="gray">
<feColorMatrix type="saturate" values="0"/>
</filter>
</svg>

<!-- тут HTML и внезапно понадобилась серая картинка -->

<svg style="width:400px; height: 431px"><image xlink:href="/imgs/2008.11.27.jpg" width="400" height="431" class="gray" /></svg>

При этом «Хром» требует, чтобы ширина и высота картинки были заданы в абсолютных единицах (остальные браузеры прекрасно понимают проценты).

Если собрать всё вместе, получается нижеприведённый код. Я поставил рядом два изображения: слева обычный элемент HTML img, справа — растр в SVG, по ссылке можно протестировать что поддерживает ваш браузер.

Посмотреть код.

<html>
<meta http-equiv="X-UA-Compatible" content="IE=9" />
<style>
    .gray {
        cursor: pointer;

        filter: url(#gray);  /* Firefox 4+ */
        filter: gray; /* IE 5+ */
        -webkit-filter: url(#gray); /* Chrome ?? */
        -webkit-filter: grayscale(1); /* Chrome 18+ */
        -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)"; /* new IE */
    }

    .gray:hover {
        filter: none;
        -webkit-filter: none;
        -ms-filter: none;
    }

</style>

<svg style="width: 0; height: 0">
<filter id="gray">
<feColorMatrix type="saturate" values="0"/>
</filter>
</svg>

<body>
<img src="/imgs/2008.11.27.jpg" class="gray" />
<svg style="width:400px; height: 431px"><image xlink:href="/imgs/2008.11.27.jpg" width="400" height="431" class="gray" /></svg>
</body>

</html>

Мне негде потестировать IE и тем более десятую версию, но я где-то читал, что из «десятки» убрали фильтры, поэтому я, на всякий случай, поставил режим совместимости с девятой версией в коде.

Читайте также

Изображение в оттенках серого на CSS
Демонстрация перевода изображения в оттенки серого средствами CSS-фильтров разных браузеров. Наведите указатель на фотографию или перейдите к ней с клавиатуры: чёрно-белое изображение снова станет цветным.
2012
CSS3 text-shadow
Благодаря БлоGноту узнал об официальном открытии сервиса «Я.ру», походил по ссылкам и обратил внимание, что в Opera 9.50 некоторые ссылки как-то интересно подсвечиваются. До того интересно, что я было подумал, что «оперовцы» реализовали CSS-фильтры из Internet Explorer.
2007
Свёртка в вебе
Я как-то пропустил момент, когда фильтры SVG стало можно накладывать на обычный тег IMG, а не на изображения внутри SVG же. Любопытные эффекты можно делать, например, можно наложить свёртку для выделения краёв и это будет работать:
2014

Комментарии 27

Евгений Степанищев (bolknote.ru) автор № 1
Протестировал встроенные браузеры.

«Андроид» 2.3.6 — не поддерживает ни один из способов.
«иОС» 5.1 — тоже.
WinPhone 7.5 — тоже.
MeeGo 1.2 — тоже.
SiMM № 2
Я поставил рядом два изображения: слева обычный элемент HTML img, справа — растр в SVG

Правая картинка становится цветной, если навести на неё мышью.
Opera 11.61.1250 Win7

GreLI № 3
Хм, говорят, Андроид начал поддерживать SVG только с 4-й версии. Раньше разве что через object. iOS вроде как SVG поддерживает, но как именно, я не знаю. Наверное, стоит продолжить эксперименты с SVG. А ещё на телефонах есть Opera Mobile и Opera Mini :).
Евгений Степанищев (bolknote.ru) автор № 9
Хм, говорят, Андроид начал поддерживать SVG только с 4-й версии. Раньше разве что через object. iOS вроде как SVG поддерживает, но как именно, я не знаю. Наверное, стоит продолжить эксперименты с SVG. А ещё на телефонах есть Opera Mobile и Opera Mini :).

«Поддерживать SVG» это как «поддерживать CSS». У SVG туча версий и расширений. Что-то может поддерживаться, что-то другое — нет. Фильтры, видимо, не поддерживаются.

Евгений Степанищев (bolknote.ru) автор № 13
Сделал способ для «Хрома», позволяющий переводить картинку в серый через подключение CSS-стиля к SVG. Обновил статью.
Евгений Степанищев (bolknote.ru) автор № 14
Таким образом, единственный настольный браузер, который никак не охвачен — «Сафари», в нём обещают поддержку фильтров SVG только в шестой версии.
Orcinus Orca (www.orcinus.ru) № 15
Сам искал простенький метод перевода в серые тона. Но простыми манипуляциями с CSS не вышло. Будем ждать когда разработают нормальные фильтры.
TATAPuH № 17
http://vhardy.github.com/presentations/htm … x.html#/28
интересна конечно вся презентация, но даю ссылку сразу на последний слайд (содержит ссылки на семплы)
П.С. фильтры и канвас это конечно круто, вебГл ещё круче
но к сожалению сносно работает только в десктопе
Евгений Степанищев (bolknote.ru) автор № 18
П.С. фильтры и канвас это конечно круто, вебГл ещё круче

ВебГЛ — это контекст канваса, то есть его часть.

TATAPuH № 20
Комментарий для Евгения Степанищева:

хм, э хм
ну скорость как бы ? не ?
картинка 100x100 обрабатывается достаточно быстро
1600х1200 уже очень даже не быстро
обработка 1000000х10000000 просто не работает (естественно что работаем только с видимой частью, тайлы и так далее,но — там чуть чуть тут немного и всё, тормозим)
для этого и ВебГЛ, доступ к шейдерам, а значит к GPU и паралельности
TATAPuH № 21
Комментарий для Евгения Степанищева:

в любом случае, на пост PS это пока не работает, а жаль (под термином «пост PS», я имею ввиду всяческие айПады и андроиды разные)
поэтому большая часть пиксельного рендеринга обычно уходит в облака (на сервера)
как ни странно получить готовый тайл из облака, обычно быстрее чем его подготовить локально через фильтры (если они есть) или поПиксельный доступ
Евгений Степанищев (bolknote.ru) автор № 22

Комментарий для TATAPuH:

хм, э хм
ну скорость как бы ? не ?
картинка 100x100 обрабатывается достаточно быстро

Ну так она и 2Д-канвасом быстро обработается. И фильтром, если GPU использовать. Причём тут ВебГЛ?

TATAPuH № 23
Комментарий для Евгения Степанищева:

по ссылке не ходил но осуждаю :)
на 28 слайде презентации есть ссылка
Evan Wallace's WebGL filters
http://evanw.github.com/webgl-filter/

вы точно уверенны что 2д канвас не проигрывает по скорости , и что SVG предоставляет фильтры по умолчанию на все случаи жизни ?
Евгений Степанищев (bolknote.ru) автор № 24
Комментарий для TATAPuH:

По ссылке я был, там ничего особенного.

Да я в теме, знаю и что такое и ВебГЛ, и СВГ, и 2Д-канвас. Всё это вполне ускоряется через GPU, свет клином на ВебГЛ не сошёлся.
TATAPuH № 25
Комментарий для Евгения Степанищева:

2D канвас в целом и пиксельный доступ в частности, не ускоряется через GPU (на данный момент только ослик старается всегда работать через GPU до тех пор пока нет обращения к памяти (к пикселям))
http://upload.wikimedia.org/wikipedia/comm … p_mine.gif вот картинка для затравки (но представьте что она увас на весь экран)
тоже казалось бы просто «фильтры и попиксельный доступ»

лет 5 назад витали подобные настроения, мол в десктоп стремительно ворвался WPF теперь заживём, всё мол само собой ускорится засчёт GPU, нет
всё само собой не случается
Евгений Степанищев (bolknote.ru) автор № 26
Комментарий для TATAPuH:

Вы мне вещи какие-то странные объясняете…

Во-первых, можно ускорять заливку, наложение текстур и так далее, то есть чисто двухмерные штуки. 2D-видекарты справлялись с этим ещё десять лет назад (всякие Matrix Millenium). Это к вопросу о том что можно ускорить на «плоском» канвасе.

Во-вторых, есть только воображаемая разница. Фильтр размытия у SVG или CSS делается ровно теми же средствами, на том же GPU, как и WebGL-фильтры. WebGL — это просто более низкий уровень и всё.

И, да, я уверен, что фильтры SVG содержат фильтры не на все случаи жизни (и зачем им их содержать)? Куда вас понесло-то? Я же про grayscale говорил.
TATAPuH № 27
извините, видимо кто о чём а вшивый о :)
один из проектов сейчас, это как раз порт существующего 2д тулкита в canvas (понятно что о полноценном 3д в броузерах пока говорить рано), в том числе той части которая рендерит различные сейсмики (и динамику тоже), а веселее всего то, что одна из таргетных платформ это именно iPod и прочие пост ПС девайсы (нефтяники их очень любят, не знаю уж за что)

вот и прокоментировал, что всё это очень круто а вебГл для 2д обработки вообще замечательно, но вот не всегда и не везде выручает