Перевод картинки в серый средствами CSS
Экспериментировал в рамках прототипа для рабочего проекта с преобразованием изображения в серую гамму. Вообще, конечно, есть тег 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 и тем более десятую версию, но я где-то читал, что из «десятки» убрали фильтры, поэтому я, на всякий случай, поставил режим совместимости с девятой версией в коде.
Протестировал встроенные браузеры.
«Андроид» 2.3.6 — не поддерживает ни один из способов.
«иОС» 5.1 — тоже.
WinPhone 7.5 — тоже.
MeeGo 1.2 — тоже.
Комментарий для Евгения Степанищева:
Правая картинка становится цветной, если навести на неё мышью.
Opera 11.61.1250 Win7
Комментарий для Евгения Степанищева:
Хм, говорят, Андроид начал поддерживать SVG только с 4-й версии. Раньше разве что через object. iOS вроде как SVG поддерживает, но как именно, я не знаю. Наверное, стоит продолжить эксперименты с SVG. А ещё на телефонах есть Opera Mobile и Opera Mini :).
Win7 IE9: работает левый способ, правый все время цветной.
ЭксперИмент
Комментарий для Евгения Степанищева:
что W7 IE9, что W8 IE10 левая серая становится цветной эсли навести мишкой. W7 FF11 обе серие но с мишкой становится цветними.
Комментарий для SiMM:
Ну да, там hover.
Комментарий для Eyeless:
Спасибо! Глазастый!
Комментарий для GreLI:
«Поддерживать SVG» это как «поддерживать CSS». У SVG туча версий и расширений. Что-то может поддерживаться, что-то другое — нет. Фильтры, видимо, не поддерживаются.
Хром 17.0.963.79 Мак Лев не работает.
Комментарий для Никита:
В «Хроме» только с версии 18 будет работать.
В «Хроме» будет работать следующее:
Сделал способ для «Хрома», позволяющий переводить картинку в серый через подключение CSS-стиля к SVG. Обновил статью.
Таким образом, единственный настольный браузер, который никак не охвачен — «Сафари», в нём обещают поддержку фильтров SVG только в шестой версии.
Сам искал простенький метод перевода в серые тона. Но простыми манипуляциями с CSS не вышло. Будем ждать когда разработают нормальные фильтры.
Комментарий для www.orcinus.ru:
Самый простенький — грузить в «канвас». Много где работать будет.
http://vhardy.github.com/presentations/html5-now-next-2011/index.html#/28
интересна конечно вся презентация, но даю ссылку сразу на последний слайд (содержит ссылки на семплы)
П.С. фильтры и канвас это конечно круто, вебГл ещё круче
но к сожалению сносно работает только в десктопе
Комментарий для TATAPuH:
ВебГЛ — это контекст канваса, то есть его часть.
Комментарий для TATAPuH:
И не очень понятно зачем в этой задаче привлекать ВебГЛ.
Комментарий для Евгения Степанищева:
хм, э хм
ну скорость как бы ? не ?
картинка 100x100 обрабатывается достаточно быстро
1600х1200 уже очень даже не быстро
обработка 1000000х10000000 просто не работает (естественно что работаем только с видимой частью, тайлы и так далее,но — там чуть чуть тут немного и всё, тормозим)
для этого и ВебГЛ, доступ к шейдерам, а значит к GPU и паралельности
Комментарий для Евгения Степанищева:
в любом случае, на пост PS это пока не работает, а жаль (под термином «пост PS», я имею ввиду всяческие айПады и андроиды разные)
поэтому большая часть пиксельного рендеринга обычно уходит в облака (на сервера)
как ни странно получить готовый тайл из облака, обычно быстрее чем его подготовить локально через фильтры (если они есть) или поПиксельный доступ
Комментарий для TATAPuH:
Ну так она и 2Д-канвасом быстро обработается. И фильтром, если GPU использовать. Причём тут ВебГЛ?
Комментарий для Евгения Степанищева:
по ссылке не ходил но осуждаю :)
на 28 слайде презентации есть ссылка
Evan Wallace’s WebGL filters
http://evanw.github.com/webgl-filter/
вы точно уверенны что 2д канвас не проигрывает по скорости , и что SVG предоставляет фильтры по умолчанию на все случаи жизни ?
Комментарий для TATAPuH:
По ссылке я был, там ничего особенного.
Да я в теме, знаю и что такое и ВебГЛ, и СВГ, и 2Д-канвас. Всё это вполне ускоряется через GPU, свет клином на ВебГЛ не сошёлся.
Комментарий для Евгения Степанищева:
2D канвас в целом и пиксельный доступ в частности, не ускоряется через GPU (на данный момент только ослик старается всегда работать через GPU до тех пор пока нет обращения к памяти (к пикселям))
http://upload.wikimedia.org/wikipedia/commons/d/d9/Seismic_wave_prop_mine.gif вот картинка для затравки (но представьте что она увас на весь экран)
тоже казалось бы просто «фильтры и попиксельный доступ»
лет 5 назад витали подобные настроения, мол в десктоп стремительно ворвался WPF теперь заживём, всё мол само собой ускорится засчёт GPU, нет
всё само собой не случается
Комментарий для TATAPuH:
Вы мне вещи какие-то странные объясняете…
Во-первых, можно ускорять заливку, наложение текстур и так далее, то есть чисто двухмерные штуки. 2D-видекарты справлялись с этим ещё десять лет назад (всякие Matrix Millenium). Это к вопросу о том что можно ускорить на «плоском» канвасе.
Во-вторых, есть только воображаемая разница. Фильтр размытия у SVG или CSS делается ровно теми же средствами, на том же GPU, как и WebGL-фильтры. WebGL — это просто более низкий уровень и всё.
И, да, я уверен, что фильтры SVG содержат фильтры не на все случаи жизни (и зачем им их содержать)? Куда вас понесло-то? Я же про grayscale говорил.
извините, видимо кто о чём а вшивый о :)
один из проектов сейчас, это как раз порт существующего 2д тулкита в canvas (понятно что о полноценном 3д в броузерах пока говорить рано), в том числе той части которая рендерит различные сейсмики (и динамику тоже), а веселее всего то, что одна из таргетных платформ это именно iPod и прочие пост ПС девайсы (нефтяники их очень любят, не знаю уж за что)
вот и прокоментировал, что всё это очень круто а вебГл для 2д обработки вообще замечательно, но вот не всегда и не везде выручает