在Android中,提供了Shader類專門用來渲染圖像以及一些幾何圖形。
Shader類包括了5個直接子類,分別為:BitmapShader、ComposeShader、LinearGradient、RadialGradient以及SweepGradient。其中,BitmapShader用於圖像渲染;ComposeShader用於混合渲染;LinearGradient用於線性渲染;RadialGradient用於環形渲染;而SweepGradient則用於梯度渲染。
使用Shader類進行圖像渲染時,首先需要構建Shader對象,然后通過Paint的setShader()方法來設置渲染對象,最后將這個Paint對象繪制到屏幕上即可。
有一點需要注意,使用不同的方式渲染圖像時需要構建不同的對象。
1.BitmapShader(圖像渲染)
BitmapShader的作用是使用一張位圖作為紋理來對某一區域進行填充。可以想象成在一塊區域內鋪瓷磚,只是這里的瓷磚是一張張位圖而已。
BitmapShader函數原型為:
public BitmapShader (Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY);
其中,參數bitmap表示用來作為紋理填充的位圖;參數tileX表示在位圖X方向上位圖銜接形式;參數tileY表示在位圖Y方向上位圖銜接形式。
Shader.TileMode有3種參數可供選擇,分別為CLAMP、REPEAT和MIRROR。
CLAMP的作用是如果渲染器超出原始邊界范圍,則會復制邊緣顏色對超出范圍的區域進行着色。REPEAT的作用是在橫向和縱向上以平鋪的形式重復渲染位圖。MIRROR的作用是在橫向和縱向上以鏡像的方式重復渲染位圖。
2.LinearGradient(線性渲染)
LinearGradient的作用是實現某一區域內顏色的線性漸變效果。
LinearGradient的函數原型為:
public LinearGradient (float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile);
其中,參數x0表示漸變的起始點x坐標;參數y0表示漸變的起始點y坐標;參數x1表示漸變的終點x坐標;參數y1表示漸變的終點y坐標;參數colors表示漸變的顏色數組;參數positions用來指定顏色數組的相對位置;參數tile表示平鋪方式。
通常,參數positions設為null,表示顏色數組以斜坡線的形式均勻分布。
3.ComposeShader(混合渲染)
ComposeShader的作用是實現渲染效果的疊加,如BitmapShader與LinearGradient的混合渲染效果等。
ComposeShader的函數原型為:
public ComposeShader (Shader shaderA, Shader shaderB, PorterDuff.Mode mode);
其中,參數shaderA表示某一種渲染效果;參數shaderB也表示某一種渲染效果;參數mode表示兩種渲染效果的疊加模式。
PorterDuff.Mode有16種參數可供選擇,分別為:CLEAR、SRC、DST、SRC_OVER、DST_OVER、SRC_IN、DST_IN、SRC_OUT、DST_OUT、SRC_ATOP、DST_ATOP、XOR、DARKEN、LIGHTEN、MULTIPLY、SCREEN。
這16種疊加模式的具體疊加效果如圖1所示。

圖1 疊加效果
4.RadialGradient(環形渲染)
RadialGradient的作用是在某一區域內實現環形的漸變效果。
RadialGradient的函數原型為:
public RadialGradient (float x, float y, float radius, int[] colors, float[] positions, Shader.TileMode tile);
其中,參數x表示環形的圓心x坐標;參數y表示環形的圓心y坐標;參數radius表示環形的半徑;參數colors表示環形漸變的顏色數組;參數positions用來指定顏色數組的相對位置;參數tile表示平鋪的方式。
5.SweepGradient(梯度渲染)
SweepGradient也稱為掃描渲染,是指在某一中心以x軸正方向逆時針旋轉一周而形成的掃描效果的渲染形式。
SweepGradient的函數原型為:
public SweepGradient (float cx, float cy, int[] colors, float[] positions);
其中,參數cx表示掃描的中心x坐標;參數cy表示掃描的中心y坐標;參數colors表示梯度漸變的顏色數組;參數positions用來指定顏色數組的相對位置。
6.實例
在本實例中,分別實現了上述的5種渲染效果。效果如圖2所示。其中,最上面的是BitmapShader效果圖;第二排的左邊是LinearGradient的效果圖;第二排的右邊是RadialGradient的效果圖;第三排的左邊是ComposeShader的效果圖(LinearGradient與RadialGradient的混合效果);第三排的右邊是SweepGradient的效果圖。

