天天看點

【Android】PorterDuffXfermode使用(通過消除背景層與重疊部分繪制組合圖形)

    利用PorterDuffXfermode,繪制組合圖形,過程我分成了4個步驟(onDraw方法裡面):

     1、通過canvas.saveLayout()先繪制一個背景圖層(這裡位置大小很重要,應該根據覆寫層來定義)(如果沒有背景層,産生效果可能和預期不太一樣)

     2、canvas.drawXXX()畫底部圖形Dst;

     4、paint.setXfermode()設定圖形相交模式

     5、canvas.drawBitmap(maskBm, x, y, paint)畫覆寫圖形

下面是圓形與矩形SRC_OUT模式下重疊後效果圖:

【Android】PorterDuffXfermode使用(通過消除背景層與重疊部分繪制組合圖形)

上圖實作代碼:

package com.example.d_customprogressbar.widget;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

public class PorterDuffXferView extends View{
	
	
	
	private Paint mPaint;
	private Paint mPaint2;
	
	private Rect rect;
	private Bitmap maskBm;//遮罩層
	
	public PorterDuffXferView(Context context, AttributeSet attrs) {
		super(context, attrs);
		mPaint = new Paint();
		mPaint.setColor(Color.YELLOW);
		mPaint.setAntiAlias(true);
		mPaint.setStyle(Style.FILL);
		
		mPaint2 = new Paint();
		mPaint2.setColor(Color.BLUE);
		mPaint2.setAntiAlias(true);
		mPaint2.setStyle(Style.FILL);
		
		//繪制遮罩層
		rect = new Rect(0,0, 250, 100);
		maskBm = Bitmap.createBitmap(250, 100, Config.ARGB_8888);
		Canvas canvas = new Canvas(maskBm);
		canvas.drawRect(rect, mPaint2);
//		canvas.saveLayer(0,0, 250, 100,  null,
//				Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG  
//				| Canvas.HAS_ALPHA_LAYER_SAVE_FLAG  
//				| Canvas.FULL_COLOR_LAYER_SAVE_FLAG  
//				| Canvas.CLIP_TO_LAYER_SAVE_FLAG);
		
		
	}



	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		//繪制背景圖層(這裡位置大小很重要,應該根據覆寫層來定義)(如果要實作SRC-OUT效果:那麼左上點與覆寫層一樣)
		int sc= canvas.saveLayer(100,100, 500, 500,  null,
				Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG  
				| Canvas.HAS_ALPHA_LAYER_SAVE_FLAG  
				| Canvas.FULL_COLOR_LAYER_SAVE_FLAG  
				| Canvas.CLIP_TO_LAYER_SAVE_FLAG);
		//畫圓-DST
		canvas.drawCircle(100, 100, 100, mPaint);
		//設定圖形相交模式
		mPaint.setXfermode(new PorterDuffXfermode(Mode.SRC_OUT));  
		//畫覆寫層(藍色矩形)SRC
		canvas.drawBitmap(maskBm, 100f, 100f, mPaint);  
		
//      mPaint.setXfermode(null);  
//		canvas.restoreToCount(sc);
		
	}

}
           

效果分析:

【Android】PorterDuffXfermode使用(通過消除背景層與重疊部分繪制組合圖形)

如果把背景層代碼注釋,覆寫層就變黑了,如下圖:

【Android】PorterDuffXfermode使用(通過消除背景層與重疊部分繪制組合圖形)

總結:用PorterDuffXfermode時,一定要先saveLayout()繪制背景層

Demo:http://download.csdn.net/detail/u013372185/9560935