1. 程式人生 > >Android Paint之MaskFilter詳解

Android Paint之MaskFilter詳解

尊重原創,轉載請標明出處    http://blog.csdn.net/abcdef314159

這一篇來簡單分析一下Paint的setMaskFilter(MaskFilter maskfilter)方法,其中MaskFilter有兩個子類,一個BlurMaskFilter一個是EmbossMaskFilter,這裡先來看一下BlurMaskFilter這個類的原始碼

    public enum Blur {
        /**
         * Blur inside and outside the original border.
         */
        NORMAL(0),

        /**
         * Draw solid inside the border, blur outside.
         */
        SOLID(1),

        /**
         * Draw nothing inside the border, blur outside.
         */
        OUTER(2),

        /**
         * Blur inside the border, draw nothing outside.
         */
        INNER(3);
        
        Blur(int value) {
            native_int = value;
        }
        final int native_int;
    }
    
    /**
     * Create a blur maskfilter.
     *
     * @param radius The radius to extend the blur from the original mask. Must be > 0.
     * @param style  The Blur to use
     * @return       The new blur maskfilter
     */
    public BlurMaskFilter(float radius, Blur style) {
        native_instance = nativeConstructor(radius, style.native_int);
    }
構造方法很簡單,傳入一個半徑,是繪製陰影模糊的半徑,其中型別有以上4種,這裡就不在一一敘述,先看一下程式碼然後在直接看執行結果
public class MaskFilterView extends View {
	private Paint paint;
	private TextPaint mTextPaint;
	private BlurMaskFilter bmf1;
	private BlurMaskFilter bmf2;
	private BlurMaskFilter bmf3;
	private BlurMaskFilter bmf4;

	public MaskFilterView(Context context, AttributeSet attrs) {
		super(context, attrs);
		paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		paint.setColor(Color.RED);
		paint.setStyle(Style.FILL_AND_STROKE);
		mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
		mTextPaint.setTextSize(64);
		mTextPaint.setColor(Color.BLUE);
		mTextPaint.setTextAlign(Align.CENTER);

		bmf1 = new BlurMaskFilter(100, Blur.NORMAL);
		bmf2 = new BlurMaskFilter(100, Blur.SOLID);
		bmf3 = new BlurMaskFilter(100, Blur.OUTER);
		bmf4 = new BlurMaskFilter(100, Blur.INNER);

	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		canvas.translate(0, 200);
		canvas.drawColor(Color.WHITE);
		paint.setMaskFilter(bmf1);
		canvas.drawCircle(300, 300, 150, paint);
		canvas.drawText("NORMAL", 300, 600, mTextPaint);

		paint.setMaskFilter(bmf2);
		canvas.drawCircle(300, 900, 150, paint);
		canvas.drawText("SOLID", 300, 1200, mTextPaint);

		paint.setMaskFilter(bmf3);
		canvas.drawCircle(800, 300, 150, paint);
		canvas.drawText("OUTER", 800, 600, mTextPaint);

		paint.setMaskFilter(bmf4);
		canvas.drawCircle(800, 900, 150, paint);
		canvas.drawText("INNER", 800, 1200, mTextPaint);
	}
}
在Androidmanifest中要加上下面這段程式碼,否則不會出現任何模糊效果
        android:hardwareAccelerated="false"
來看一下執行的結果


效果很明顯,這裡就不在詳述。下面再來看一下EmbossMaskFilter這個類,先看一下他的構造方法

    /**
     * Create an emboss maskfilter
     *
     * @param direction  array of 3 scalars [x, y, z] specifying the direction of the light source
     * @param ambient    0...1 amount of ambient light
     * @param specular   coefficient for specular highlights (e.g. 8)
     * @param blurRadius amount to blur before applying lighting (e.g. 3)
     * @return           the emboss maskfilter
     */
    public EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius) {
        if (direction.length < 3) {
            throw new ArrayIndexOutOfBoundsException();
        }
        native_instance = nativeConstructor(direction, ambient, specular, blurRadius);
    }
其中direction表示x,y,z的三個方向,ambient表示的是光的強度,範圍為[0-1],specular是反射亮度的係數,blurRadius是指模糊的半徑,看一下程式碼
package test.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.EmbossMaskFilter;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.view.View;

public class MaskFilterView extends View {
	private Paint paint;
	EmbossMaskFilter emboss;

	public MaskFilterView(Context context, AttributeSet attrs) {
		super(context, attrs);
		paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		paint.setColor(Color.RED);
		paint.setStyle(Style.STROKE);
		paint.setStrokeWidth(32);
		paint.setTextSize(368);
		float[] direction = new float[] { 1, 1, 1 };
		// 設定環境光亮度
		float light = 0.1f;
		// 選擇要應用的反射等級
		float specular = 8;
		// 向mask應用一定級別的模糊
		float blur = 3;
		emboss = new EmbossMaskFilter(direction, light, specular, blur);

	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		canvas.drawText("山大王", 30, 400, paint);
	}

	@SuppressLint("NewApi")
	public void setparam(float x, float y, float z, float light,
			float specular, float blur) {
		emboss = new EmbossMaskFilter(new float[] { x, y, z }, light, specular,
				blur);
		paint.setMaskFilter(emboss);
		invalidate();
	}
}

看一下執行結果,這個會根據不同的值產生不同的結果,下面只擷取已其中的一個