Android中的自繪View的那些事兒(五)之 遮罩濾鏡:BlurMaskFilter 和 EmbossMaskFilter 的簡介
阿新 • • 發佈:2019-01-22
MaskFilter
MaskFilter翻譯過來叫遮罩濾鏡,它可以為Paint邊緣的alpha通道應用轉換。目前有兩個子類:BlurMaskFilter 和 EmbossMaskFilter。它們分別可實現出模糊效果和浮雕效果。
BlurMaskFilter
BlurMaskFilter是指定一個半徑值使處理Paint的邊緣變模糊。我們來看看它的建構函式:
BlurMaskFilter(float radius, // 半徑值,必須大於0 BlurMaskFilter.Blur style) // 模糊效果,它是一個列舉值,其值包括:NORMAL、SOLID、OUTER 和 INNER
示例:
public class MyView extends View { public MyView(Context context) { this(context, null, 0); } public MyView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public MyView(Context context, @Nullable AttributeSet attrs, intdefStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.RED); paint.setMaskFilter(new BlurMaskFilter(30, BlurMaskFilter.Blur.NORMAL)); canvas.drawRect(100, 100, 250, 250, paint); paint.setMaskFilter(new BlurMaskFilter(30, BlurMaskFilter.Blur.SOLID)); canvas.drawRect(100, 350, 250, 500, paint); paint.setMaskFilter(new BlurMaskFilter(30, BlurMaskFilter.Blur.OUTER)); canvas.drawRect(100, 600, 250, 750, paint); paint.setMaskFilter(new BlurMaskFilter(30, BlurMaskFilter.Blur.INNER)); canvas.drawRect(100, 850, 250, 1000, paint); } }
執行效果:
看到執行效果後,是不是感覺到哪裡不對呢?原來因為在GPU硬體加速模式下,Paint的setMaskFilter是不被GPU支援的,所以為了能夠正常顯示MaskFilter的效果,需要將要繪製的Paint使用軟體渲染模式,即關閉硬體加速。我們來修改一下onDraw的程式碼:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.RED); setLayerType(View.LAYER_TYPE_SOFTWARE, paint); paint.setMaskFilter(new BlurMaskFilter(30, BlurMaskFilter.Blur.NORMAL)); canvas.drawRect(100, 100, 250, 250, paint); paint.setMaskFilter(new BlurMaskFilter(30, BlurMaskFilter.Blur.SOLID)); canvas.drawRect(100, 350, 250, 500, paint); paint.setMaskFilter(new BlurMaskFilter(30, BlurMaskFilter.Blur.OUTER)); canvas.drawRect(100, 600, 250, 750, paint); paint.setMaskFilter(new BlurMaskFilter(30, BlurMaskFilter.Blur.INNER)); canvas.drawRect(100, 850, 250, 1000, paint); }
執行效果:
注意到了嗎,新程式碼比舊程式碼就只是多了一行:setLayerType(View.LAYER_TYPE_SOFTWARE, paint); 便可以使paint的繪製關閉了硬體加速。其中,第二個引數也可為null,就表示當前View所有的繪製都會關閉硬體加速。除了針對View外,其實還可以對Activity或Application做關閉硬體加速的處理。方法就是在AndroidManifest.xml中使用android:hardwareAccelerated = "false",像這樣:
<application
……
android:hardwareAccelerated = "false">
<activity
……
android:hardwareAccelerated="false"/>
</application>
EmbossMaskFilter
EmbossMaskFilter是指定方向、光亮度、反射等級以及模糊級別這些引數來決定繪出浮雕效果。我們來看看它的建構函式:
EmbossMaskFilter (float[] direction, // 3個浮點值的陣列,X、Y、Z方向指定光源
float ambient, // 環境光亮度,取值範圍是0~1
float specular, // 反射等級,值如:8
float blurRadius) // 照明前的模糊量,值如:3
示例:
public class MyView extends View {
public MyView(Context context) {
this(context, null, 0);
}
public MyView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MyView(Context context, @Nullable AttributeSet attrs, intdefStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
setLayerType(View.LAYER_TYPE_SOFTWARE, paint);
float[] direction = new float[] { 1, 1, 1 };
float light = 1f;
float specular = 1;
float blur = 5;
paint.setMaskFilter(new EmbossMaskFilter(direction, light, specular,blur));
paint.setTextSize(100);
paint.setFlags(Paint.FAKE_BOLD_TEXT_FLAG);
canvas.drawText("Hello World", 50, 200, paint);
}
}
上面程式碼中,在Paint的setMaskFilter方法中傳入了一個EmbossMaskFilter物件,最後效果將輸出在的繪製文字Hello World中。EmbossMaskFilter的四個引數的值決定了浮雕的效果,大家可自行去試驗。