2012/02/08

Android:画面密度によるリソースのスケーリング

解像度にあったサイズを割り出すには下記の比率を覚えておくと便利です。
3:4:6:8
左から ldpi, mdpi, hdpi, xhdpi となります。

mdpiで100pxの画像をhdpiでも同じ見た目に仕上げたい場合は
4:6=100:x
4x=600
として x=150px が求められます。

もう少し掘り下げてみます。

開発者はどのプラットフォームでも同じ動作をするようにアプリを作成する必要があります。
UIについても同様に「特定の端末でレイアウトが崩れる」といった問題を避けなければい
けません。
今回はマルチ画面対応を実現するために欠かせない「画面密度」「解像度」についてです。

・画面密度
画面の物理的な領域内におけるピクセル数。
通常dpi(ドット数/インチ dot per inch)と呼ばれます。
画面密度の低い(lowな)画面は、画面密度の高い(highな)画面と比べて、領域あたりのピ
クセル数が少なくなります。
Androidは、画面密度の程度をlow, medium, high, extra highの4つに分類しています。
それぞれの画面密度は下記です。
  • low dpi(ldpi):120dpi
  • mdpi(medium dpi):160dpi
  • hdpi(high dpi):240dpi
  • xhdpi(extra high dpi):320dpi

・解像度 
画面の物理ピクセルの総数。
PC等でもよく見る1280x768がこれに当たります。

マルチ画面をサポートするにあたって、画面密度と解像度は非常に重要です。
対象とするユーザが持つ端末の画面密度と解像度はバラバラです。
同じ画像をA端末で表示した場合とB端末で表示した場合とでは見た目に差がでる場合が
あります。

どの画面密度と解像度でも同じような見た目にしたい場合は、密度非依存pxを
使用します。密度非依存pxは単位dpとして知られます。
dpは画面密度に依存しない依存しないサイズです。
160dpi(mdpi)の画面では1pxに相当し、240dpi(hdpi)の画面では1.5pxに相当します。
dpでサイズを指定すると、画面密度が変化しても見た目は変化しないため、各画面密度
におけるスケーリングを透過的に扱うことができます。

●dp→px変換、px→dp変換
変換は簡単です。
Androidでは160dpiが画面密度の基準として扱われるため1dp=1pxとなります。
ldpi~xhdpiまでの画面密度比は3(ldpi):4(mdpi):6(hdpi):8(xhdpi)になります。
100pxは各画面密度では何dpになるのかはmdpiを基準に相似比で考えます。
  • 100dpはldpiで何pxか? 3:4=x:100となり75px
  • 100dpはmdpiで何pxか? 4:4=100:xなので100px
  • 100dpはhdpiで何pxか? 4:6=100:xとなり150px
  • 100dpはxhdpiで何pxか? 4:8=100:xとなり200px

px→dp変換も同じです。
mdpiで100pxの場合、xhdpiで同じ見た目のサイズとするには
4:8=100:xとなり200pxのサイズを指定する必要があります。

各画面密度におけるdpサイズとpxサイズの関係は下記の図がわかりやすいです。



●解像度による画像サイズ
画像ファイルのサイズは静的ですので、上記で述べたように同じ画像をhdpiとxhdpiで描
画すると見た目のサイズが変わってきます。
これも画面密度の違いにより、画像がスケーリングされるためです。

スケーリングは画像にとっては大敵で、画像が拡大されてしまうと粗く見えてしまいます。
そのため、画像は各解像度毎に用意する必要あります。
用意するべき画像のサイズの計算も3:4:6:8の相似比を利用します。

画像サイズ100px×100pxの見た目を画面密度毎に統一したい場合、
  • ldpiでは、3:4=x:100となり75px×75pxの画像をdrawable-ldpiに配置
  • mdpiでは、4:4=100:xとなり100px×100pxの画像をdrawable-mdpiに配置
  • hdpiでは、4:6=100:xとなり150px×150pxの画像をdrawable-hdpiに配置
  • xhdpiでは、4:8=100:xとなり200px×200pxの画像をdrawable-xhdpiに配置
となる。

マルチ画面のサポートとスケーリングについてはDeveloperサイトが参考になります。
http://developer.android.com/guide/practices/screens_support.html

以上です。