안드로이드 이미지뷰 영역에 맞게 이미지를 확대 또는 축소하는 방법. [scaleType] (How to Scale the Image on the ImageView)

2017. 1. 9. 20:23


1. ImageView의 영역과 이미지의 크기.

지난 글 [개발자 레시피 - 안드로이드 이미지뷰 기본 사용법]에서, 이미지 파일(png, jpg)에 저장된 이미지를 화면에 표시하기 위해 ImageView를 사용하는 방법에 대해 알아보았습니다.


Drawable 리소스에 이미지 파일(png, jpg, ..)를 추가한 다음, ImageView의 src 속성 또는 setImageResource() 함수를 사용하여 추가된 이미지를 화면에 표시하는 방법을 설명했죠.


그런데, 지난 글에서는 ImageView의 영역과 이미지의 크기에 대해서는 전혀 관심을 두지 않았습니다. 예제에 사용할 적당한 크기의 이미지를 만들어 사용했기 때문에 원본 이미지를 그대로 ImageView에 표시하는 것이 전혀 문제가 되지 않았죠.


하지만 다양한 크기의 이미지가 사용되는 경우이거나 ImageView의 영역보다 큰 이미지를 표시해야 하는 경우, ImageView 영역 안에서 이미지를 어떻게 보여줄 것인지는 충분히 고민이 되어야 할 문제입니다.


이런 이유로, 지금 여기에서, ImageView와 이미지의 크기에 따른 표시 방법에 대해 알아보도록 하겠습니다.

2. ImageView와 이미지 크기에 따른 몇 가지 경우의 수.

[개발자 레시피 - 안드로이드 이미지뷰 기본 사용법]처럼 원본 이미지가 자신의 크기대로 ImageView에 표시되어야 한다면, 아무런 고민없이 이미지를 표시하면 됩니다.

이미지의 크기대로 ImageView 표시


그런데 만약 원본 이미지의 크기가, 화면에서 ImageView가 차지하는 영역보다 작으면 어떨까요? 물론 작은 이미지를 원본 크기대로 ImageView 안에 표시할 수도 있지만, 어떤 경우에는 ImageView 영역의 가로, 세로 또는 양쪽 모두 꽉차게 만들고 싶을 수도 있을 것입니다.

ImageView의 크기보다 작은 이미지 표시


반대로, ImageView의 영역보다 이미지의 크기가 훨씬 큰 경우도 마찬가지죠.

ImageView의 크기보다 작은 이미지 표시


이렇듯, ImageView 위에 이미지가 어떻게 보여질 것인가에 대한 옵션은 여러 가지가 존재하며, 이는 ImageView에서 제공하는 속성을 통해 선택될 수 있습니다.

3. ImageView 영역에 맞게 이미지 확대 또는 축소.

3.1 scaleType 속성

위에서 설명한 ImageView 영역에 맞게 이미지의 크기를 확대 또는 축소하거나, 이미지를 이동시키는 동작은 ImageView의 scaleType 속성을 사용하여 지정할 수 있습니다.

  * android:scaleType - ImageView의 크기에 맞게 이미지 크기 조절 또는 이동.
        > 아래의 값 중 하나를 지정.
          -. matrix       (0) : 매트릭스를 사용하여 스케일. 이미지 커스터마이징 가능.
          -. fitXY        (1) : 가로,세로 방향으로 ImageView에 가득 채움.
          -. fitStart     (2) : 가로 또는 세로 중 한 방향으로 스케일.
                                ImageView의 Start 기준으로 이미지 표시.
          -. fitCenter    (3) : 가로 또는 세로 중 한 방향으로 스케일.
                                ImageView의 Center 기준으로 이미지 표시.
          -. fitEnd       (4) : 가로 또는 세로 중 한 방향으로 스케일.
                                ImageView의 End 기준으로 이미지 표시.
          -. center       (5) : 스케일 없이 이미지를 가운데 표시.
          -. centerCrop   (6) : 이미지 비율을 유지한 상태로 스케일. ImageView를 벗어나는 부분은 잘라냄.
          -. centerInside (7) : 이미지 비율을 유지한 상태로 스케일. ImageView를 벗어나지 않음.

