WEB上でドット絵を拡大表示する
この記事は2013年6月9日に書かれています。

設定なし

設定あり
ドット絵をくっきり表示させるには、CSS で以下の設定を行います。
ただし、この設定は HTML5+CSS3 の標準ではありません。
現在この方法が使えるブラウザでも、今後使えなくなる可能性があります。
(実際、Chrome は過去のバージョンで動作したにもかかわらず、現在のバージョンでは動作しません)
img { -ms-interpolation-mode: nearest-neighbor; // IE image-rendering: -webkit-optimize-contrast; // Safari image-rendering: -moz-crisp-edges; // Firefox image-rendering: -o-crisp-edges; // Opera image-rendering: crisp-edges; // CSS3 (最新版で廃止) image-rendering: pixelated; // CSS4 (まだ草案段階) }
サポートしないブラウザは、Javascript で解決できるかもしれません。
現状では、Chrome だけですが、以下のスクリプトを使うことで解決できます。
<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>
CSS も Javascript も、ここに示したコードではすべての画像を対象にしています。
CSS は 先頭の img を、javascript は中央あたりの $("img") を書き変えれば、特定の class を持つ img のみを対象にできます。
詳細な話題の目次
CSS の記述方法について
さて、ネット上を調べると、「ドット絵を綺麗に拡大する」方法について、さまざまな…全く異なる…情報が見つかります。
ドット絵を綺麗に拡大する(長いので、以下「ドット絵の拡大」と書きます)方法は、CSS3 の策定中にコロコロと変更され…「時期尚早」と判断され、CSS4 に先送りになりました。
これが、情報が書かれた時期によって、内容があまりにも違う原因です。
CSS3 はまだ草案の段階で、勧告に至っていません。つまり、まだ変更される可能性があります。ただし、ある程度の同意は得られた状態ですので、「独自仕様」として機能を前倒しで実装するのは許されています。
最初に書いた CSS では、似た行が並んでいます。これは、各ブラウザが独自実装…つまり、わざと互換性のない形で実装しているためです。
CSS4 になると、まだ策定中なので実装しないことが推奨されています(実験的に実装することは構わない)。ドット絵の拡大方法が CSS4 に先送りされた、ということは、現状のブラウザで実装しない方がよい、と言う意味になります。
Chrome が CSS をサポートしなくなったのは、「実装しない方がよい」という勧告を正しく守っているからなのでしょう。
最初に書いた CSS は、 IE 現状では Chrome を除いて動作します。
現状、というのが2013年6月9日時点であることに注意してください。先にも書いたように、CSS の策定方針がコロコロ変わるのが問題で、この記事もすぐに時代遅れになる可能性があります。
optimizeSpeed
最初に、CSS3 の策定方法について書いておきます。
CSS3 は現在も策定中であり、決定はされていません。
策定中の最新版は、Editor's Draft として公開されています。
これは Draft、つまり提案に過ぎないため、公式な記録すら残っていません。常に最新版公開のみです。
策定中のバージョンは、ある程度まとまると公開されます。こちらは記録が残ります。
最初の公開バージョンの日付は、2009年7月。
このバージョンでは、ドット絵の拡大の指定方法は盛り込まれていませんでした。
しかしどうやら、その後の Draft でドット絵の拡大について議論があったようです。
記録に残っていないため詳細がわからないのですが、ここで image-rendering プロパティが導入され、設定値として optimizeSpeed と optimizeQuality 、そして auto の3つの値が定められた様子です。
optimizeSpeed は速度優先。ドット間の補間などを行わず、ドットが目立つ方法を意味します。
optimizeQuality は品質優先。ドット間の補間を行い、ドットがぼやけるようにします。
auto は、状況に応じてブラウザが調整する、と言う意味です。
これ、Draft で提案されただけの模様で、その次の公開バージョンでは「optimeizeSpeed と optimizeQuality は非推奨」と明記されました。この2つの値はエラーにはしないが、auto と同じ扱いとなるよう求めています。
ネット上には、optimizeSpeed を指定することでドット絵を拡大できる、としているページもあるのですが、すでに非推奨の値ですので動作しないことになります。
optimize-contrast
2番目の公開バージョンは 2011年2月。
ここで、公開文書としてははじめて、image-rendering プロパティが提示されました。
指定できる値は auto と optimize-contrast の2つです。
optimize-contrast は、「シャープなラインを維持し、色をスムージングしない」ように求めています。その主な利用目的として、ドット絵の表示も挙げられています。
シャープなラインを維持し…というのは微妙な言い回しですが、つまり EPX や 類似アルゴリズムを使用することを想定しているようです。
先に書いたように、optimizeSpeed と optimizeQuality は非推奨の値と明記されました。
おそらくは、「速度優先」と「品質優先」という言葉では、処理内容が不明瞭で非互換性につながるためでしょう。
実際、GPU を使用して高速に拡大を行うと、補間を伴う高品質でしか行えません。ドット絵のために低品質の拡大を行うと、CPU を使うことになり低速になります。
webkit ブラウザ(safari, chrome) では、 -webkit-optimize-contrast という設定を行います。
この記述の根拠は、この公開文書にあるようです。
どうも ver.20 で導入されて、ver.22 までは正しく動作したようなのですが、ver.23 以降は動作しないようです。
CSS3 の草案から外されたので、プログラムのソースコード上も扱いが変わり、通常は動作しないようになっている、と言うことのようです。
crisp-edges
さて、3番目の公開バージョンは、5か月後の2011年7月。
image-rendering の取る値は auto と crisp-edges に変わりました。
説明も少し変わり、「画像のエッジを維持し、色をスムージングしない」となっています。
値の名前の変更も含め、重要なのは「コントラスト」(つまり、色をスムージングしない)ではなく、エッジを維持することだ、と明示したかったのでしょう。
ここで、「画像のエッジを維持し」と明記されたのは、ドット絵をドット絵のまま拡大する、ということを想定していたように思えます。
つまり、EPX などのアルゴリズムを使わず、あえて低品質な画像拡大を行え、ということ。
しかし、エッジを維持する、という言葉は受け取る人によって異なるでしょう。元のドット絵の形が変わってはならない、と考えることもできますし、斜めに連続したドットを斜め線だと類推し、「はっきりとエッジを出した」画像を表示しようとする…つまり、EPX アルゴリズムを使用するほうがよい、と考えることもできます。
ここでも、optimizeSpeed と optimizeQuality は廃止で、auto と同じとなる、と明示されています。
しかし、optimize-contrast をどのように扱うかは示されていません。
FireFox が使用する -moz-crisp-edges と、Opera が使用する -o-crisp-edges はここに由来します。
crisp-edges 自体を設定するのも、いつか全ブラウザでこれが設定できるようになるから、と言う期待なのですが…
そして姿を消した
4番目のバージョンは、3番目からわずか2か月後の 2011年 9月です。ここで、image-rendering プロパティは忽然と姿を消しました。
いったい、この2か月の間に何があったのでしょう? 草案から消えてしまった、ということは、image-rendering プロパティを使用するのは不適切である、と言う意味になります。
chrome では、実際に動作していたコードを、動作しないようにしてしまいました。バグじゃないか、と騒いでいる人も多いようですが、勧告に従っているのだと思われます。(根拠は次の章で)