Image Resizing Algorithm
経緯
Retina対応等が進む中、大きい画像をWeb上で縮小表示し高解像度ディスプレイに対応するケースが多々あります。
がしかし、ブラウザ固有のリサイズのアルゴリズムや表示画像サイズによっては、レンダリングされた画像がぼやけることも。
そこで、リサイズのアルゴリズムを正しく理解した上で、適切な対応方法を検討したい、という話なのです。
縮小表示の例
(サンプル画像が古いことへの突っ込みは受け付けません。久しく絵と呼べるものを描いていないのです。)
Chromeで見た場合
- width: 140px は実画像サイズの1/2なので、4ピクセルが1ピクセルに縮小される計算
- ⇒ ボケない
- width: 145px は実画像サイズから表示サイズに縮小する際にピクセル数が割り切れない少数になってしまう
- ⇒ エッジがボケた感じになる
- width: 145px に style属性で image-rendering: pixelated; を指定すると、縮小アルゴリズムが「最近傍 (Nearest Neighbor)」に指定される
- ⇒ エッジがギザる
IEで見た場合
ChromeのリサイズアルゴリズムがBilinearやBicubicといったエッジを滑らかにするアルゴリズムであるのに対して、 IEは元々Nearest Neighborのような単純なアルゴリズムを使っているようで、width: 145px をIEで見てもボケるというよりギザる感じでした。 (※個人的な主観です)
拡大表示の例
拡大表示の方がアルゴリズムの違いがわかりやすいです。
- 原寸の画像はあえてドットが分かりやすいようにしている 100x100pxの画像
- そのままブラウザで3倍のサイズに指定して表示すると、ドットのギザギザはブラウザのレンダリングの仕様によってぼかされて表示される
- style属性で image-rendering: pixelated; を指定すると、原寸のピクセルをそのまま拡大され、ドットがはっきり表示される
image-renderingの指定について
ブラウザ上のリサイズアルゴリズムを指定するのに使っていた image-rendering ですが、 まだ実験段階、開発途上といったところみたいです。
値 | 説明 |
---|---|
auto |
|
crisp-edges | |
pixelated |
各ブラウザに対応させたい場合
.pixelated { -ms-interpolation-mode: nearest-neighbor; /* IE8+ */ image-rendering: -webkit-optimize-contrast; /* Safari (WebKit) */ image-rendering: -moz-crisp-edges; /* Firefox (Gecko) */ image-rendering: -o-crisp-edges; /* Opera 12.x */ image-rendering: pixelated; /* Chrome 41+, Opera 29+ (CSS4) */ }
参照:http://memo.sdn-project.net/post/113148316679/pixelated
よく使われるリサイズアルゴリズム
滑らか度 | 名称 | 説明 |
---|---|---|
低 | NearestNeighbor (最近傍補間) | |
中 | Bilinear (バイリニア補間) | |
高 | Bicubic (双三次補間) | |
高+ | Lanczos3 |
参照:http://imagingsolution.blog107.fc2.com/blog-entry-142.html, http://www.geocities.jp/numada777/ip05.html, http://www.amedama.com/blog/20110220392.html
対応案とまとめ
縮小表示
- 理想は表示サイズの2倍3倍といった整数値でピクセル表示ができる元画像サイズを用意する(とにかくこれ)
- ユーザーに入稿してもらったものを表示する際や1つの画像を同一画面で使いまわす際、縮小時にエッジがボヤける(特に線画)と言った場合は、 CSSで image-rendering を指定するといった手法もあり(※あまりおすすめできない)
拡大表示
- 通常の画像の場合は表示画像より大きいもの(Retina対応するのであれば4倍)を用意する
- ドット絵等あえてジャギー(ギザギザ)を見せたいものは、CSSで image-rendering を指定する方法もあり
Goのresizeパッケージ、giftパッケージを使って画像ファイル自体のリサイズ処理も色々と試したので、その話も書いておきたい気持ちある。