위의 scaleType 속성에 대한 설명만으로는 각 속성 값을 사용했을 때 이미지가 어떻게 표시되는지, 그 결과가 쉽게 상상되지 않죠. 그래서 각 속성 값의 특징 및 표시 결과를 비교할 수 있도록, 아래와 같이 표로 정리해보았습니다.

scaleType 스케일 여부 비율 유지 표시 형태
원본 이미지 - -

scaleType original

사용안함 O O

scaleType not used

matrix 지정 가능 지정 가능

scaleType matrix

fitXY O X

scaleType fitXY

fitStart O O

scaleType fitStart

fitCenter O O

scaleType fitCenter

fitEnd O O

scaleType fitEnd

center X O

scaleType center

centerCrop O O

scaleType centerCrop

centerInside O O

scaleType centerInside

위의 표에서 scaleType의 각 속성 값을 클릭하면, 해당 값에 대한 상세 설명을 확인하실 수 있습니다.

3.2 scaleType 속성에 따른 이미지 표시 결과

자 그럼 지금부터, 앞서 설명한 scaleType 속성을 적용했을 때 각 속성 값에 따라 이미지가 어떻게 ImageView위에 표시되는지, 실제 코드를 적용한 예제 화면을 통해 알아보도록 하겠습니다.


예제를 위해 제작된 이미지 파일은 두 종류이며, ImageView의 영역보다 작은 크기의 이미지와 ImageView의 영역보다 큰 이미지로 구성되어 있습니다.

scaleType 속성을 위해 제작된 이미지


다음은 scaleType 옵션을 사용하지 않고 이미지 파일을 원본 크기대로 표시한 화면입니다. (layout_width와 layout_height 속성 값을 "wrap_content"로 지정)

