Custom Control Details (6): Paint Brush MaskFilter Filter

Posted by jwstockwell on Sat, 22 Jun 2019 23:39:52 +0200

First, look at an API: setMaskFilter(MaskFilter maskfilter):

Setting up MaskFilter, you can use different MaskFilter to achieve the effect of the filter, such as filtering, stereo, etc.

The following two subclasses of MaskFilter are available:

BlurMaskFilter: Specifies a vague style and radius to handle Paint's edges.

Emboss MaskFilter: Specifies the direction of the light source and the ambient light intensity to add relief effect.

 

Here's how Demo works:

1. BlurMaskFilter (Fuzzy Effect)

public class XBlurMaskFilterView extends View {
  
    public XBlurMaskFilterView(Context context) {
        super(context);
    }

    public XBlurMaskFilterView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public XBlurMaskFilterView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        BlurMaskFilter bmf = null;
        Paint paint=new Paint();
        paint.setColor(Color.RED);         //stroke color
        paint.setStyle(Paint.Style.FILL);  //Brush Style
        paint.setAntiAlias(true);          //Anti-Aliasing
        paint.setStrokeWidth(4);           //Brush thickness
        paint.setTextSize(60);             //Draw text size, unit px
        //The first parameter is the radius of ambiguity and the second parameter is the mode of ambiguity.

        bmf = new BlurMaskFilter(4f,BlurMaskFilter.Blur.NORMAL);
        paint.setMaskFilter(bmf);
        canvas.drawText("This is the effect of internal and external ambiguity.", 100, 100, paint);

        bmf = new BlurMaskFilter(4f,BlurMaskFilter.Blur.OUTER);
        paint.setMaskFilter(bmf);
        canvas.drawText("This is the effect of external ambiguity.", 100, 200, paint);

        bmf = new BlurMaskFilter(4f,BlurMaskFilter.Blur.INNER);
        paint.setMaskFilter(bmf);
        canvas.drawText("This is the effect of internal ambiguity.", 100, 300, paint);

        bmf = new BlurMaskFilter(4f,BlurMaskFilter.Blur.SOLID);
        paint.setMaskFilter(bmf);
        canvas.drawText("This is the effect of internal coarsening and external blurring.", 100, 400, paint);
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);     //Turn off hardware acceleration

    }
}

 

Design sketch:

 

Take a look at the core code:

new BlurMaskFilter(4f,BlurMaskFilter.Blur.NORMAL);
Two parameters:
1. Fuzzy radius
 2. Fuzzy Types
 BlurMaskFilter.Blur.NORMAL: Internal and External Fuzziness
 BlurMaskFilter.Blur.OUTER: External Ambiguity
 BlurMaskFilter.Blur.INNER: Internal Ambiguity
 BlurMaskFilter.Blur.SOLID: Internal coarsening, external blurring

 

 

Emboss MaskFilter

public class XEmbossMaskFilterView extends View {

    public XEmbossMaskFilterView(Context context) {
        super(context);
    }

    public XEmbossMaskFilterView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public XEmbossMaskFilterView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        float[] direction = new float[]{ 1, 1, 3 };   // Setting the direction of the light source
        float light = 0.4f;     //Setting Ambient Brightness
        float specular = 8;     // Definition of mirror reflection coefficient
        float blur = 6.0f;      //Fuzzy radius
        EmbossMaskFilter emboss=new EmbossMaskFilter(direction,light,specular,blur);

        Paint paint = new Paint();
        paint.setAntiAlias(true);          //Anti-Aliasing
        paint.setColor(Color.RED);//stroke color
        paint.setStyle(Paint.Style.FILL);  //Brush Style
        paint.setTextSize(120);             //Draw text size, unit px
        paint.setStrokeWidth(14);           //Brush thickness
        paint.setMaskFilter(emboss);

        paint.setMaskFilter(emboss);
        canvas.drawText("This is the relief effect.~", 50, 100, paint);


        setLayerType(View.LAYER_TYPE_SOFTWARE, null);     //Turn off hardware acceleration
    }
}

 

Design sketch:

 

Core code:

EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius) 

Parametric significance: Direction: Floating-point array for controlling the direction of light sources along the x, y, and Z axes Ambient: set ambient brightness between 0 and 1 Specular: specular reflection coefficient blurRadius: Fuzzy Radius

 

Note:

When using MaskFilter, it should be noted that when our targetSdKV Version >= 14, MaskFilter will not work, because Android in the API version 14 or above is the default on hardware acceleration, which makes full use of the characteristics of GPU, making the painting smoother, but will consume more memory. So we turn off the hardware acceleration, which can be turned on or off at different levels.

Application: Add: android: hardware Accelerated = "true" to the application node of the configuration file
 Activity: Add android: hardware Accelerated = "false" to the activity node of the configuration file
 View: You can get the View object and call it, or set it directly in the onDraw() method of View: view.setLayerType(View.LAYER_TYPE_HARDWARE, null);

Topics: Android