본문 바로가기

책 요약하기/코틀린을 활용한 안드로이드 프로그래밍

#9. 그래픽과 이미지 2021-02-14

- 요약 -

1. 화면에 도형을 그릴 때 사용하는 클래스는 Canvas와 Paint이다. 캔버스와 페인트의 개념은 도화지와 붓에 비유할 수 있습니다.

 

2. 그래픽을 표현할 때는 다음과 같이 View 클래스를 재정의하는 형태가 많이 사용됩니다.

public override fun onCreate(savedInstanceState: Bundle?) {
	super.onCreate(savedInstanceState)
    setContentView(재정의한 클래스 이름(this))
}

private class 재정의한 클래스 이름 (context:Context) : View(context) {
	override fun onDraw(canvas: Canvas?) {
    	super.onDraw(canvas)
        // 화면에 그려질 코드
    }
}

 

3. 대표적인 Paint 클래스의 속성은 다음과 같습니다.

Paint.isAntiAlias 도형의 끝부분을 부드럽게 처리한다.
Paint.color 색상을 설정한다.
Paint.strokeWidth 도형 또는 글자 외관선의 두께를 설정한다.
Paint.style 도형 내부를 채울지 여부를 결정한다.
Paint.textSize 글자 크기를 설정한다.

 

4. 터치의 일반적인 사용 형식은 다음과 같습니다.

