Hatena::Groupsubtech

ういはるかぜの化学

Sunday, January 22, 2012

[]Metro style appsの解像度に合わせたスケーリング 17:29 Metro style appsの解像度に合わせたスケーリング - ういはるかぜの化学 を含むブックマーク はてなブックマーク - Metro style appsの解像度に合わせたスケーリング - ういはるかぜの化学

このエントリの内容はWindows Developer Previewの仕様を元にしています。今後Betaリリース時には変更される可能性があることに注意してください。

昨今のスマートフォンタブレットは画面が高精細化してきつつあり、アプリケーション解像度に応じた対応を迫られ、iPhone 4以降ではRetina Display対応といった風にアプリケーション対応しているのを見かけるようになりました。

Windows 8(コードネーム)はこれからリリースされるOSですのでそのあたりも考慮されています。そこでMetro style appsにおいてはアプリケーションはどのようにして対応するのかガイドライン(MSDN Content Issue)があるのでちょっと解説してみます

スケーリングのされ方

Metro style appsでは解像度と画面の物理サイズによって100%,140%,180%と3段階の拡大率を持ち自動的に適用されます。拡大というのはブラウザの拡大みたいなものです。

たとえば10.6インチの1366x768では拡大なしですが、同じ物理画面サイズで1920x1080の場合には140%に拡大されるといった感じです。また、同じ1920x1080でも10.6インチ(スレートサイズ)と23インチ(デスクトップ)では解像度(DPI)が違うので拡大率も違ったりします。この辺は別に書きます(→Metro style appsと解像度と画面サイズと画面解像度 - ういはるかぜの化学 - subtech)

拡大率 画面サイズ
100% 10.6インチ/1366x768, 23インチ/1920x1080
140% 10.6インチ/1920x1080
180% 10.6インチ/2560x1440

アプリケーションですべきこと

自動的に拡大されると書きましたが、ただ拡大するだけではキレイになるとは限らないのでアプリケーション側での対応も必要となりますガイドライン(MSDN Content Issue)によれば以下のことをするようにと書かれています

スケーラブルなベクターグラフィックスを使う

解像度依存ベクター画像を使いましょうという話です。ベクター画像であれば伸び縮みさせてもジャギジャギしたりもやもやしたりしません(Windowsがうまくレンダリングします)。

HTMLアプリケーションを作る場合にはSVGを、C#などで作る場合にはXAMLを使うことで実現します。

アプリケーションパッケージからビットマップ画像を読み込む

ビットマップ画像(JPEG,PNGなど)に特定のルールに従って名前をつけておくと自動的に拡大率の状態に応じて読み込むファイルを変える機能があります

この機能によって拡大率の違いによってサイズの違う画像を読み込むことができます

たとえばHTMLでは以下のようにimg要素でファイル /img/Image.png を参照します。

<img src="/img/Image.png" alt="Image" />

この時、実際に読み込まれるファイルは /img/Image.png だけでなく以下の拡大率によってバリエーションも参照されます

この例のようにファイル名に .scale-{100,140,180} を含めるか、フォルダとして scale-{100,140,180} として分けるか好きな置き方を選ぶことができます。これはHTMLからの参照だけでなくCSSからの参照(たとえばbackground-imageプロパティ)も対象となります

外部の画像を参照する場合メディアクエリーを使う

外部つまりリモートにある画像を参照する場合には拡大率によって自動バリエーション検索する機能は動作しません。

そこでHTML ベースMetro style appsでCSSから参照する場合にはメディアクエリーで解像度に応じて読み込む画像を切り替えます

たとえばMSDNにある例だと以下のようなCSSになっています

/* CSS - 拡大率に応じてリモートの画像を読み込む */
@media all and (max-resolution: 134dpi){
    /* 100%の拡大率のとき100%用の画像 */
    .imageBackground {
        background-image: url('http://www.fabrikam.com/foo.png?s=100');
    }
}
@media all and (min-resolution: 135dpi) {
    /* 140%の拡大率のとき140%用の画像 */
    .imageBackground {
        background-image: url('http://www.fabrikam.com/foo.png?s=140');
    }
}
@media all and (min-resolution: 173dpi) {
    /* 180%の拡大率のとき180%用の画像 */
    /* MSDNのサンプルでは174dpiになっているが173dpiでないと動かない */
    .imageBackground {
        background-image: url('http://www.fabrikam.com/foo.png?s=180');
    }
}