圖2 渲染效果
定義了MyView類,用來繪制各種渲染效果,MyView.java源碼如下。
MyView.Java源碼
1 package com.example.android_imageshader; 2 3 import android.annotation.SuppressLint; 4 import android.content.Context; 5 import android.graphics.Bitmap; 6 import android.graphics.BitmapShader; 7 import android.graphics.Canvas; 8 import android.graphics.Color; 9 import android.graphics.ComposeShader; 10 import android.graphics.LinearGradient; 11 import android.graphics.Paint; 12 import android.graphics.PorterDuff; 13 import android.graphics.RadialGradient; 14 import android.graphics.RectF; 15 import android.graphics.Shader; 16 import android.graphics.SweepGradient; 17 import android.graphics.drawable.BitmapDrawable; 18 import android.view.View; 19 20 @SuppressLint({ "DrawAllocation", "DrawAllocation", "DrawAllocation" }) 21 public class MyView extends View { 22 23 Bitmap mBitmap = null; //Bitmap對象 24 Shader mBitmapShader = null; //Bitmap渲染對象 25 Shader mLinearGradient = null; //線性漸變渲染對象 26 Shader mComposeShader = null; //混合渲染對象 27 Shader mRadialGradient = null; //環形渲染對象 28 Shader mSweepGradient = null; //梯度渲染對象 29 30 public MyView(Context context) { 31 super(context); 32 33 //加載圖像資源 34 mBitmap = ((BitmapDrawable) getResources(). 35 getDrawable(R.drawable.snow)).getBitmap(); 36 37 //創建Bitmap渲染對象 38 mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT, 39 Shader.TileMode.MIRROR); 40 41 //創建線性渲染對象 42 int mColorLinear[] = {Color.RED, Color.GREEN, Color.BLUE, Color.WHITE}; 43 mLinearGradient = new LinearGradient(0, 0, 100, 100, mColorLinear, null, 44 Shader.TileMode.REPEAT); 45 46 //創建環形渲染對象 47 int mColorRadial[] = {Color.GREEN, Color.RED, Color.BLUE, Color.WHITE}; 48 mRadialGradient = new RadialGradient(350, 325, 75, mColorRadial, null, 49 Shader.TileMode.REPEAT); 50 51 //創建混合渲染對象 52 mComposeShader = new ComposeShader(mLinearGradient, mRadialGradient, 53 PorterDuff.Mode.DARKEN); 54 55 //創建梯形渲染對象 56 int mColorSweep[] = {Color.GREEN, Color.RED, Color.BLUE, Color.YELLOW, Color.GREEN}; 57 mSweepGradient = new SweepGradient(370, 495, mColorSweep, null); 58 } 59 60 public void onDraw(Canvas canvas) { 61 super.onDraw(canvas); 62 63 Paint mPaint = new Paint(); 64 canvas.drawColor(Color.GRAY); //背景置為灰色 65 66 //繪制Bitmap渲染的橢圓 67 mPaint.setShader(mBitmapShader); 68 canvas.drawOval(new RectF(90, 20, 90+mBitmap.getWidth(), 69 20+mBitmap.getHeight()), mPaint); 70 71 //繪制線性漸變的矩形 72 mPaint.setShader(mLinearGradient); 73 canvas.drawRect(10, 250, 250, 400, mPaint); 74 75 //繪制環形漸變的圓 76 mPaint.setShader(mRadialGradient); 77 canvas.drawCircle(350, 325, 75, mPaint); 78 79 //繪制混合漸變(線性與環形混合)的矩形 80 mPaint.setShader(mComposeShader); 81 canvas.drawRect(10, 420, 250, 570, mPaint); 82 83 //繪制梯形漸變的矩形 84 mPaint.setShader(mSweepGradient); 85 canvas.drawRect(270, 420, 470, 570, mPaint); 86 } 87 }
相關資料:
Android學習筆記進階15之Shader渲染:
http://www.cnblogs.com/snake-hand/archive/2012/02/17/2454394.html
Graphics中PorterDuff.Mode!!!!!!
http://blog.csdn.net/dylancao/article/details/7722617
