[Android] ImageView画像をScreenのレイアウトにフィットさせるには

画像をスクリーン画面の中央に設定して、かつ枠からはみ出さないようににフィットさせるには ImageView.ScaleType を上手に使わないといけません。
 

centerCrop1b
scaletype_1b


 

Android Studio 2.1.3
Android 7.0

 

sponsored link

ImageView.ScaleType

 
設定のパラメータは8つあります
Google Developer:Reference ImageView.ScaleType

    1. CENTER
      • Viewの中央に表示、拡大縮小無し
      • android:scaleType=”center”
    2. CENTER_CROP
      • View内で画像の縦横比を維持し、Cropして中央に配置
      • android:scaleType=”centerCrop”
    3. CENTER_INSIDE
      • View内で画像の縦横比を維持し画像すべてをView内の中央に配置
      • android:scaleType=”centerInside”
    4. FIT_CENTER
      • View内で画像の縦横比を維持し中央に配置
      • android:scaleType=”fitCenter”
    5. FIT_END
      • View内で画像の縦横比を維持し、右下に寄せて配置
      • android:scaleType=”fitEnd”
    6. FIT_START
      • View内で画像の縦横比を維持し、左上に寄せて配置
      • android:scaleType=”fitStart”
    7. FIT_XY
      • View内で縦横を独立してリサイズし、フル画面にする
      • android:scaleType=”fitXY”
    8. MATRIX
      • Image Matrix を使うときに使用する
      • android:scaleType=”matrix”

 
これだけ見ると、簡単に色々設定できそうですが android:scaleType=”center” だけ追加しても期待通りのレイアウトにならないケースがあったりします
 
 
下のように2つの縦長、横長画像を用意して ローテーションさせた時の表示を確認してみます
 
Test Case:
 スマホ画面サイズ: 540×897 pix
 

【image1】
854×480 pix
16:9 横長画像(Landscape)
image1

【image2】
960×1708 pix
16:9 縦長画像(Portrait)
image2

 
レイアウトファイルは以下のように記述して
android:scaleType をそれぞれ変えて試してみます
 
activity_main.xml

 

MainActivity.java

 

CENTER

 
Viewの中央に表示、拡大縮小無し

 
リサイズしないので、画像がスクリーンよりも大きいとはみ出て
Portraitでは横長画像は左右が切れてしまう
 

center1b scaletype_1b

 

縦長画像は、landscapeで上下が切れる
 

scaletype_2 center2a

 

ところで、CENTERとあるのに、縦長画像のPortraitは橋が画面の中央ではなく 上に張り付いています
 
referenceでは Center the image in the view とあるが、
Screenの中央とは言っていない!…(x~x)

 
android:layout_height=”wrap_content” これを

に変更すると
 
center1c
 
画面中央に配置できました。
Viewの範囲を意識しないといけないのですね
 
とは言っても アプリが複雑になり、ネストのネストの中に入り込んでいると
match_parent を使えないケースもあります
RelativeLayout、LineaLayout に
android:gravity=”center”
などを入れるとうまくいったりします。
 

CENTER_CROP

 

 
CROPなので惜しげもなくバッサリ切られる  

centerCrop1b scaletype_1b

 

縦長画像は
 

scaletype_2 centerCrop2a

 

はて、CENTER と同じような結果となりました?・・・
 
画像サイズが画面より 大きい かあるいは 小さい 場合に差がはっきりするようです
CENTER は中央に表示しますが、拡大縮小は無し
CENTER_CROP 縦横比を維持し、Cropして中央に配置
 

CENTER CENTER_CROP
center3c centerCrop3c

 

元画像が 80×60 pix と小さいので、拡大されると粗が出る
 
このケースでは
 
android:layout_width=”wrap_content
android:layout_height=”wrap_content
 
をそれぞれ match_parent に変更しないと
CENTER_CROPでは元の画像サイズとなり、同じ表示になってしまうので注意
 

CENTER_INSIDE

 

 
Referenceでは、
CENTER_CROP: Scale the image uniformly (maintain the image’s aspect ratio) so that both dimensions (width and height) of the image will be equal to or larger than the corresponding dimension of the view (minus padding).  
CENTER_INSIDE: Scale the image uniformly (maintain the image’s aspect ratio) so that both dimensions (width and height) of the image will be equal to or less than the corresponding dimension of the view (minus padding).
 
larger than か less than の違いだけであとの文面は同じ とにかくViewの中に収まるように配置される
 

centerInside1b centerInside1a

 

縦長画像のPortraitではView内に収めるため余白が出る
 

centerInside2b centerInside2a

 
FIT_CENTER

 

 
画像のアスペクト比を変えずにView内に収め、中央に配置する
android:layout_height=”wrap_content”
にすると右下のように中央ではなくなる
android:layout_height=”match_parent”
にすると修正される
 

fixCenter1b fixCenter1a

 

縦長画像は
 

fixCenter2b fixCenter2a

 

このケースでは CENTER_INSIDE と同じような結果となりました
これも、画像サイズとそれを入れる枠によって表示が異なります
それぞれ

 

scaletype2

CENTER_INSIDE では枠内の中央に配置されるだけですが
FIT_CENTERの場合は、上のように拡大されて中央表示となっています


 
FIT_END

 

 
END、右下に寄った画像配置となる、ここでもViewの範囲に注意が必要となる
 

fitEnd1a fitEnd1b

 

縦長画像は
 

fitEnd2b fitEnd2a

 
FIT_START

 

 
START、左上に寄った画像配置となる
 

fitStart1a fitStart1b

 

縦長画像は
 

fitStart2a fitStart2b

 
FIT_XY

 

 
縦横をそれぞれ独立して、Screen いっぱいに拡大縮小する 当然本来の画像ではなくなるが、
プレーンな背景たとえば空色一色の画像や あるパターンの繰り返しで背景を埋めたいとき、
余白を残したくない場合に有効なのかもしれない 因みにこの設定には、やはり
android:layout_width=”match_parent”
android:layout_height=”match_parent”
としないと画面いっぱいにリサイズされないので注意
 

fitXY1a fitXY1b

 

縦長画像は
 

fitXY2b fitXY2a

 
MATRIX

 

 
Canvas, draw 等で
setImageMatrix() を使うときに設定する

画面に関係なく指定したサイズで左上に寄せて表示させることもできる


fitMatrix1
 
これは、他とは毛色が違うので、別物として扱うことになりますね
 

その他の関連ページ