min-resolution/max-resolutionの値が謎のdpiになっている理由は別に書くことにしますが、メディアクエリーのパターンとしては謎のdpiの指定も含めてこのようになります

ユーザー画像ファイルシステムから取り出すときにはサムネイルAPIを使う

ユーザーが持っている画像を動的に読み出して使う場合にはWinRTにあるサムネイルAPIを使いますサムネイルAPIWindows現在の拡大率に最適な画像を返します。

サムネイルAPIというのはWindows.Storage名前空間にあるStorageFileクラスが持つ、GetThumbnailAsyncメソッドのことです。StorageFileクラスフォルダなどから参照したときにとれるものです(よくあるFileクラス的なもの)。

参照:no title

画像を実行時に読み込む場合には拡大率をみて読み込む

JavaScriptなどから動的に画像を読み込む場合にはコード現在の拡大率によって画像の参照をコントロールする必要があります

現在の拡大率はWindows.Graphics.Display.DisplayPropertiesクラスResolutionScaleプロパティを参照することで得ることができます

switch (Windows.Graphics.Display.DisplayProperties.resolutionScale) {
    case Windows.Graphics.Display.ResolutionScale.scale100Percent:
        console.log('100%'); break;
    case Windows.Graphics.Display.ResolutionScale.scale140Percent:
        console.log('140%'); break;
    case Windows.Graphics.Display.ResolutionScale.scale180Percent:
        console.log('180%'); break;
}
画像には幅と高さを指定する

拡大率で読み込む画像が変わったりした場合レイアウトが崩れるのを防ぐため、画像には幅と高さを指定するようにします。

グリッドをつかう

要するにメジャーグリッドを20px、マイナーグリッドを5pxずつとして画面を設計することで拡大した場合にも中途半端な値(たとえば23px*1.4倍=32.2pxに対して25px*1.4倍=35px)にならずピクセル丸めとズレのようなものが発生しなくなってきれいです。

アプリケーションでしてはいけないこと

スケーリング考慮する上で逆に避けるべきこともガイドラインには書かれています

小さい画像を拡大時に使うこと

小さい画像というか100%用の標準的なサイズだけしか用意されていない場合、高解像度環境でスケーリングが必要な場合自動的に拡大されてぼやけた見た目になることになります。ということで画像は各拡大率にあわせたものを用意しておきましょう。

iPhoneで言うとRetina非対応アプリiPhone 4で実行したようなことになるのでという話です。

大きい画像を小さくして使うこと

小さい画像を高解像度で使うのと逆に、高解像度用の画像を低い拡大率で使うと縮小するとジャギジャギしてしまうので避けましょう。たとえば180%のパターンだけ用意してそれを140%と100%でも使い回す、といったことです。

ただし例外的に写真画像は縮小しても見た目上問題ないのであればよいでしょう。

5pxの倍数以外でサイズを指定すること

上にも書きましたが5pxの倍数以外でサイズを指定すると拡大したときにズレが生じてしまますので避けましょう。

スケーリングの状態を試す

スケーリングの仕組みが用意されていてもどうやってテストすれば?となるわけですが、シミュレータには解像度画面サイズを想定した設定が用意されていてこれでテストすることができます

f:id:mayuki:20120122171004p:image

どうぞご利用ください。

参考までに設定時の状態を以下にまとめておきます

拡大率 設定
100% 10.6インチ/1366x768, 12インチ/1280x800, 23インチ/1920x1080, 27インチ/2560x1440
140% 10.6インチ/1920x1080
180% 10.6インチ/2560x1440

トラックバック - http://subtech.g.hatena.ne.jp/mayuki/20120122