Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 圖像處理(一) : Shader

Android 圖像處理(一) : Shader

編輯:關於Android編程

?之前一段時間,我都在研究Android自定義View的相關知識,隨著逐漸的深入,漸漸了解到了一些Android圖像處理的知識,主要是Bitmap,Canvas,Shader,Matric,ColorFilter和Xfermode的使用。所以准備寫一系列文章介紹一下這些方面的知識。

圖像處理相關概念介紹

?要想了解Shader的概念,首先要了解Android圖像處理中幾個比較重要的概念:bitmap,canvas,drawing primitive,paint。需要注意的是,上述四個詞並不指android中的類,而是四個概念。
?bitmap指畫布。畫家畫圖時都需要一塊畫布,然後才會在畫布上繪制各種形狀和顏色,Android中的Bitmap就有畫布的功能。比如下面這段代碼。


    static Bitmap makeSrc(int w,int h) {
            Bitmap bm = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);
            Canvas c = new Canvas(bm);
            Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);

            p.setColor(0xFF66AAFF);
            c.drawRect(100,100,100,100,p);
            return bm;

}

?Bitmap這裡就充當一個畫布的作用,之後Canvas的操作都是在這個Bitmap畫布進行繪制。
?canvas是繪制操作的集合,你可以把它理解成畫家的手,通過它你可以在畫布上繪制各種圖像和顏色。相應的在Android的Canvas類中就封裝了繪制相關的各種操作,比如drawXXX系列。
?drawing primitive指繪制實體或者原始內容,比如畫家繪畫時可能會畫一個蘋果,也可能只是繪制一些線段,矩形等。這些都是繪制實體。在Android中,Path,Rect,Text,Bitmap都可以充當drawing primitive的角色,因為你都可以把它們繪制到畫布上。你也可以這樣理解,Canvas中的drawXXX系列函數中的XXX都是指drawing primitive。
?paint就是指畫家的神奇畫筆啦。Android中的Paint類就充當這個角色,我們可以通過Paint來配置畫筆的顏色,粗細,紋理等。我們系列文章主要講解的Shader,ColorFilter,Xfermode三個類都和Paint直接相關。

Shader概念介紹

?Shader,也就是所謂的著色器。它應用於計算機圖形學領域,指一組提供計算機圖像資源在執行繪制任務時使用的指令,用於計算圖像的顏色和明暗。從技術角度來看,著色器是渲染器的一部分,它負責計算目標的顏色。以我的理解,Paint就是渲染器,Paint.setShader這個函數展示了著色器和渲染器之間的關系。下面這段代碼顯示了Shader的使用方式。


    String text = "Shader";
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.photo);
    BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    Paint paint = new Paint();
    paint.setShader(bitmapShader);
    paint.setTextSize(100);
    paint.setStrokeWidth(50);
    canvas.drawText(text,0,text.length(),150,400,paint);

?上邊的代碼片段使用了BitmapShader,也就是說使用圖片上相應位置的顏色進行著色。就相當於使用這個圖片作為背景,字體顏色是透明色,字體在(150,400)位置進行繪制,字體最終顯示的顏色就是圖片中相應位置的顏色。
?Shader.TileMode是指平鋪模式,一共有三種類型:CLAMP,MIRROR,REPEAT。構造函數中後兩個參數分別規定了當繪制實體的x或y軸范圍超過一定范圍時(比如BitmapShader中Bitmap的大小,LinearGradient中構造函數傳入的x,y值),著色器填充的行為。我們以BitmapShader為例,來講述三種模式的區別。原圖如下所示,來自於這個博客。

使用的bitmap原圖


    Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.img);
    BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.XXX, Shader.TileMode.XXXX);
    Paint paint = new Paint();
    paint.setShader(bitmapShader);
    canvas.drawColor(Color.GRAY);
    canvas.drawRect(0,0,800,800,paint);

?Shader.TileMode.CLAMP是邊緣拉伸模式,它會拉伸邊緣的一個像素來填充其他區域。效果圖如下所示,我們可以看到,超出bitmap大小的范圍都被圖片邊緣的顏色所填充。

