Retina/非Retinaへの画像の振り分け方法の実験

公開日:

RetinaディスプレイのiPhoneやMacでウェブページを見たときに画像がぼやけた(ぼけた)ように見える理由は、ウェブサイト側がRetinaに対応した画像の使い方をしていないのが原因です。

Retina用には表示サイズの4倍のピクセル数をもつ画像を使えばきれいに表示できますが、それだと非Retina用にはデータ容量が大きすぎるのでデバイスによって表示する画像を振り分ける必要が生じます。そこで、振り分け方法について試しました。

対策と課題

  1. Retinaディスプレイできれいな画像を表示するには、
  2. 縦横2倍(ピクセル数は4倍)の画像を用意して、それを実サイズの¼で表示させるという方法が唯一。
  3. でもそれだと Retina以外のユーザーは必要以上のデータを受信することになる。
  4. 閲覧デバイス/ディスプレイによって読み込ませる(表示させる)画像を振り分けるのが効率的。
  5. では、その方法をどうするか?というのが課題になると思います。

画像と、振り分け条件

このページの画像は、iPhone 5を縦にしたときは 320 x 240(実際はもう少し小さい)、パソコンから見ると 640 x 480ピクセルで表示されます。きれいに見えるための必要な大きさをまとめました。

画像表示サイズと必要な大きさ
ブラウザの表示サイズ きれいに見えるために
必要なピクセルサイズ
非Retina 640 x 480 640 x 480
Retina/iPhone 5 320 x 240 640 x 480
Retina/Mac 640 x 480 1280 x 960

3種類のデバイスそれぞれに最適な画像を振り分けるのが目標です。

Retina かどうかだけで振り分けると、iPhoneには大きすぎるデータになるので、Retina かつ、ウインドウ幅が569px以上は、1280 x 960を表示するようにしたいです。

569pxは、iPhone 5の画面サイズが320 x 568 CSSピクセルなのでそれ以上ということ(Retina Mac/iPad miniの最小サイズにするべきか? …検討中)。

画像振り分けに使う2カットの写真
どちらの画像が使われているか分かりやすいようにサイズを画像上に明記してあります。

画像を振り分ける方法を試す

写真下に画像を表示しているソースコードを書いています。画像のパスやaltタグなどは省略しています。

結果はすべて、2014年5月2日現在のものです。将来は変わっている可能性があります。

srcset

srcsetで指定された条件にあうときに画像が読み込まれます。

2x, 569w, 569w 2x の3パターンを試します。
569w 2x がうまくいくのが理想です。

ファイル名 = 大きさです。
・ 640x480.jpg
・ 1280x960.jpg

※ 2014年5月現在、Google ChromeWebKitしか対応(一部の指定方法のみ)していないのでブラウザによって効果が分かれます。

srcset(2x)デバイスピクセル比 による振り替え

デバイスピクセル比 2x(2倍)のときは、1280x960.jpgが読み込まれます。Retinaのデバイスピクセル比は2倍です。

srcset 2x 表示テスト
<img src="640x480.jpg" srcset="1280x960.jpg 2x">
srcset(2x)の結果
必要なデータサイズ 表示されている画像
非Retina 640 x 480 640 x 480 ✓
Retina/iPhone 5 640 x 480 640 x 480 ✓
Retina/Mac 1280 x 960 Chrome, WebKit 1280 x 960 ✓
その他 640 x 480 小さい

srcset(569w)ウインドウサイズ による振り替え

ウインドウサイズ(Viewport幅)が569ピクセル以上なら1280x960.jpgが読み込まれます。

srcset 569w 表示テスト
<img src="640x480.jpg" srcset="1280x960.jpg 569w">
srcset(569w)の結果
必要なデータサイズ 表示されている画像
非Retina 640 x 480 Chrome 1280 x 960 大きい
その他 640 x 480 ✓
Retina/iPhone 5 640 x 480 640 x 480 ✓
Retina/Mac 1280 x 960 640 x 480 小さい

srcset(569w 2x)ウインドウ幅とデバイスピクセル比 による振り替え

srcset 569w 2x 表示テスト
<img src="640x480.jpg" srcset="1280x960.jpg 569w 2x">
srcset(569w 2x)の結果
必要なデータサイズ 表示されている画像
非Retina 640 x 480 640 x 480 ✓
Retina/iPhone 5 640 x 480 640 x 480 ✓
Retina/Mac 1280 x 960 Chrome, WebKit 1280 x 960 ✓
その他 640 x 480 小さい

retina.js

retina.jsをダウンロードして低解像度/高解像度の画像を準備。サイトに従ってソースを書く。

retina.js によりRetinaデバイスが検知されて、Retinaの時だけ高解像度の写真がダウンロードされます。

ファイル名と大きさです。
・ notrespassing = 640x480
・ notrespassing@2x.jpg = 1280x960

retina.js 表示テスト
<img src="notrespassing.jpg">
retina.jsの結果
必要な
データサイズ
表示されている
画像
非Retina 640 x 480 640 x 480 ✓
Retina/iPhone 5 640 x 480 1280 x 960 大きい
Retina/Mac 1280 x 960 1280 x 960 ✓

srcset + retina.js

retina.js用のファイル名をつけた画像をsrcset属性を使って記述するとどうなる?
↠retina.js と同じ結果でした。

ファイル名と大きさです。
・ notrespassing = 640x480
・ notrespassing@2x.jpg = 1280x960

srcset 569w 2x + retina.js 表示テスト
<img src="notrespassing.jpg" srcset="notrespassing@2x.jpg 569w 2x">
srcset(569w 2x) + retina.jsの結果
必要な
データサイズ
表示されている
画像
非Retina 640 x 480 640 x 480 ✓
Retina/iPhone 5 640 x 480 1280 x 960 大きい
Retina/Mac 1280 x 960 1280 x 960 ✓

考察

Retina/Mac優先なら retina.js推し。しかし、iPhoneには大きすぎるデータを送ってしまう。

ブラウザが対応すれば srcsetの方が良いと思うけど、srcsetはまだ草案段階で将来的にどうなるか分からない。

Retina/Mac優先なら、とりあえず、srcset + retina.js方式で記述しておいて、srcsetが主要ブラウザに実装されたら、retina.jsを削除するのはどうだろう?

iPhone優先なら、srcsetを書いて実装されるのを首を長くして待つ。

メディアクエリなんかを駆使してうまいことできないだろうか…?