Android scratch effect – proterduffxfermode

Time:2021-8-20

Android scratch effect – proterduffxfermode

Let’s see the effect
效果展示This scenario mainly simulates the winning effect of scratch music in some of our apps, which is mainly realized by using the proterduffxfermode class of Android.

proterDuffXfermode

When drawing with canvas in Android, you can use porterduffxfermode to mix the pixels of the drawn graphics with the pixels at the corresponding position in canvas according to certain rules to form new pixel values, so as to update the final pixel color value in canvas, which will create many interesting effects. The function of porterduffxfermode is very powerful. Other application scenarios are not introduced here, mainly to see the implementation and principle of scratch music.

public class PorterDuffXfermode extends Xfermode

Porterduffxfermode inherits xfermode. When using, pay attention to the API paint. Setxfermode (xfermode xfermode).
Porterduffxfermode supports the following mixed modes of more than ten pixel colors: clear, SRC, DST and Src_ OVER、DST_ OVER、SRC_ IN、DST_ IN、SRC_ OUT、DST_ OUT、SRC_ ATOP、DST_ ATOP、XOR、DARKEN、LIGHTEN、MULTIPLY、SCREEN。
Here we use porterduff. Mode. DST_ In, take two layers to draw the intersection and display the lower layer. This mode is used to operate.
在这里插入图片描述

  • Custom view inherits ImageView
    The code is relatively small, so I came directly
public class ProterDuffXfermodeView extends AppCompatImageView {
    private Bitmap mBgBitmap,mFgBitmap;
    private Paint mPaint;
    private Canvas mCanvas;
    private Path mPath;

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

     private void init() {
        //Create paint
        mPaint=new Paint();
        //Set transparency
        mPaint.setAlpha(0);
        //Set xfermode mode
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        //Paint type
        mPaint.setStyle(Paint.Style.STROKE);
        //Paint.join.miter-acute angle, round-arc, bevel-straight line
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeWidth(50);
        //Thread cap
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPath=new Path();
        Drawable drawable =getDrawable();
        mBgBitmap=((BitmapDrawable)drawable).getBitmap();
        mFgBitmap=Bitmap.createBitmap(mBgBitmap.getWidth(),mBgBitmap.getHeight(),Bitmap.Config.ARGB_8888);
        mCanvas=new Canvas(mFgBitmap);
        mCanvas.drawColor(Color.GRAY);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mPath.reset();
                mPath.moveTo(event.getX(), event.getY());
                break;
            case MotionEvent.ACTION_MOVE:
                mPath.lineTo(event.getX(), event.getY());
                break;
        }
        mCanvas.drawPath(mPath, mPaint);
        invalidate();
        return true;
    }
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(mBgBitmap, 0, 0,null);
        canvas.drawBitmap(mFgBitmap, 0, 0,null);
    }
}

First, there are two bitmaps, one is the background (scraping photos) and the other is the front (gray occlusion).
Here are a few APIs to explain

//Sets the style of the brush
        mPaint.setStyle(Paint.Style.FILL);// Fill content
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mPaint.setStyle(Paint.Style.STROKE);// Stroke 
//Thread cap
        mPaint.setStrokeCap(Paint.Cap.BUTT);// No,
        mPaint.setStrokeCap(Paint.Cap.ROUND);// Round
        mPaint.setStrokeCap(Paint.Cap.SQUARE);// square
mPaint.setStrokeJoin(Paint.Join.MITER);// Acute angle
	mPaint.setStrokeJoin(Paint.Join.ROUND);// arc
	mPaint.setStrokeJoin(Paint.Join.BEVEL);// straight line

Other APIs are easy to understand. I won’t introduce them here.
Ontouchevent event distribution
Path is mainly used
Path encapsulates a geometric path composed of lines and curves (quadratic and cubic Bezier curves). You can use the drawpath in canvas to draw this path (also supports different painting modes of paint), and can also be used to trim the canvas and draw text according to the path. We sometimes use path to describe the outline of an image, so it is also called contour line (contour line is only a way to use path, and the two are not equivalent).
Path detailsIf you don’t understand, you can read this article
Moveto moves the starting point of the next operation
Lineto adds a line from the previous point to the current point to the path
These two APIs are mainly used
Finally, ondraw()

  • XML can directly reference the custom view.
    Of course, there may be other ways to realize this function. Here is just an idea and the simplest implementation.

Welcome to the official account of the prince and the pig.