본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[Android/안드로이드] paint에 shader 적용하기.

by 돼지왕 왕돼지 2012. 2. 18.
반응형


안녕하세요 돼지왕 왕돼지입니다.
오늘은 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>

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>

SweepGradient (float cx, float cy, int color0, int color1)
SweepGradient (float cx, float cy, int[] colors, float[] positions)
// 원의 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보다 더 일반적인 그리기 개체인 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
 
 
로그인 없이 추천 가능합니다. 손가락 꾸욱~





반응형

댓글