본문 바로가기

컴퓨터학원(복습)(수료)

자바(JAVA)기반 안드로이드 웹&앱 개발 48일차 (1) (드로어블, 선그리기, 비트맵, 페인트보드, 부드러운선, 멀티터치)

멀티미디어 부분은 내일 올리겠습니다.

수업시간에는 코드는 있는 것을 사용하고 설명해주시는 방향으로 하셨습니다.

집에 와서 코드를 작성하여보니 그 이유가 이해가 갔습니다.

중복되는 코드도 많고, 이러한 것들은 미리 사용해져 있는 것들을 사용하면 되기 때문에 이해하는 게 먼저였을 것 같습니다.

아래주소는 선 그리기 sdk 를 제공하는 삼성 사이트입니다.

https://developer.samsung.com/galaxy-spen-remote/s-pen-remote-sdk.html

[드로어블 객체로 만들어 그리기]

1. 그리기 메서드를 사용하면 다양한 그래픽을 그릴 수 있는데 왜 굳이 그리기 객체를 만들어서 그리는 방법이 따로 있는 걸까요? 그래픽을 그리는 하나의 단위를 그리기 객체로 만들어 두면 각각의 그래픽 그리기 작업을 독립적인 객체로 나누어 관리할 수 있는 장점이 생기기 때문입니다. 그리고 이 객체에 애니메이션을 적용할 수도 있습니다.

구분

설명

리소스 파일의 사용

프로젝트 리소스에 이미지와 같은 파일을 포함시킨 후 읽어 들여 사용합니다.

XML로 정의하여 사용

그리기 객체의 속성을 정의한 XML 파일을 정의하여 사용합니다.

소스 코드에서 객체를 만들어 사용

소스코드에서 new 연산자를 이용하여 그리기 객체를 만든 후 사용합니다.

비트맵 이미지를 주어진 좌표 값에 그립니다.

2. 여러 가지 그리기 객체 중에서도 특히 셰이프 드로어블(ShapeDrawable)은 도형으로 정의된 Shape 객체를 담을 수 있으며, 이를 이용해서 메모리에 만들어진 그래픽 정보를 관리할 수 있도록 합니다.

※ 드로어블 객체로 만들어 그리기 예시

 

☞ 뷰가 채워지는 화면의 크기를 알아오기 위히 시스템 서비스 객체인 윈도우 매니저(WindowManager)를 참조합니다.

☞ 색상 정보는 XML 파일로 정의되며, /app/res/values/ 폴더 밑에 colors.xml이라는 파일에 color01, color02, color03 이라는 이름을 가진 색상 값을 추가합니다.

☞ 그리기 객체는 draw() 메서드를 직접 호출하여 그릴 수 있으므로 onDraw() 메서드 내에서 파라미터로 캔버스 객체를 전달합니다.

☞ LinearGradient 이용하면 뷰 영역의 위쪽 2/3 와 아래쪽 1/3 을 따로 채워줌으로써 위쪽에서부터 아래쪽으로 색상이 조금씩 변하는 배경화면을 만들 수 있습니다.

☞ LinerarGradient 객체는 선형 그러데이션을 구현하는데 하나의 직선 그러데이션 축을 따라 서로 혼합되는 여러 가지 색으로 영역을 그릴 수 있도록 합니다. 첫번째와 두번째 파라미터는 시작점(x1, y1)의 좌표, 세 번째와 네 번째 파라미터는 끝점(x2, y2)의 좌표로써 그러데이션의 축을 설정합니다. 이 그러데이션 축에 색상과 타일 처리방식으로 지정한 영역을 채워줍니다.

 

[선 그리기]

1. 선 그리기를 위한 속성은 Stroke와 rkhsfus된 메서드로 설정할 수 있습니다.

구분

설명

setStrokeWidth

Stroke의 폭을 설정합니다.

setStrokeCap

Stroke의 시작과 끝 부분의 모양을 설정합니다.

설정할 수 있는 값은 Cap.BUTT, Cap.ROUND, Cap.SQUARE입니다.

디폴트 값은 Cap.BUTT 입니다.

setStrokeJoin

Stroke의 꼭짓점 부분에 사용되는 연결모양을 설정합니다.

설정할 수 있는 값은 Join.MITER, Join.ROUND, Join.BEVEL입니다.

