안드로이드에서는 이미지를 다루기 위한 몇가지 클래스가 존재한다.
Canvas, Bitmap, Drawable이 그것이다.
각각의 이미지 관련 클래스들에 대해 전반적인 사항을 알아보고자 한다.
1
2
3
4
5
6
Drawable drawable = getResources().getDrawable(id);
drawable.setBounds(0,0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); // drawable을 그리려는 영역을 지정
onDraw(canvas canvas) {
drawable.draw(canvas);
}
만약 원본 이미지 사이즈가 100 x 50 이라고 가정을 하고, setBounds 메소드에 parameter를 (0,0, 200, 100)이라고 설정하면?
가로 세로가 2배로 확대되어서 그려지는 식이다.
임의의 bitmap을 생성하고 bitmap에 원하는 내용을 그리는 방법을 살펴보자.
다음과 같이 임의의 bitmap을 생성할 수 있다.
Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
세번째 parameter인 Config.ARGB_8888 외에도 몇가지 설정 가능한 값들이 존재한다.
원하는 걸로 생성하면 되는데, ARGB_8888로 생성할 경우 투명값을 지정할 수가 있는 반면, RGB_565로 생성하면 불투명한 이미지만 가능하다. 알파 채널을 제외하므로 메모리를 절약할 수 있는 장점이 있다.
이렇게 만들어진 bitmap에 직접 그림을 그리거나 다른 이미지를 그리려고 하면 아래와 같이 새로운 canvas를 만들어야 한다.
1
2
Canvas canvas = new Canvas();
canvas.setBitmap(bitmap);
이렇게 하면, 향후에 canvas에 그리는 모든 작업은 bitmap에 반영이 된다.
안드로이드에서는 bitmap을 직접 다루기보단 대부분 Drawable이라는 wrapping된 형태로 이미지를 처리하기 때문에, Bitmap의 경우 종종 Drawable로 변환해야 하는 경우가 있다. 이런 경우를 위해서 BitmapDrawable이라는 클래스가 존재하는데, 아래 예제와 같은 방식으로 변환이 가능하다.
Drawable drawable = (Drawable)(new BitmapDrawable(bitmap));
BitmapDrawable은 Drawable로 type casting이 가능한 점을 기억하면 된다.
width X height 크기의 drawable 오브젝트가 있다고 가정하고, setBounds를 이용하여 임의의 좌표 (x, y)에 원래의 크기로 출력하려 한다면 아래와 같은 방법으로 가능하다.
1 2
obj.setBounds(x, y, x + width, y + height); obj.draw(canvas);
그런데 사실, 이 방식은 귀찮은 점이 있다.
항상 width, height를 지정해 주어야 한다는 것인데, 이 때문에 코드가 상당히 길어져 보기 좋지 않다.
getIntrinsicWidth()/Height()로 항상 구하던지 별도의 변수에 값을 유지해야한다.
이를 피하려면 위 방법보다는 아래와 같이 canvas의 좌표이동 변환식을 이용하는게 깔끔하다.
1
2
3
4
5
6
7
8
obj.setBounds(0, 0, width, height); // 가로 세로 크기값은 drawable을 생성하는 최초 한번만 지정하면 됨
canvas.save(); // 현재 변환식을 저장함
canvas.translate(x, y) // 좌표이동과 관련된 변환식 적용함
obj.draw(canvas); // drawable을 그림
canvas.restore(); // 원래 변환식으로 복구함
canvas.translate(x, y) 를 지정할 경우 출력할 이미지를 (x, y)만큼 이동시켜서 그려준다. (좌표이동 행렬식이라고 생각하면 됨)