티스토리 뷰



이 자료들은 팁스소프트에서 제공하는 [ 알짜배기 ] 프로그램을 이용하면 더 편리하게 볼수 있습니다.
* 알짜배기 프로그램 받기 - http://www.tipssoft.com/bulletin/tb.php/QnA/8406
* 관리자의 Tipssoft 이야기를 들어보세요 ( 트위터 ID : tipssoft )
* 안드로이드 강좌 목록 - http://www.tipssoft.com/bulletin/tb.php/old_bbs/501
* 이 예제는 안드로이드 팜으로 만들어졌습니다.
이번 강좌에서는 안드로이드 시스템에서 화면 출력시 여러가지 형식의 그라데이션을 사용하는 방법에
대해서 알아보도록 하겠습니다.
1. 사용 방법
그리기를 수행할 때 사용하는 Canvas 클래스에서는 대부분의 그리기 작업을 수행할 때 Paint
객체를 요구합니다. Paint 클래스는 그려질 그림의 색상이나 두께 등 여러가지 속성을 정의할 때
사용하는데 이 중 그라데이션을 출력하기 위해서 설정할 수 있는 속성이 Shader 입니다.
그래서 일반적인 상황에서 사각형을 그리면 Paint 클래스의 setColor 메소드로 설정한 색상으로
사각형이 그려지지만 Shader 를 적용한 후 사각형을 그리면 해당 사각형 영역에 특정한 패턴이
그려지거나 그라데이션이 그려지게됩니다.
Shader 클래스는 그라데이션이나 패턴을 설정하는 클래스들의 부모 클래스이고, 이 클래스의
자식 클래스들에 여러가지 출력 형태가 정의되어 있습니다.
아래의 코드는 Shader 객체로 그라데이션 및 패턴 출력을 할 때 기본적으로 사용하는 루틴입니다.
// Paint 객체를 생성한다.
Paint shader_paint = new Paint();
shader_paint.setAntiAlias(true);
// Shader 클래스의 하위 클래스중 하나를 생성한다. 빨강색과 검정색을 그라데이션 시킨다.
LinearGradient shader = new LinearGradient(0, 0, 100, 0, Color.RED, Color.BLACK,
Shader.TileMode.CLAMP));
// Paint 객체에 그라데이션된 Shader 객체를 설정한다.
shader_paint.setShader(shader);
// Shader 가 적용된 페인트를 이용하여 사각형을 그린다.
canvas.drawRect(0, 0, 100, 100, shader_paint);
// 설정한 Shader 객체를 제거한다.
shader_paint.setShader(null);
그라데이션을 구성하는 것은 일반 그리기 작업을 하는 것보다 부하가 큰 작업이기때문에 출력할
영역만큼의 비트맵을 생성한 후 그라데이션을 구성하고 그리는 작업을 해당 비트맵에 한번만 하는
것이 좋습니다. 그리고 onDraw 처럼 반복적으로 그리기 작업을 수행하는 곳에서는 drawBitmap
메소드를 해당 비트맵을 출력하도록 하는 것이 좋습니다.
2. Shader 종류
Shader 클래스의 하위 클래스를 이용하면 여러가지 형태의 그라데이션 및 패턴을 적용하여 그림
그리기를 할 수 있습니다. BitmapShader 클래스는 Bitmap 객체를 여러가지 패턴을 적용하여
출력하도록 해주고, LinearGradient, SweepGradient, RadialGradient 들은 색상을 이용하여
그라데이션을 적용한 그리기를 할 수 있도록 제공해주며 ComposeShader 는 두개의 Shader
클래스를 조합하여 그리기를 수행할 수 있도록 해줍니다. 이제부터 다섯가지 클래스의 사용법에
대하여 알아보도록 하겠습니다.
2.1 BitmapShader
BitmapShader 클래스는 Bitmap 클래스의 이미지를 반복적으로 출력하거나 반전시켜 출력하도록
제공하여 일종의 패턴을 적용한 비트맵 출력을 가능하도록 해줍니다. BitmapShader 클래스의
생성자는 다음과 같습니다.
BitmapShader(Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)
bitmap 은 그려질 Bitmap 객체이고, tileX 와 tileY 는 Shader.TileMode 타입으로 비트맵에
적용될 패턴의 타입을 의미하는데 설정 가능한 값은 아래와 같습니다.
- CLAMP : 출력되는 방향으로 이미지가 끌린 것처럼 테두리의 색상이 겹쳐져서 출력됩니다.
- MIRROR : 이미지가 반대 방향으로 반전되어 반복적으로 출력됩니다.
- REPEAT : 이미지가 반복적으로 출력됩니다.
아래의 < 그림 1 > 과 같은 그림에 X 축으로 CLAMP 를 적용하면 < 그림 2 > 처럼 출력되고,
< 그림 1 > 에 X 축으로 REPEAT, Y 축으로 MIRROR 를 적용하면 < 그림 3 > 처럼 출력됩니다.
< 그림 1 > < 그림 2 > < 그림 3 >
BitmapShader 클래스를 사용하여 패턴 그리기를 하려면 다음과 같이 코드를 구성하시면 됩니다.
// Paint 객체를 생성한다.
Paint shader_paint = new Paint();
shader_paint.setAntiAlias(true);
// BitmapShader 클래스를 생성한다. 비트맵이 X 축으로는 평범하게 반복되지만
// Y 축으로는 반전되면서 반복되는 패턴을 가진다.
BitmapShader shader = new BitmapShader(icon_bitmap, Shader.TileMode.REPEAT,
Shader.TileMode.MIRROR);
// Paint 객체에 비트맵 패턴이 적용된 Shader 객체를 설정한다.
shader_paint.setShader(shader);
// Shader 가 적용된 페인트를 이용하여 사각형을 그린다.
canvas.drawRect(0, 0, 100, 100, shader_paint);
// 설정한 Shader 객체를 제거한다.
shader_paint.setShader(null);
2.2 LinearGradient
LinearGradient 클래스는 선의 형태로 그라데이션을 출력할 수 있도록 해줍니다. LinearGradient
클래스의 생성자는 다음과 같습니다.
LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions,
Shader.TileMode tile)
LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)
x0, y0 는 그라데이션이 그려지는 시작 좌표이고, x1, y1 는 끝 좌표를 의미합니다. 첫번째
생성자에서 colors 와 positions 는 그라데이션을 구성할 색상의 배열과 해당 색상의 상대적인
위치 배열입니다. 두 배열은 하나의 그라데이션을 구성할 때 필요한 요소들이므로 동일한
요소 개수를 가져야합니다. 두번째 생성자에서의 color0 과 color1 은 그라데이션을 구성하는
색상이 두가지인 경우에만 사용합니다. tile 에는 CLAMP 와 REPEAT, MIRROR 중에 하나의
값을 설정하면 되는데 어떤 값을 설정해도 비슷한 결과가 출력됩니다.
다음은 LinearGradient 클래스를 사용한 예제 코드와 결과 입니다.
// Paint 객체를 생성한다.
Paint shader_paint = new Paint();
shader_paint.setAntiAlias(true);
// 그림을 그릴 영역의 너비와 높이를 구한다.
int width = getWidth();
int height = getHeight();
// 그라데이션을 구성할 색상과 각 색상의 상대적 위치값을 배열로 구성한다.
int[] colors = {Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN, Color.BLUE,
Color.MAGENTA, Color.RED};
float[] color_pos = {0.0f, 0.17f, 0.34f, 0.51f, 0.68f, 0.85f, 1.0f};
// LinearGradient 클래스를 생성한다. 시작 좌표를 좌측 상단으로 두고, 끝 좌표를 우측 하단으로
// 두어서 대각선 방향의 그라데이션이 그려진다.
LinearGradient shader = new LinearGradient(0, 0, width, height, colors, color_pos,
Shader.TileMode.CLAMP);
// Paint 객체에 비트맵 패턴이 적용된 Shader 객체를 설정한다.
shader_paint.setShader(shader);
// Shader 가 적용된 페인트를 이용하여 사각형을 그린다.
canvas.drawRect(0, 0, width, height, shader_paint);
// 설정한 Shader 객체를 제거한다.
shader_paint.setShader(null);
2.3 SweepGradient
SweepGradient 클래스는 90 도에서 시계방향으로 회전하면서 그라데이션을 출력할 수 있도록
해줍니다. SweepGradient 클래스의 생성자는 다음과 같습니다.
SweepGradient(float cx, float cy, int[] colors, float[] positions)
SweepGradient(float cx, float cy, int color0, int color1)
cx, cy 는 회전하며 그려질 그라데이션의 중심 좌표이고, 첫번째 생성자에서 colors 와
positions 는 그라데이션을 구성할 색상의 배열과 해당 색상의 상대적인 위치 배열입니다.
두 배열은 하나의 그라데이션을 구성할 때 필요한 요소들이므로 동일한 요소 개수를 가져야
합니다. 두번째 생성자에서의 color0 과 color1 은 그라데이션을 구성하는 색상이 두가지인
경우에만 사용합니다.
다음은 SweepGradient 클래스를 사용한 예제 코드와 결과 입니다.
// Paint 객체를 생성한다.
Paint shader_paint = new Paint();
shader_paint.setAntiAlias(true);
// 그림을 그릴 영역의 너비와 높이를 구한다.
int width = getWidth();
int height = getHeight();
// 그라데이션을 구성할 색상과 각 색상의 상대적 위치값을 배열로 구성한다.
int[] colors = {Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN, Color.BLUE,
Color.MAGENTA, Color.RED};
float[] color_pos = {0.0f, 0.17f, 0.34f, 0.51f, 0.68f, 0.85f, 1.0f};
// SweepGradient 클래스를 생성한다. 영역의 중심을 중점으로 하며 7가지 색상을
// 그라데이션으로 구성한다.
SweepGradient shader = new SweepGradient(width/2, height/2, colors, color_pos);
// Paint 객체에 비트맵 패턴이 적용된 Shader 객체를 설정한다.
shader_paint.setShader(shader);
// Shader 가 적용된 페인트를 이용하여 사각형을 그린다.
canvas.drawRect(0, 0, width, height, shader_paint);
// 설정한 Shader 객체를 제거한다.
shader_paint.setShader(null);
2.4 RadialGradient
RadialGradient 클래스는 둥근 원모양으로 그라데이션을 구성합니다. RadialGradient 클래스의
생성자는 다음과 같습니다.
RadialGradient(float x, float y, float radius, int[] colors, float[] positions, Shader.TileMode tile)
RadialGradient(float x, float y, float radius, int color0, int color1, Shader.TileMode tile)
x, y 는 구성될 원형의 중점 좌표이며, radius 는 그라데이션이 구성될 반지름의 크기를 의미
합니다. 첫번째 생성자에서 colors 와 positions 는 그라데이션을 구성할 색상의 배열과 해당
색상의 상대적인 위치 배열입니다. 두 배열은 하나의 그라데이션을 구성할 때 필요한 요소들
이므로 동일한 요소 개수를 가져야합니다. 두번째 생성자에서의 color0 과 color1 은 그라데이션을
구성하는 색상이 두가지인 경우에만 사용합니다. tile 에는 CLAMP 와 REPEAT, MIRROR 중에
하나의 값을 설정하면 되는데 어떤 값을 설정해도 비슷한 결과가 출력됩니다.
다음은 RadialGradient 클래스를 사용한 예제 코드와 결과 입니다.
// Paint 객체를 생성한다.
Paint shader_paint = new Paint();
shader_paint.setAntiAlias(true);
// 그림을 그릴 영역의 너비와 높이를 구한다.
int width = getWidth();
int height = getHeight();
// 너비와 높이중 작은 값의 절반을 반지름으로 지정한다.
int radius;
if(width > height) radius = height / 2;
else radius = width / 2;
// 그라데이션을 구성할 색상과 각 색상의 상대적 위치값을 배열로 구성한다.
int[] colors = {Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN, Color.BLUE,
Color.MAGENTA, Color.RED};
float[] color_pos = {0.0f, 0.17f, 0.34f, 0.51f, 0.68f, 0.85f, 1.0f};
// RadialGradient 클래스를 생성한다. 영역의 중심을 중점으로 하며 7가지 색상을
// 그라데이션으로 구성한다.
RadialGradientshader = new RadialGradient(width/2, height/2, colors, color_pos,
Shader.TileMode.CLAMP);
// Paint 객체에 비트맵 패턴이 적용된 Shader 객체를 설정한다.
shader_paint.setShader(shader);
// Shader 가 적용된 페인트를 이용하여 사각형을 그린다.
canvas.drawRect(0, 0, width, height, shader_paint);
// 설정한 Shader 객체를 제거한다.
shader_paint.setShader(null);
2.5 ComposeShader
ComposeShader 클래스는 두개의 Shader 를 합성하여 출력하도록 해줍니다. 예를 들어 두개의
LinearGradient 클래스를 합성하거나 RadialGradient 클래스와 SweepGradient 클래스를 합성하여
Color Picker 를 만들 수도 있고, BitmapShader 클래스와 LinearGradient 클래스를 합성하여
이미지가 점점 특정 색으로 변하도록 할 수도 있습니다. ComposeShader 클래스의 생성자는
다음과 같습니다.
ComposeShader(Shader shaderA, Shader shaderB, Xfermode mode)
ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode)
shaderA 와 shaderB 는 합성할 Shader 객체인데 합성시 shaderA 가 " dst " 에 해당하고
shaderB 가 " src " 에 해당합니다. ComposeShader 클래스가 생성될 때 두 Shader 객체가
가진 패턴이나 그라데이션에서 색상값으로 연산을 수행하여 합성을 하기때문에 두개의 Shader
객체를 어디에 배치하느냐에 따라 결과가 달라질 수도 있습니다. mode 에는 어떤 연산을 통해서
두개의 Shader 를 합성할 것인지 정해주어야 합니다.
다음은 ComposeShader 클래스를 사용한 예제 코드와 결과 입니다.
// Paint 객체를 생성한다.
Paint shader_paint = new Paint();
shader_paint.setAntiAlias(true);
// 그림을 그릴 영역의 너비와 높이를 구한다.
int width = getWidth();
int height = getHeight();
// 너비와 높이중 작은 값의 절반을 반지름으로 지정한다.
int radius;
if(width > height) radius = height / 2;
else radius = width / 2;
// 그라데이션을 구성할 색상과 각 색상의 상대적 위치값을 배열로 구성한다.
int[] colors = {Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN, Color.BLUE,
Color.MAGENTA, Color.RED};
float[] color_pos = {0.0f, 0.17f, 0.34f, 0.51f, 0.68f, 0.85f, 1.0f};
// 수평으로 7 색상을 그라데이션하는 Shader 를 생성한다.
LinearGradient horizontal_linear = new LinearGradient(0, 0, width - 1, 0, colors, color_pos,
Shader.TileMode.REPEAT);
// 수직으로 두개의 그라데이션을 적용하되 시작색을 투명으로 지정하여 Shader 를 생성한다.
LinearGradient vertical_linear = new LinearGradient(0, 0, 0, height - 1, 0, Color.BLACK,
Shader.TileMode.MIRROR);
// 두개의 Shader 를 합성하는 Shader 를 생성한다.
ComposeShader shader = new ComposeShader(horizontal_linear, vertical_linear,
PorterDuff.Mode.DARKEN);
/*
// 두번째 그림의 ComposeShader
// 원형의 그라데이션을 구성하는 Shader 를 생성한다.
RadialGradient radial = new RadialGradient(width/2, height/2, radius, colors, color_pos,
Shader.TileMode.CLAMP);
// 시계방향으로 두가지 색상을 그라데이션하되 시작색을 투명으로 지정하여 Shader 를 생성한다.
SweepGradient sweep = new SweepGradient(width/2, height/2, 0, Color.BLACK);
// 두개의 Shader 를 합성하는 Shader 를 생성한다.
ComposeShader shader = new ComposeShader(radial, sweep, PorterDuff.Mode.DARKEN);
*/
// Paint 객체에 비트맵 패턴이 적용된 Shader 객체를 설정한다.
shader_paint.setShader(shader);
// Shader 가 적용된 페인트를 이용하여 사각형을 그린다.
canvas.drawRect(0, 0, width, height, shader_paint);
// 설정한 Shader 객체를 제거한다.
shader_paint.setShader(null);
3. 첨부된 예제
이 글에 첨부된 파일은 위에서 설명한 Shader 클래스의 하위 클래스들을 사용하여 그라데이션 및
비트맵 패턴을 출력하는 예제입니다. 해당 프로젝트에는 별도의 Bitmap 객체에 그리기 작업을 하고,
해당 비트맵을 onDraw 에서 이용하도록 구성되어 있습니다.


댓글