디폴트 값은 Join.MITER 입니다.

setStrokeMiter

Stroke 폭의 절반에 대한 Miter 길이의 비율 제한을 설정합니다.

※ 선 그리기 예시

 

☞ 선을 구성하는 좌표 값은 Path 객체에 넣어 두게 되는데, Path 객체의 moveTo() 메서드는 단순히 좌표값을 추가하는 역할을 하고 lineTo()는 이전 좌표 값과 선으로 연결되는 좌표 값을 추가하는 역할을 합니다. 즉 5개의 점을 이용해 선을 그리는 경우에는 moveTo() 메서드를 한 번 호출하고 난 후 lineTo() 메서드를 네 번 호출하여 Path 객체에 좌표 값을 추가합니다.

 

[비트맵 이미지 사용하기]

1. 비트맵(Bitmap) 객체는 메모리에 만들어지는 이미지라고 할 수 있습니다.

2. 비트맵 객체를 이용하면 화면에 이미지를 그릴 수 있습니다.

3. 비트맵은 그래픽을 그릴 수 있는 메모리 공간을 제공합니다. 흔히 더블 버퍼링(Double Buffering)이라 불리는 방법인데, 별도의 메모리 공간에 미리 그래픽을 그린 후 뷰가 다시 그려져야 할 필요가 있을 때 미리 그려놓은 비트맵을 화면에 표시하는 방법입니다.

※ 비트맵 이미지 사용하기

 

☞ 뷰가 새로 그려질 때 호출되는 onDraw() 메서드를 보면 단순히 메모리에 만들어 두었던 cacheBitmap을 그리는 코드만 들어가 있습니다. 실제 그래픽이 그려지는 시점은 testDrawing() 메서드가 호출되었을 때이며, createBitmap() 메서드를 이용해 만들어지는 비트맵 객체는 뷰의 onSizeChanged() 메서드가 호출되었을 때 초기화된 후, testDrawing() 메서드에 의해 그려지게 됩니다.

 

[비트맵 객체로 그래픽 그리기]

1. BitmapFactory 클래스는 비트맵 이미지를 만들기 위한 클래스 메서드들을 제공하며 이 메서드들은 이미지를 메모리에 비트맵 객체로 만들어 줄 수 있는 방법을 제공합니다.

구분

설명

파일에서 읽기

파일 패스를 지정하면 해당 위치의 이미지 파일을 읽어옵니다.

public static Bitmap decodeFile(String pathName)

리소스에서 일기

리소스에 저장한 이미지 파일을 읽어옵니다.

public static Bitmap decodeResource(Resources res, int id)

바이트 배열에서 읽기

바이트 배열로 되어 있는 이미지 파일을 읽어옵니다.

public static Bitmap decodeByteArray

(byte[] data, int offset, int length)

스트림에서 읽기

입력 스트림에서 이미지 파일을 익어옵니다.

public static Bitmap decodeStream(InputStream is)

2. 바이트 배열이나 스트림에서 읽을 수 있다는 것은 원격지에 있는 이미지 파일도 손쉽게 읽어 들일 수 있다는 것을 의미합니다.

※ 비트맵 객체로 그래픽 그리기 예시

 

☞ 안드로이드에서는 이미지 변환을 위해 Matrix 클래스가 사용됩니다. 기본적으로 제공하는 Matrix 객체를 이용하면 확대/축소, 이동, 회전, 뒤틀림 등의 효과를 간단하게 처리할 수 있습니다. setScale(), setTranslate(), setRotate(), setSkew() 가 있습니다.

☞ setScale() 메서드를 이용하면 대칭 이미지를 만들 수 있는데, (-1, 1)은 좌우대칭, (1,-1)은 상하 대칭 이미지를 만들기 위해 파라미터로 전달됩니다.

☞ 이미지에 다양한 효과를 내는 데는 마스크(Mask)를 이용하기도 합니다.

 

[페인트보드 만들기]

1. 페인트 보드는 손가락으로 터치하는 방식의 터치 이벤트를 처리하여 빈 화면 위에 손가락으로 그림을 그릴 수 있는 가장 단순한 형태입니다. 즉, onTouchEvent() 메서드로 터치한 곳의 좌표 값을 이용하여 그리기 기능을 구현하는 것입니다.

