-
[ImageView] ScaleType: Matrix (행렬)Software/Android : 안드로이드 2018. 8. 14. 01:25반응형
Android에서 ImageView는 해당 View의 이미지가 어떤 형태로 어떻게 배치될 것인 지를 ScaleType을 통해 설정할 수 있다.
ScaleType은 아래와 같이 총 8가지가 있고 xml의 "scaleType" attribute로 설정하거나 Code level에서 ImageView의 setScaleType(ImageView.ScaleType scaleType)을 통해 설정 가능 하다.
ImageView.ScaleType
Values
CENTER
Center the image in the view, but perform no scaling.
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).
FIT_CENTER
Scale the image using Matrix.ScaleToFit.CENTER.
FIT_END
Scale the image using Matrix.ScaleToFit.END.
FIT_START
Scale the image using Matrix.ScaleToFit.START.
FIX_XY
Scale the image using Matrix.ScaleToFit.FILL.
MATRIX
Scale using the image matrix when drawing.
표 1. ImageView의 ScaleType (참조: Android Developer)
Matrix 이외의 나머지 7가지의 scaleType이 경우 단순 attribute 설정만으로 즉각적인 결과값을 얻어 볼 수 있다. 그러나 Matrix의 경우 Scaling, Roatation, Translation등과 같은 Matrix연산을 직접 해주어야 한다.
- Matrix ScaleType을 사용
xml에서 scaleType="matrix" 값으로 설정해주거나 코드 상에서 ImageView.setScaleType(ImageView.ScaleType.MATRIX)를 호출해 주어야 한다. 그리고 ImageView.setImageMatrix(Matrix)를 통해 Image matrix를 설정할 수 있다.
- 좌표계
좌측 최상단을 원점(0, 0)으로 가지는 좌표계로 오른쪽 방향으로 x값이 그리고 아랫 방향으로 y 값이 증가한다.
그림 1. 좌표계
즉 아무런 Matrix 연산이 되지 않은 상태에서의 ImageView와 Bitmap은 아래와 같이 되어 있을 것이다.
그림 2. 기본적인 Bitmap과 ImageView의 위치
Bitmap Size가 Image View의 Size 보다 작은 경우에는 왼쪽과 같이 Image View에 빈 여백이 보여지게 될 것이고 만약 반대의 경우라는 오른쪽 과 같이 Image View에 Bitmap 좌측 상단 일부분만 보여 지게 된다.
원점 (0, 0)이 좌측 상단 꼭지점이므로 위와 같은 형태로 Bitmap이 정렬된다.
- 3 x 3 Matrix
Android에서 ImageMatrix는 3 x 3 matrix 를 가지는데 (x, y, w) Vertex와의 곱을 통해 변형된 값의 Vertex를 얻을 수 있다.
그림 3. Matrix 연산 (with Vertex)
Android에서 Matrix의 기본값은 Identity Matrix(단위 행렬)이며 w 값의 경우 초기값으로 1을 가진다.
W
의미
1
공간에서의 위치
0
방향
- Scaling Matrix
Matrix에 Scale 값을 적용하는 건 매우 간단하다. x, y에 적용할 Scale 값이 있다고 했을 때 Matrix는 아래와 같은 Matrix가 된다.
그림 4. Scaling Matrix 연산
그림 5. Scaling 된 Bitmap 도식화
- Rotation Matrix
Rotation을 위한 Matrix와 Vertex 연산은 아래와 같다. 더불어 Sin, Cos 그래프를 함께 첨부하였으니 계산 시 참고하면 되겠다.
그림 6. Rotation Matrix 연산
그림 7. Sin, Cos 그래프
출처: http://www.bbc.co.uk/bitesize/standard/maths_ii/trigonometry/graphs/revision/1/
저 행렬식을 이용해 가로 2, 세로 1의 직사각형 이미지를 회전 시켜 보도록 하자.
수식에 회전시키고자 하는 Degree 값을 넣어서 계산하면 아래와 같은 결과를 얻을 수 있다.
X = cos𝛳 * x + - sin𝛳 * y
Y = sin𝛳 * x + cos𝛳 * y
- 90˚ 의 경우
Cos(90) = 0, Sin(90) = 1 이므로 (x, y) -> (-y, x)
(0,0) -> (0, 0) | (2, 0) -> (0. 2) | (2, 1) -> (-1, 2) | (0, 1) -> (-1, 0)
- 180˚ 의 경우
Cos(180) = -1, Sin(180) = 0 이므로 (x, y) -> (-x, -y)
(0,0) -> (0, 0) | (2, 0) -> (-2, 0) | (2, 1) -> (-2, -1) | (0, 1) -> (0, -1)
- 270˚ 의 경우
Cos(270) = 0, Sin(270) = -1 이므로 (x, y) -> (y, -x)
(0,0) -> (0, 0) | (2, 0) -> (0. -2) | (2, 1) -> (1, -2) | (0, 1) -> (1, 0)
그림 8. Degree에 따른 Rotate 결과
- Translation Matrix
x, y 이동을 위한 Translation matrix 연산식은 아래와 같다.
그림 9. TranslationMatrix 연산
만약 100 * 100 이미지가 있고 50 * 50 ImageView가 있다고 했을 때 Matrix를 이용한 ceter crop을 한다고 가정해 보자.
그림 10. Bitmap의 이동
이동 원점은 View의 centerX, centerY가 되고 목표 지점은 bitmap의 centerX, centerY가 될 것이다.
이동 원점과 목표 지점을 모두 알고 있는 상황이므로 이걸 가지고 우리는 dx, dy를 아래와 같이 구할 수 있다.
dx = viewCenterX - bitmapCenterX
dy = viewCneterY - bitmapCenterY
반응형'Software > Android : 안드로이드' 카테고리의 다른 글
[Java 8] Android Studio 3.x와 Java 8 (0) 2019.03.12 [ImageView] ScaleType: Matrix (예제) (0) 2018.08.20 댓글