반응형
안녕하세요 돼지왕 왕돼지입니다.
오늘은 paint 에 shader 적용하는 방법에 대해 같이 알아보겠습니다.
Shader 의 종류
LinearGradient
RadialGradient
SweepGradient
BitmapShader
ComposeShader
LinearGradient ( 선형 그래디언트 )
<APIs>
Shader Paint.setShader(Shader shader) // shader 제거시 null 값 대입
LinearGradient (float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)
LinearGradient (float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile)
// positions에는 두 점과의 상대적 거리, color 배열과 크기가 같아야 하며 0~1사이.
// position 값이 null 이면 같은 거리 가짐
<TitleMode>
타일 모드 | 설명 |
CLAMP | 무늬의 끝 부분을 계속 반복 |
MIRROR | 무늬를 반사시켜 계속 반복 |
REPEAT | 똑같은 무늬 계속 반복 |
<example>
setContentView(new MyView(this));
protected class MyView extends View{
public MyView(Context context){
super(context);
}
public void onDraw(Canvas canvas){
Paint Pnt = new Paint();
Pnt.setAntiAlias(true);
int[] colors = {Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.WHITE};
float[] pos = {0.0f, 0.1f, 0.6f, 0.9f, 1.0f};
Pnt.setShader(new LinearGradient(0, 0, 100, 0, Color.BLUE, Color.WHITE, TileMode.CLAMP));
canvas.drawRect(0, 0, 100, 100, Pnt);
// 반복
Pnt.setShader(new LinearGradient(0, 0, 100, 0, Color.BLUE, Color.WHITE, TileMode.REPEAT));
canvas.drawRect(0, 160, 320, 200, Pnt);
//여러 색
Pnt.setShader(new LinearGradient(0, 0, 320, 0, colors, null, TileMode.CLAMP));
canvas.drawRect(0, 260, 320, 300, Pnt);
//여러 색 with 배치
Pnt.setShader(new LinearGradient(0, 0, 320, 0, colors, pos, TileMode.CLAMP));
canvas.drawRect(0, 310, 320, 350, Pnt);
}
}
RadialGradient ( 원형 그래디언트 )
<APIs>
<example>
RadialGradient(float x, float y, float radius, int color0, int color1, Shader.TielMode tile)
RadialGradient(float x, float y, float radius, int[] colors, float[] positions, Shader.TileMode tile)
// 원의 중심에서 시작하여 원테두리 쪽으로 색상이 변함
// 원의 중심에서 시작하여 원테두리 쪽으로 색상이 변함
<example>
setContentView(new MyView(this));
protected class MyView extends View{
public MyView(Context context){
super(context);
}
public void onDraw(Canvas canvas){
Paint Pnt = new Paint();
Pnt.setAntiAlias(true);
int[] colors = {Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.WHITE};
float[] pos = {0.0f, 0.1f, 0.6f, 0.9f, 1.0f};
Pnt.setShader( new RadialGradient(80, 80, 70, Color.BLUE, Color.WHITE, TileMode.CLAMP) );
canvas.drawCircle(80, 80, 70, Pnt);
//여러 색
Pnt.setShader(new RadialGradient(80, 230, 70, colors, null, TileMode.CLAMP));
canvas.drawCircle(80, 230, 70, Pnt);
//여러 색 with 배치
Pnt.setShader(new RadialGradient(230, 230, 70, colors, pos, TileMode.CLAMP));
canvas.drawRect(230, 230, 70, Pnt);
}
}
SweepGradient ( 스윕 그래디언트 )
<APIs>
<example>
SweepGradient (float cx, float cy, int color0, int color1)
SweepGradient (float cx, float cy, int[] colors, float[] positions)
// 원의 3시방향에서 시작하여 반시계 방향으로 회전
// 원의 3시방향에서 시작하여 반시계 방향으로 회전
<example>
setContentView(new MyView(this));
protected class MyView extends View{
public MyView(Context context){
super(context);
}
public void onDraw(Canvas canvas){
Paint Pnt = new Paint();
Pnt.setAntiAlias(true);
int[] colors = {Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.WHITE};
float[] pos = {0.0f, 0.1f, 0.6f, 0.9f, 1.0f};
Pnt.setShader(new SweepGradient(80, 80, Color.BLUE, Color.WHITE, TileMode.CLAMP));
canvas.drawCircle(80, 80, 70, Pnt);
//여러 색
Pnt.setShader(new SweepGradient(80, 230, colors, null, TileMode.CLAMP));
canvas.drawCircle(80, 230, 70, Pnt);
//여러 색 with 배치
Pnt.setShader(new SweepGradient(230, 230, colors, pos, TileMode.CLAMP));
canvas.drawRect(230, 230, 70, Pnt);
}
}
BitmapShader ( 비트맵 쉐이더 )
<APIs>
BitmapShader (Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)
<example>
setContentView(new MyView(this));
protected class MyView extends View{
public MyView(Context context){
super(context);
}
public void onDraw(Canvas canvas){
Paint Pnt = new Paint();
Pnt.setAntiAlias(true);
Bitmap clover = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.clover);
Pnt.setShader(new BitmapShader (clover, TileMode.REPEAT, TileMode.REPEAT));
canvas.drawRect(0, 0, 320, 150, Pnt);
Pnt.setShader (new BitmapShader(clover, TileMode.MiRROR, TileMode.REPEAT));
canvas.drawRect(0, 160, 320, 310, Pnt);
}
}
ComposeShader ( 컴포즈 쉐이더 ) - 여러개의 Shader 동시 적용
<APIs>
ComposeShader (Shader shaderA, Shader shaderB, Xfermode mode)
ComposeShader (Shader shaderA, Shader shaderB, PorterDuff.Mode moe)
<example>
setContentView(new MyView(this));
protected class MyView extends View{
public MyView(Context context){
super(context);
}
public void onDraw(Canvas canvas){
Paint Pnt = new Paint();
Pnt.setAntiAlias(true);
Bitmap clover = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.clover);
ComposeShader comp = new ComposeShader(
new BitmapShader(clover, TileMode.REPEAT, TileMode.REPEAT),
new LinearGradient(0, 0, 320, 0, 0x0, Color.BLACK, TileMode.REPEAT),
new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
Pnt.setShader(comp);
canvas.drawRect(0, 0, 320, 200, Pnt);
}
}
ShapeDrawable
<What is it?>
- Shader는 런타임에만 사용할 수 있다는 면에서 활용이 제한적이며 View의 백그라운드를 쉐이더로 지정할 수도 없다.
- Shader는 런타임에만 사용할 수 있다는 면에서 활용이 제한적이며 View의 백그라운드를 쉐이더로 지정할 수도 없다.
- 그래서 Shader보다 더 일반적인 그리기 개체인 drawable을 XML에 미리 생성해놓을 수도 있다. (drawable 폴더에 배치)
<example>
<xml>
// (1,1) button
// gradient angle은 9시방향 기준으로 반시계방향
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#ffffff"
android:endColor="#0000ff"
android:angle="90"/>
</shape>
// (1, 2) button
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFF0000"/> <!-- 내부 -->
<stroke android:width="2px" android:color="#FFFFFF00"
android:dashWidth="2px" android:dashGap="2px" /> <!-- 테두리 -->
<corners android:radius="15px" /> <!-- 모서리 부드럽게 -->
</shape>
// (1, 3) button
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#FFFFFFFF" />
<stroke android:width="4px" android:color="#FF00FF00" />
</shape>
<java>
// (2, 1) button
GradientDrawable g = new GradientDrawable (GradientDrawable.Orientation.LEFT_RIGHT, new int[] {Color.BLUE, Color.GREEN});
btn.setBackgroundDrawable(g);
// (2,2) button
btn.setBackgroundDrawable (new ColorDrawable(Color.GREEN));
// (2, 3) button
PaintDrawable pd = new PaintDrawable (Color.YELLOW);
pd.setCornerRadius(10.0f);
btn.setBackgroundDrawable(pd);
// (3, 1) button 둥근 공
ShapeDrawalbe sd = new ShapeDrawable(new OvalShape());
sd.getPaint.setShader(new RadialGradient(60, 30, 50, Color.WHTE, Color.BLACK, TileMode.CLAMP));
btn.setBackgroundDrawable(sd);
// (3, 2) button 둥근 사각형
float[] outR = new float[] {5, 5, 30, 40, 5, 5, 5, 5};
RectF inRect = new RectF (30, 30, 30, 30);
float[] inR = new float[] {0, 0, 20, 30, 0, 0, 0, 0};
ShapeDrawable sd2 = new ShapeDrawable (new RoundRectShape(outR, inRect, inR));
sd2.getPaint().setColor(Color.MAGENTA);
btn.setBackgroundDrawable(sd2);
// outR -> 좌상단 원(2개), 우상단 원(2개), 우하단 원(2개), 좌하단 원(2개)
// rect -> 내부 사각형, 외곽 사각형으로부터의 거리인듯 (높을수록 작은 내부사각형)
// (3, 3) button 화살표
Path path = new Path();
path.moveTo(5,0);
path.lineTo(0,7);
path.lineTo(3,7);
path.lineTo(3, 10);
path.lineTo(7,10);
path.lineTo(7,7);
path.lineTo(10,7);
ShapeDrawable sd3 = new ShapeDrawable(new PathShape(path, 10, 10));
sd3.getPaint().setShader(new LinearGradient(0, 0, 0, 10, 0xff00ff00, 0xffff0000, TileMode.CLAMP));
btn.setBackgroundDrawable(sd3);
cf) xml로 지정한 drawable은 layout에서 <Button ~ android:background="@drawable/xxx"/>
<drawable tree>
Drawalbe - GradientDrawable
- ColorDrawable
- PaintDrawable
- ShapeDrawable - RectShape
- OvalShape
- PathShape
- RoundRectShape
- ArcShape
로그인 없이 추천 가능합니다. 손가락 꾸욱~
반응형
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[Android/안드로이드] Alarm Service 에 대해 알아본다. (0) | 2012.02.18 |
---|---|
[Android/안드로이드] Service 에 대해 알아본다. (0) | 2012.02.18 |
[Android/안드로이드] Paint에 Filter 적용하기 + draw에 효과주기. (1) | 2012.02.18 |
[Android/안드로이드] Canvas Operation 에 대해 알아보자. ( Transformation & Scaling & Rotating ) (0) | 2012.02.18 |
[Android/안드로이드] Frame Animation 사용해보자. (0) | 2012.02.18 |
댓글