[scaleType 예제 원본 이미지


참고로, 예제에 사용된 ImageView는 200dp x 150dp의 고정 크기를 가지며, background 속성을 사용하여 배경을 회색(#AAAAAA)으로 지정하였습니다.

3.2.1 사용하지 않음.

ImageView에 scaleType 속성을 사용하지 않으면, 이미지는 자동으로 ImageView의 영역 내에 표시되도록 스케일되며, 스케일된 이미지는 ImageView의 중앙에 표시됩니다. 이는 "fitCenter" 값의 표시 결과와 동일합니다. 즉, scaleType의 기본 값은 "fitCenter" 입니다.

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp">

        <ImageView
            android:layout_width="200dp"
            android:layout_height="150dp"
            android:layout_marginEnd="50dp"
            android:background="#AAAAAA"
            android:src="@drawable/smile_small" />

        <ImageView
            android:layout_width="200dp"
            android:layout_height="150dp"
            android:background="#AAAAAA"
            android:src="@drawable/smile_large" />

    </LinearLayout>

scaleType 사용하지 않을 때 표시 화면


3.2.2 matrix

matrix는 "Image Matrix"를 사용하여, 이미지를 표시할 때 사용됩니다. 이 "Image Matrix"라는 것은, ImageView의 크기에 따라 이미지를 어떠한 형태로 변환하여 표시할 것인지를 지정한 값을 말하는 것인데요. "Image Matrix"를 사용하면 개발자가 직접 이미지의 크기 조절, 위치 변경, 원근감 왜곡 등의 효과를 줄 수 있습니다.


일단 scaleType 속성에 matrix 값만 지정하면, 아래와 같이 원본 크기대로 Left, Top을 기준으로 그려집니다.

scaleType 속성 matrix


ImageView에 사용될 "Image Matrix"는 Matrix 클래스(android.graphics.Matrix)를 객체를 만들어 기술하며, Matrix 클래스의 객체는 setImageMatrix() 함수를 통해 전달됩니다.


scaleType 속성에 matrix 값을 사용하면, 최종적으로 표시될 이미지에 매우 다양한 효과를 입힐 수 있습니다. matrix가 아닌 다른 값을 사용했을 때의 이미지 형태도 matrix를 사용하여 표시할 수 있죠. 즉, 개발자가 최종 표시될 이미지에 대해 일일이 커스터마이징 할 수 있도록 만들어주는 것이 바로 matrix 속성과 setImageMatrix() 함수인 것이죠.


"Image Matrix"를 여기서 설명하자면 지면이 한참 모자라니, 자세한 사용법에 대해서는 다른 기회에 좀 더 자세히 살펴보도록 하고, 여기서는 간단한 예제만 소개하겠습니다.


예제 코드는 첫 번째 이미지(imageView1)의 크기를 2배로 늘리고, 두 번째 이미지(imageView2)를 Left, Top 위치를 기준으로, 시계 방향으로 "45도" 기울여 표시하는 예제입니다.

    ImageView imageView1 = (ImageView) findViewById(R.id.imageView1) ;
    Matrix matrix1 = new Matrix() ;
    matrix1.postScale(2.0f, 2.0f);
    imageView1.setImageMatrix(matrix1) ;

    ImageView imageView2 = (ImageView) findViewById(R.id.imageView2) ;
    Matrix matrix2 = new Matrix() ;
    matrix2.postRotate(45.0f) ;
    imageView2.setImageMatrix(matrix2) ;

scaleType 속성 matrix setImageMatrix 예제


3.2.3 fitXY

fitXY는 이미지를 ImageView 영역에 가득채워 표시할 때 사용합니다. 즉, 가로(X), 세로(Y) 방향으로 이미지를 확대 또는 축소하여 ImageView의 크기에 맞추는 것이죠. 이 때, 원본 이미지의 비율은 무시됩니다.

scaleType 속성 fitXY


3.2.4 fitStart

fitStart는 이미지를 ImageView 영역 내에 모두 표시되도록 확대 또는 축소한 다음, 크기가 조절된 이미지를 ImageView의 Start(Left, Top) 기준으로 표시합니다. 단, 이미지의 크기가 조절될 때, 원본 이미지의 비율을 유지합니다.

scaleType 속성 fitStart


3.2.5 fitCenter

fitCenter 값은 fitStart와 마찬가지로 비율을 유지한 채, ImageView의 크기에 맞게 이미지의 크기를 조절합니다. 단, 이미지가 표시되는 기준을 Center로 설정한다는 차이가 있습니다.

scaleType 속성 fitCenter


3.2.6 fitEnd

fitEnd 또한 fitStart와 fitCenter처럼 이미지가 조절되며, 이미지를 End(Right, Bottom)에 표시합니다. 그리고 이미지 비율도 원본 이미지의 비율을 따릅니다.

scaleType 속성 fitEnd


3.2.7 center

center는 이미지의 크기를 전혀 늘이거나 줄이지 않고, 원본 이미지를 그대로 ImageView에 표시합니다. 이미지 표시 기준 위치만 ImageView의 중앙(Center)에 맞춥니다.

scaleType 속성 center


3.2.8 centerCrop

centerCrop은 이미지가 ImageView보다 같거나 크게 만든 다음, ImageView에 표시합니다. 크기 조절 후 ImageView의 크기를 벗어나는 이미지 영역은 잘려나가며(Crop) 화면에 표시되지 않습니다. 이미지 크기를 조절할 때는 원본 이미지 비율을 유지하며, 최종적으로 ImageView의 중앙(Center)에 표시됩니다.

scaleType 속성 centerCrop


3.2.9 centerInside

centerInside 값은 이미지가 ImageView보다 작거나 같은 크기로 ImageView 내에 표시되도록 만듭니다. 이 때 이미지의 비율은 원본의 비율을 그대로 유지한채로 ImageView의 중앙(Center)에 이미지를 표시합니다. 특히, 이미지의 원본 크기가 ImageView보다 작은 경우, 이미지 크기를 늘이지 않습니다.

scaleType 속성 centerInside


4. 참고.

.END.


ANDROID 프로그래밍/IMAGEVIEW