clamp效果圖<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPj88Y29kZT5TaGFkZXIuVGlsZU1vZGUuTUlSUk9Syse+tc/xxKPKvaOs0rK+zcrHy7XL/M2ouf2+tc/xseS7r8C0zO6z5Mbky/vH+NPyoaPQ6NKq16LS4rXEysejrDxzdHJvbmc+VGlsZU1vZGXKx8/ItKbA7XnW4be9z/K1xLLZ1/ejrMi7uvPU2r340NB41uG3vc/ytcSy2df3oaPSsr7NysfLtc/IvfjQ0HnW4be9z/K1xL61z/Gy2df3o6zIu7rz1Nq9+NDQeNbht73P8snPtcS+tc/xstnX9zwvc3Ryb25nPqGjsru5/c7SvvW1w7rDz/HPyL340NDExLj2t73P8snPtcSy2df3sqLDu9PQyrLDtMf4sfCjrNfu1tXQp7n7ysfSu9H5tcSho8bk0Ke5+828yOfPwsv5yr46PGJyIC8+DQo8aW1nIGFsdD0="mirror效果圖" src="/uploadfile/Collfiles/20160827/20160827093144266.png" title="\" />
?Shader.TileMode.REPEAT是重復模式,通過復制來填充其他區域
repeat效果圖
?你也可以對x,y軸使用不同的TileMode,可以得到不同的效果。
clamp+mirro效果圖

Shader類型介紹

?BitmapShader的用法很簡單,上邊的實例中也有用到,所以我們就不再詳細介紹它了。

LinearGradient

?LinearGradient是顏色線性漸變的著色器。它有兩個構造函數:
?雙色漸變的構造函數是

public LinearGradient (float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)

?參數中,(x0,y0)表示漸變的起點,(x1,y1)表示漸變的終點坐標,這兩點都是相對於屏幕坐標系。color0,color1分別表示起點的顏色和終點的顏色。不同於BitmapShader需要x,y軸兩個平鋪模式參數,LinearGradient只需要一個TileMode,表示從(x0,y0)到(x1,y1)方向上的平鋪模式
LinearGradient的平鋪效果可能比較難以理解,需要大家多做幾次實驗才能明白。
?下圖是200*200的由紅色到黃色的線性漸變效果著色器繪制200*200的矩形的效果圖,著色器的TileMode為MIRROR:
linegradient1
?下圖是上述的著色器繪制400*400的效果圖,我們可以看到二者的區別,在屏幕坐標軸的(200,200)方向(第二張圖中的黑色線段所代表的方向)上顏色是先從紅色到黃色,超過(200,200)這個點之後,由於設置平鋪模式為MIRROR所以顏色就又從黃色逐漸變成了紅色。這個對角線外上的點的顏色是和其在對角線上(-200,200)方向上的投影點的顏色相同,也就是第二張圖中藍色直線上點的顏色都是相同的。
linegradient2
linegradient5

?多色漸變的構造函數是

public LinearGradient (float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile)
?多色漸變的構造函數中,我們可以傳入多個顏色,和每個顏色的占比。而且當positions參數傳入null時,代表顏色是均勻的填充整個漸變區域的,顯得比較柔和。
linegradient

SweepGradient

?SweepGradient是梯度漸變,也稱為掃描式漸變,效果有點類似與雷達掃描效果。它也有兩個構造方法,分別為兩色漸變和多色漸變,二者的區別和之前介紹的LinearGradient的構造函數類似,我們這裡就只介紹雙色漸變的構造函數:

public SweepGradient(float cx, float cy, int color0, int color1)
?在構造函數的參數中,(cx,cy)表示漸變效果的中心點,也就是雷達掃描的圓點。color0和color1表示漸變的起點色和終點色。顏色漸變是順時針的,從中心點的x軸正方形開始。需要注意的是,這裡構造函數並不需要TileMode,因為梯度漸變的邊界相當於無限大的。
sweepgradient

RadialGradient

?RadialGradient是徑向漸變,徑向漸變就是從圓的中心點向四周漸變的特效,你可以把它想象成一個圓,從圓點到圓周沿著半徑有顏色的漸變效果。它也有兩個構造函數,我們只介紹雙色漸變的構造函數。

public RadialGradient(float centerX, float centerY, float radius,
int centerColor, int edgeColor, TileMode tileMode)

?在構造函數的參數中,(centerX,centerY)表示徑向漸變中的圓點,radius表示圓的半徑長度,centerColor表示圓點顏色,edgeColor表示圓周顏色,titleMode表示平鋪模式,它的作用方向是沿著半徑方向。下圖就是一個有紅色到黃色的徑向漸變,平鋪模式為CLAMP,所以超出圓周的范圍的點的顏色就都是圓周的顏色黃色。
radialgradient

ComposeShader

?ComposeShader用來組合不同的Shader,可以將兩個不同的Shader組合在一起,它有兩個構造函數:

ComposeShader (Shader shaderA, Shader shaderB, Xfermode mode)  
ComposeShader (Shader shaderA, Shader shaderB, PorterDuff.Mode mode)  

?二者的區別就是一個使用PorterDuff的模式,另一個可以使用所有的Xfermode。這兩個混合模式我們在之後的文章中將會詳細講到。

後記

?這裡只是簡單介紹了一下Shader的概念和基本用法,之後會多加一些實際使用的情況,希望大家持續關注。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved