PorterDuff.Mode,剛接觸到這個名字的時候,看不懂什麼意思。通過翻譯也沒有查出結果,後來通過一篇博客瞭解到原來PorterDuff是兩個人的名字的組合:Tomas Proter和 Tom Duff.,他們是最早在SIGGRAPH上提出圖形混合概念的大神級人物。通過這一點,其實我們就可以瞭解到,原來PorterDuff原來是處理圖形的混合的,是一種渲染效果。
在看PorterDuff如何添加效果之前我們首先要先看, Xfermode的概念。
Xfermode
Xfermode也是凸顯絢爛的方式,可以通過修改Paint的Xfermode來影響在Canvas已有的圖像上面繪製新的顏色的方式 。
通過API我們可以查詢到Xfermode包含三個子類:
AvoidXfermode:指定了一個顏色和容差,強制Paint避免在它上面繪圖(或者只在它上面繪圖)。
PixelXorXfermode: 當覆蓋已有的顏色時,應用一個簡單的像素異或操作。
PorterDuffXfermode: 這是一個非常強大的轉換模式,使用它,可以使用圖像合成的16條Porter-Duff規則的任意一條來控制Paint如何與已有的Canvas圖像進行交互。到這我們終於知道爲什麼要介紹Xfermode的了。
PorterDuff.Mode
不免俗套,先貼出16種模式的效果圖:
現在再來介紹下16種模式:
1.PorterDuff.Mode.CLEAR
所繪製不會提交到畫布上,也就是不顯示內容。
2.PorterDuff.Mode.SRC
顯示繪製圖片的上層圖片。
3.PorterDuff.Mode.DST
顯示繪製圖片下層圖片。
4.PorterDuff.Mode.SRC_OVER
正常繪製顯示,上下層繪製疊蓋。
5.PorterDuff.Mode.DST_OVER
上下層都顯示,下層居上顯示。
6.PorterDuff.Mode.SRC_IN
取兩層繪製交集。顯示上層。
7.PorterDuff.Mode.DST_IN
取兩層繪製交集。顯示下層。
8.PorterDuff.Mode.SRC_OUT
取上層繪製非交集部分。
9.PorterDuff.Mode.DST_OUT
取下層繪製非交集部分。
10.PorterDuff.Mode.SRC_ATOP
取下層非交集部分與上層交集部分。
11.PorterDuff.Mode.DST_ATOP
取上層非交集部分與下層交集部分。
12.PorterDuff.Mode.XOR
異或:去除兩圖層交集部分。
13.PorterDuff.Mode.DARKEN
取兩圖層全部區域,交集部分顏色加深。
14.PorterDuff.Mode.LIGHTEN
取兩圖層全部,點亮交集部分顏色。
15.PorterDuff.Mode.MULTIPLY
取兩圖層交集部分疊加後顏色。
16.PorterDuff.Mode.SCREEN
取兩圖層全部區域,交集部分變爲透明色。
PorterDuff.Mode的使用 ##
使用PorterDuff.Mode不能直接在View的畫布上使用,也就是不能在自定義View的onDraw()方法中使用。必須在Bitmap的Canvas上使用,PorterDuff.Mode效果是應用在Paint上的,通過Paint來設置效果。我們來看具體的步驟和代碼。
1. 創建一個Bitmap對象。
2. 創建一個Bitmap對象的Canvas畫布。
3. 在Bitmap的Canvas上繪製圖形,在繪製的圖形的Paint上通過setXfermode(Xfermode xfermode)添加圖形混合效果,該方法傳入的是一個Xfermode對象,所以使我們要先創建一個Xfermode 的對象:
PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.XOR);
- 這樣效果就添加成功了。
public class MyBitmapViewAnother extends View {
private int width;//設置高
private int height;//設置高
private Paint mPaint;
//設置一個Bitmap
private Bitmap bitmap;
//創建該Bitmap的畫布
private Canvas bitmapCanvas;
private Paint mPaintCirlcle;
private Paint mPaintRect;
public MyBitmapViewAnother(Context context) {
super(context);
}
public MyBitmapViewAnother(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();//Bitmap的畫筆
mPaintCirlcle = new Paint();
mPaintCirlcle.setAntiAlias(true);
mPaintCirlcle.setColor(Color.YELLOW);
// PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.DST_OVER);
// mPaintCirlcle.setXfermode(mode);
mPaintRect = new Paint();
mPaintRect.setAntiAlias(true);
mPaintRect.setColor(Color.GRAY);
PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.XOR);
mPaintRect.setXfermode(mode);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);//設置寬和高
//自己創建一個Bitmap
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmapCanvas = new Canvas(bitmap);//該畫布爲bitmap的
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//設置該View畫布的背景
canvas.drawColor(Color.LTGRAY);
canvas.drawBitmap(bitmap, 0, 0, mPaint);
bitmapCanvas.drawCircle(width / 2, height / 2, width / 2, mPaintCirlcle);
bitmapCanvas.drawRect(0, 0, width / 2, height / 2, mPaintRect);
}
}
代碼中使用的是PorterDuff.Mode.XOR交集部分不顯示的效果。