WEB上でドット絵を拡大表示する
目次
pixelated
image-rendering 自体が姿を消してからほぼ1年後、、CSS4 草案の最初のバージョンが発表されました。そして、image-rendering はここで再び姿をあらわしました。
CSS4 に移行になった、ということは、議論が明らかに不足しており、互換性を保ったまま各ブラウザが実装することはできない、と判断されたことを意味します。
(ここまでに書いたことを読んでいただければ、ドット絵の扱いのややこしさが理解していただけるでしょう。)
CSS3 すらまだ勧告に至らない状態で、CSS4 は実装しないように求められています。
実際、chrome や safari が使用している webkit ライブラリでは、image-rendering は CSS4 向けの機能として、特別な方法でコンパイルしなくては使えないように変更されています。
さて、CSS4 の image-rendering では、auto と crisp-edges に加え、「pixealted」が指定できるようになっています。
crisp-edges との違いは2つ。明示的に「ニアレストネイバー法か、それに類するアルゴリズムを使用する」と書かれたこと、縮小時には auto と同じ動作とする、と明記されたことです。
縮小時! そうです。今までの議論はすべて「ドット絵の拡大」で、縮小のことが全く考慮されていませんでした。
複数ドットを混ぜた色で表現すれば、「コントラストの維持」ではなくなります。かといって、ドットを間引けば「エッジの維持」ではなくなります。crisp-edges で、いったいどうやって縮小しろと言うのでしょう?
ここら辺の議論不足も、CSS3 から姿を消した理由のようです。
しかし、「ドット絵を拡大したい」と言う用途では、pixelated 指定が本命であるように思います。そこで、冒頭の CSS コードでは、最後に pixelated 指定を入れてあります。「将来に期待して」crisp-edges を入れるくらいなら、こちらを入れておいても損はないでしょう?
…気が早すぎるかな (^^;
JavaScript について
chrome は CSS を理解しませんが、JavaScript で同等の動作が可能です。
というのも、ドット絵の拡大は、CSS の機能としては削除されましたが、JavaScript の機能としては「標準」として残っているためです。
今後、同じように CSS でドット絵の拡大ができないブラウザが現れた場合、Javascript の調整で解決できる可能性があります。
設置方法
というわけで、冒頭に書いたプログラムの使い方。
プログラムの動作前提として、jQuery が必要です。1.7.2 と 2.0.2 で動作確認しました。多分一般的なバージョンなら動きます。
以下のコードを、head 内に記述します。
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
さて、冒頭のプログラムをもう一度引用しておきましょう。
<script type="text/javascript"><!-- if(navigator.userAgent.indexOf("Chrome")>0) $(window).load(function(w,h,c,x,y){w="width";h="height"; $("img") .map(function(v,d){c=$("<canvas>")[0];x=c[w]=d[w];y=c[h]=d[h];v=c.getContext("2d"); v.webkitImageSmoothingEnabled=!1;v.drawImage(d,0,0,x,y);$(c).replaceAll(d)})}) --></script>
上のコード全体を、HTML の中に書いてください。head 内でも body 内でも、どこでも構いません。
ページ内の全ての画像を読み込み終わったタイミングで動作しますので、HTML の一番最後に書くのがおすすめです。
中央あたりに $("img") と書いてある行があります。ここは、環境に合わせて書き変えてください。
記述方法は CSS に準じます。つまり、 class="dot" を対象とする場合、$(".dot") とします。
技術解説
先のコードは、短くするために読みにくくなっています。
同じ内容を、読みやすくしたコードを示します。
<script type="text/javascript"><!-- if(navigator.userAgent.indexOf('Chrome')>0){ // chrome のときだけ $(window).load(function(){ // 画像全部読みおわったら $("img").map(function(v,d){ // 全部の img タグに対し var c = $("<canvas>")[0]; // canvasを作って var x = c.width = d.width; // img と同じ大きさにする var y = c.height = d.height; v=c.getContext("2d"); // canvas の 2d context を得て v.webkitImageSmoothingEnabled=false; // 「スムージングなし」を設定 v.drawImage(d,0,0,x,y); // img 画像を、canvas に拡大コピー $(c).replaceAll(d); // img タグを canvas に置き換え }) }) } --></script>
コメントを入れたので、内容はだいたい理解していただけるかな、と思います。
UserAgent を調べて、Chrome 以外では動作しないようになっています。Chrome であっても、UserAgent 偽装していると動きません。
出来るだけ小さなコードにしたかったから、必要最低限のことしかやっていない、とも言えます。
「スムージングなし」の設定は、Javascript の現在の草案では ImageSmoothingEnabled で制御できることになっています。
ただし、制御できるのは「スムージングを行うか否か」ということだけ。スムージングしない、ということが、必ずしもニアレストネイバー法を使うことを意味してはいません。オプションがどのような意味を持つのか、ちゃんと規定されていないのです。
また、現状ではまだ草案に過ぎないため、「Chrome の独自拡張」扱いで、頭に webkit を付けた名前を使用します。ちなみに、moz で始めると Firefox でも同じ動作をします。
上のコードで「方法論」は示せたと思いますので、UserAgent 偽装に対応するとか、ページ全体の読み込みを完了する前に綺麗なドットで表示するとか、そういうのは各自やってください。
コードサイズも増えているし、何よりも「細かな技法」を入れているために説明には向かないのだが、ページの読み込み完了を待たずに起動するため、待たされる時間が短い。
知りたい人は最初のページのHTMLソースを見て、自分で理解してください。
(記事冒頭の h1 タグの下に書き込んであります)
ライセンス
CSS に関しては、他のサイトが紹介しているのと大差ないので権利主張しません。自由に使ってください。
Javascript コードに関しては、コピペして使うのや、「こんな方法がある」という紹介は自由だけど、元ネタとしてこのページを明示してもらえるとありがたいです。もっとも、強制ではありません。