override fun onTouchEvent(event: MotionEvent) : Boolean {
	when (event.action) {
    	MotionEvent.ACTION_DOWN -> {
        	// 손가락으로 화면을 누르기 시작했을 때 동작
        }
        MotionEvent.ACTION_MOVE -> {
        	// 터치 후 손가락을 움직일 때 동작
        }
        MotionEvnet.ACTION_UP -> {
        	// 손가락을 화면에서 뗄 때 동작
        }
        MotionEvent.ACTION_UP -> {
        	// 터치가 취소될 때 할 일
        }

 

5. 이미지 파일을 화면에 출력하는 가장 일반적인 형태는 다음과 같습니다.

[res/drawable 폴더의 이미지 파일을 보여주는 onDraw() 메소드]

override fun onDraw (canvas: Canvas?) {
	super.onDraw(canvas)
    
    var picture = BitmapFactory.decodeResource(resources, R.drawble.이미지파일)
    canvas.drawBitmap(picture, 시작x, 시작y, null)
    picture.recycle()
}

 

[SD 카드의 이미지 파일을 보여주는 onDraw() 메소드]

override fun onDraw(canvas: Canvas?) {
	super.onDraw(canvas)
    
    var picture = BitmapFactory.decodeFile("파일경로 및 파일")
    canvas.drawBitmap(picture, 시작x, 시작y, null)
    picture.recycle()
}

 

6. Canvas 클래스의 기하학적 메소드에는 rotate(), scale(), translate(), skew() 등이 있다.

(rotate - 회전, scale - 축적(확대, 축소), translate - 이동, skew - 기울기)

 

7. 안드로이드에서는 블러링 효과를 주기 위해 BlurMaskFilter 클래스를 엠보싱 효과를 주기 위해 EmbossMaskFilter 클래스를, 색상이나 밝기를 조절하기 위해 ColorMatrix 클래스와 ColorMatrixColorFilter클래스를, 채도를 조절하기 위해 ColorMatrixsetSaturation() 메소드를 사용한다. (블러링, 칼라매트릭스, 칼라메트릭스세츄레이션 주로 씀)

 

- 연습문제 -

1. 화면에 도형을 그릴 때 사용하는 클래스 중 ( 1 )는 도화지와, ( 2 )는 붓 혹은 물감과 개념이 비슷하다.

답 :

( 1 ) - Canvas 클래스

( 2 ) - Paint 클래스

 

2. 각각을 설명하는 클래스 및 속성 또는 메소드를 쓰시오.

  1. 선 두께를 설정 -> Paint.strokeWidth
  2. 도형의 내부를 채울지 여부를 설정 -> Paint.style
  3. 원을 그림 -> canvas.drawCircle(cx, cy, radius, paint)
  4. 연속된 점을 연결하여 그림 -> canvas.drawLine(startX, startY, stopX, stopY, paint)
  5. 글자 크기를 설정 -> paint.textSize
  6. 여러 개의 점을 화면에 찍음 -> canvas.drawPoints(FloatArray, paint)
  7. 글자의 정렬 방법을 설정 -> paint.textAlign

 

3. 리소스의 이미지는 ( 1 ) 메소드를 이용하고, SD 카드의 이미지는 ( 2 ) 메소드를 이용하여 접근한다. 그리고 이미지를 화면에 출력하는 데에는 공통적으로 ( 3 ) 메소드를 사용한다. 비트맵 자원을 해제하려면 ( 4 ) 메소드를 사용한다.

답 : 

( 1 ) -> BitmapFactory.decodeResource(resources, 그림 id)

( 2 ) -> BitmapFactory.decodeFile(파일 경로)

( 3 ) -> drawBitmap(picture, startX, startY, Paint)

( 4 ) -> recycle()

 

4. 블러링 효과를 주려면 ( 1 ) 클래스를, 엠보싱 효과를 주려면 ( 2 ) 클래스를, 색상이나 밝기를 조절하려면 ( 3 ), ( 4 ) 클래스를 사용한다. 또한 컬러 이미지를 회색 이미지로 변환하려면 ( 5 ) 메소드를 사용한다.

답 : 

( 1 ) -> BlurMaskFilter(radius, style)

(★ radius는 블러링 효과를 낼 크기(반지름)이며, 스타일은 블러링 종류별 효과입니다.)

( 2 ) -> EmbossMaskFilter(FloatArray, ambient, specular, blurRadius)

(★ EmbossMaskFilter(빛의 xyz방향 1차 배열, 빛의 밝기, 반사 계수, 블러링 크기) )

( 3 ) -> ColorMatrix(FloatArray)

ex)
var array = floatArrayOf( 1f, 0f, 0f, 0f, 5f
						  0f, 2f, 0f, 0f, 5f
                          0f, 0f, 3f, 0f, 5f
                          0f, 0f, 0f, 4f, 0f)

(★ FloatArray는 4 x 5 배열로 각각 RGBA Bright를 의미합니다. 1f = Red, 2f = Green 3f = Blue 4f = Alpha, 5f = Brightness)

( 4 ) -> ColorMatrixColorFilter(ColorMatrix)

( 5 ) -> ColorMatrix.setSaturation(satur)

(★ satur회색조 0f ~ 1f)

 

5. [실습 9-2]의 아이콘을 모두 없애고 컨택스트 메뉴로 변경하시오. 단, 별도의 메뉴 XML 파일을 만들지 말고 Kotlin 코드로만 작성한다.

 

[activity_main.xml]

기존의 아이콘버튼은 전부 없애고 리니어 레이아웃만 남겨둡니다.

 

[MainActivity.kt]

(레이아웃을 롱클릭 하면 컨텍스트 메뉴가 나오게 합니다. 그리고 onCreateContextMenu 메소드와 onContextItemSelected메소드를 추가하여 메뉴 항목을 생성 합니다.)

 

6. [직접 풀어보기 9-2]를 이전에 그린 도형이 계속 화면에 남아 있도록 수정하시오.

 

[MainActivity.kt의 onCreate]

[MyShape Class]

도형 클래스로써 도형에 대한 정보를 가지고 있습니다.

 

[MyGraphicView Class]

 

[onToutchEvent Method]

(★ 기존에 MotionEvent.ACTION_MOVE, MotionEvent.ACTION_UP -> { ... }에서 분리하여

MotionEvent.ACTION_UP(터치를 뗄 때) arrayList에 그린 도형 정보를 추가합니다. )

 

[onDraw Method]

(★ onDraw 메소드 호출 시 arrayList에 추가한 도형을 먼저 그립니다. 이후 터치 하는 동안에 해당 도형을 그립니다.)

[결과 화면]

 

이상 마치겠습니다! :)