SVG filterを使って全てのページをゲームボーイ風にするGreasemonkey

ゲームミュージックと生存確認をかねた画期的な: svgのfilterを使ってドット階調っぽい効果をつける がかっこよかったので、アレンジしてこんなGreasemonkeyを作ってみました。


全てのウェブサイトをゲームボーイ風にするGreasemonkey


インストールはこちらから http://userscripts.org/scripts/show/138971


このGreasemonkeyをインストールすると、画面左上にこうしたアイコンが表示されます。

それをクリックすると、閲覧しているウェブサイトがゲームボーイのようなドット絵風の画面になります。


アイコンをもう一度クリックすると元に戻ります。

利用上の注意点
  • 普通のGreasemonkeyGoogle Chromeなどでも使えるのですが、これはCSSSVG filterを利用しているので2012年7月現在 Firefoxのみ対応です。
  • 「全てのページ」とは言え、フレームを使ったページとFlashには対応していません。
  • あと画像処理が複雑で、動作が重くなるかもしれませんのでご注意ください。
    • 特にgifアニメ画像があると、かなり負荷が大きいです……。


Bookmarklet

Bookmarklet版も作ってみました。
Pixel Art filter - Hatena::Let

こちらはアイコンでの切り替え機能は無しで、元に戻す際はページを再読み込みしてください。


[どうぞご利用ください。]

ドット絵てきな解説


ゲームボーイは今から23年前の1989年に任天堂からは発売されたゲーム機で、当時の液晶画面はモノクロ4階調(4色)しか表示できませんでした。そのため、このGreasemonkeyでも全てのページを4色で表示されるように変換しています。
ただカラーが白黒になるのは仕方ないにしても
「4色だとガタガタになってしまうんじゃない?」

……と思ってしまうかもしれませんが、そこはタイルパターンというドット絵の技法でカバーしています。

タイルパターンとは

タイルパターンはこのように、少ない色数しか使えない環境でもピクセルの組み合わせて模様を作りグラデーションを表現するドット絵の基礎的な技法です。白から黒に変化するグラデーションをタイルパターンを使って表現すると









(2倍に拡大 上から順に4階調・7階調・13階調・25階調)

いずれも4色だけしか使っていませんが、こんな風にやりようによっては滑らかな階調を作ることができます。

ただ、頑張って25階調分のタイルパターンを作ってみたものの、その代わりに動作がすげー重くなってしまったために実際は階調を減らして、もう少し処理を簡略化させています。


この辺りの話はこちらに書いたのと、25階調版のSVG filterも置いてあります。
写真をゲームボーイ風にするCSS & SVG filterのデモ



技術的な解説

今回はそれぞれGreasemonkey/Bookmarkletではあるのですが、画像変換の部分ではJavascriptを使っているわけではありません。仕組みとしては、タイトルの通り SVG filter を CSSで指定しているだけ、という単純な構成です。

SVGとはなにか?

SVGとは Scalable Vector Graphics(スケーラブル・ベクター・グラフィックス)の略で、XMLで記述された画像形式のことです。ベクター系ということで、イラストや図などにも使われるのですが、アニメーションもできたりと様々な機能があります。
その中の一つが fliterです。

SVGのfilterとは

例えばこんな感じに使えます。


filterでぼかしをかけたサンプル

<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 100 80">
<title>SVG filterのデモ</title>
<defs>

<!-- filter要素の設定、IDはbokashiに -->
<filter id="bokashi">
	<!-- feGaussianBlur要素はガウスぼかしを行います -->
	<feGaussianBlur stdDeviation="2"/>
</filter>

<style type="text/css">
<![CDATA[
	/* fill は塗り、strock系は線の設定です */
	.face{fill:#FFDD5F;stroke:#FF591F;stroke-width:3;stroke-miterlimit:10;}
	.lip{fill:none;stroke:#BF3000;stroke-width:2;stroke-miterlimit:10;}
	.eyes{fill:#044F00;}
	/* イラストの各種設定はここまで */

	/* filterの設定 IDを指定します */
	.elm{
		filter: url(#bokashi);
	}
]]>
</style>
</defs>

<!-- イラストの部分はここから -->

<g><!-- g要素はそれぞれの要素をまとめるグループ化の役割があります -->
<circle class="face" cx="27.6" cy="40.7" r="17.1"/>		<!-- 円 -->
<ellipse class="eyes" cx="16.8" cy="39.8" rx="2.2" ry="4.3"/>	<!-- 瞳の楕円 -->
<ellipse class="eyes" cx="38" cy="40.2" rx="2.2" ry="4.3"/>
<polyline class="lip" points="23.6,49 27.3,51.8 31.4,49 "/>	<!-- 口 -->
</g>

<g class="elm">
<circle class="face" cx="72.6" cy="40.7" r="17.1"/>
<ellipse class="eyes" cx="61.8" cy="39.8" rx="2.2" ry="4.3"/>
<ellipse class="eyes" cx="83" cy="40.2" rx="2.2" ry="4.3"/>
<polyline class="lip" points="68.6,49 72.3,51.8 76.4,49 "/>
</g>

</svg>

通常の(X)HTMLと違い、fill(塗り)やstroke(線関連)など独特のプロパティはありますが、Adobe Illustratorに慣れているとどういう指定かは理解しやすいんじゃないかなと思います。で、注目する点はfilterで

<filter id="bokashi">
	<feGaussianBlur stdDeviation="2"/>
</filter>
	.elm{
		filter: url(#bokashi);
	}

filter要素にidをつけて、それをCSSで指定する、といった形式でそれを適用します。
今回は対象となる要素(右側の顔マーク)にぼかしをかける、という指定になっていますね。


SVGでは他にもどのようなfilterが使えるか?というとMicrosoftのデモページで色々と試すことができるので便利です。
Hands On: SVG Filter Effects

SVGのfilterを(X)HTMLに

先ほどまでの例では、SVGファイルの中でfilterを使っていましたが、このfilterを(X)HTMLにも適用することもできます。
こんな感じで、CSSでfilterを指定すると画像もテキストもページ全体にぼかしがかけられます。

ページ全体にぼかしをかけたサンプル

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>SVG filterのデモ</title>
<style>
body{
	/* SVGファイルを指定して、filterのIDを記述 */
	filter: url(blur.svg#bokashi);
}
</style>
</head>
<body>
(略)

先ほどのSVGファイルを指定し*1、さらにIDを書くとそのfilterが適用されます。


SVGのfilterはうまく利用していくと結構複雑なことが可能で面白いのですが、SVGファイル内ならモダンなブラウザは大抵対応しているものの、CSSでfilterを指定するのはまだFirefoxしかダメなのが残念なところなんですよね……。

SVG関連リンク

あと、SVG作成ソフトとしてはオープンソースInkscape が定番ですが正直言ってかなりとっつきにくいのが難点。しかし、こちらサイトはかなり詳しい解説サイトですので色々と参考になるかなと。
InkscapeでDesign - Inkscapeの使い方 - もくじ

><

*1:インラインSVG要素があればそちらでも可