2. 터치 이벤트가 동작하는 방식은 크게 (1) 눌렀을 때 , (2) 누른 상태로 움직일 때, (3) 떼었을 때로 나눌 수 있습니다. 각각의 경우에 대하여 이벤트를 처리하면서 drawLine() 메서드로 선을 그리면 됩니다.

※ 페인트보드 만들기 예시

 

☞ 손가락으로 누르거나 눌린 상태로 이동할 때 뷰 위에 선을 그리는 가장 간단한 방법은 이전 터치 때의 좌표와 현재 터치 때의 좌표를 이용해서 선을 그리는 것입니다.

☞ 손가락으로 누른 ACTION_DOWN 상태에서 좌표 값을 변수에 저장한 후 ACTION_MOVE 상태에서 이전의 좌표 값과 현재의 좌표 값을 연결하여 선을 그리는 것입니다. 이전에 터치했을 때의 좌표는 lastX와 lastY 라는 변수에 저장되었다가 현재 터치했을 때의 좌표와 함께 그리기 작업에 사용됩니다.

☞ 이벤트의 마지막 부분에 invalidate() 메서드를 추가하여 화면을 다시 그리도록 하면 이동 시에도 지속적으로 화면을 갱신할 수 있습니다.

 

[부드러운 선 만들기]

1. 여러 가지 그리기 메서드 중에서 패스를 이용하면 연속적인 점들을 이용하여 직선 또는 부드러운 곡선을 쉽게 그릴 수 있습니다. 흔히 아크(Arc) 또는 커브(Curve)로도 표현되는 곡선 그리기 방법은 drawLine() 메서드를 이용하여 직선을 그려 점들을 연결할 때 발생하는 격자형의 딱딱함을 없앨 수 있습니다.

※ 부드러운 선 만들기 예시

 

[멀티터치 이미지 뷰어 만들기]

1. 두 손가락을 이용해 손가락 사이를 벌리면 이미지가 점차 확대되고 손가락 사이를 좁히면 이미지가 작아지도록 만들 때 사용하는 기능인데, 안드로이드의 이벤트에 대해 알아가다 보면 멀티터치는 어떻게 처리할까에 대해 궁금해질 것입니다.

2. 하나의 손가락에 대한 좌표 값은 getX() 와 getY() 메서드를 이용해 알 수 있고 눌린 상태는 getAction() 메서드를 이용해 구분할 수 있습니다.

★ public final int getPointerCount()

☞ 몇 개의 손가락이 터치되었는지를 알 수 있도록 해주는 것으로 만약 반환된 값이 1이라면 한 개의 손가락, 2라면 두 개의 손가락이 터치된 상태입니다.

★ public final float getX(int pointerIndex)

★ public final float getY(int pointerIndex)

※ 멀티터치 이미지 뷰어 만들기 예시

 

☞ 이미지를 보여주고 터치했을 때의 이벤트를 이용해 이미지를 확대/축소하거나 이동하기 위해 새로 정의하는 ImageDisplayView 클래스는 일반 View 클래스를 상속합니다. 또한 이 클래스는 터치 이벤트를 처리하므로 OnTouchListener 인터페이스를 구현하도록 합니다.

★ public boolean postScale(float sx, float sy, float px, float py)

☞ 첫 번째 파라미터는 X축을 기준으로 확대하는 비율, 두 번째 파라미터는 Y축을 기준으로 확대하는 비율을 의미합니다. 세 번째와 네 번째 파라미터는 확대 또는 축소할 때 기준이 되는 위치가 되는데 일반적으로는 비트맵 이미지의 중심을 지정합니다.

★ public boolena postTranslate(float dx, float dy)

☞ 비트맵 이미지를 이동시킬 때 사용할 수 있는데, 첫 번째와 두 번째 파라미터는 이동할 만큼의 X와 Y 좌표 값을 의미합니다.

★ public boolean postRotate(float degress)

☞ 비트맵 이미지를 회전시킬 때 사용할 수 있는데, 첫 번째 마라미터는 회전 각도를 의미합니다.

 

[머티리얼 디자인의 개념 알아두기]

1. 머티리얼 디자인(Material Design)은 구글이 안드로이드에 적용한 디자인 트렌드 중의 하나입니다. 좀 더 단순하고 직관적인 디자인을 할 수 있게 도입한 것이죠.