Basic tutorial for Android -- 8.3.7 Paint API -- Xfermode and PorterDuff (4)
This section introduces:
In the previous section, we wrote the first example about the use of Xfermode and PorterDuff: Implementation of ImageView for rounded corners and circular images,
We have realized the benefits brought by PorterDuff. Mode. DST_IN. In this section, we will continue to write examples for practical practitioners,
Do you still remember the implementation of pulling beautiful clothes in the basic Android tutorial 8.3.2?
At that time, our implementation scheme was to set 20*20 pixels near the finger touch area to transparent, like this:
I wonder if you have found a problem. When we clean beautiful clothes, they are all square blocks, but we draw a picture board.
When drawing a picture, The strikethroughs are smooth. Is there a way to combine the two and we can also smooth our clothes?
The answer must be yes, that is, Xfermode! In this section, we use another mode,DST_OUTMode!
Draw a target chart in different places
If you forget a certain mode or haven't even seen 18 modes, go to the following steps:
Basic tutorial for Android -- 8.3.5 painting API -- Xfermode and PorterDuff (2)
In addition, you still need to paste PorterDuff. Mode:
Well, let's not talk much about it. Let's start this section ~
1. Implementation and implementation process analysis:
To implement:
Well, I don't know how many times have you read that Gif image? I wonder if the figure is suitable for everyone's taste, pig.
It was obtained from someone else's APP. Don't ask me the phone number or leave a mailbox or something. I don't know anything ~ Find something,
Ask the old driver in the group, Kishen. Okay. Let's analyze the implementation process ~
Let's talk about the principle. In fact, there are two bitmaps. The first and the second are dressed in front and the second is not dressed,
Then, a Path is used to record the drawing drawn by the user, and then the DST_OUT mode is set for our paint brush.
The DST (target chart) overlapping the Path is a picture of the clothes that will become transparent! It's easy!
Let's further refine it! First, we need two bitmaps to store the first and second images. Here we make both bitmaps full screen! Next, set the paint brush, rounded corner, pen width, and anti-aliasing! Next, define a painting Path, that is, the method for the user to draw the area. After setting the Xfermode, draw the area! Then rewrite the onTouchEvent method, which is the same as the previous custom palette! At last, rewrite the onDraw () method. First draw the background image, call the user's method of drawing the region, and then draw the foreground image!
It may seem a bit complicated. In fact, the code is too simple to say ~
2. Code implementation:
Just a custom View --StripMeiZi. java
/*** Created by Jay on 0025. */public class StripMeiZi extends View {private Paint mPaint = new Paint (); private Path mPath = new Path (); private Canvas mCanvas; private Bitmap mBeforeBitmap; private Bitmap mBackBitmap; private int mLastX, mLastY; private int screenW, screenH; // screen width and height private Xfermode mXfermode = new porterduxfermode (PorterDuff. mode. DST_OUT); public StripMeiZi (Context context) {this (context, null);} public StripMeiZi (Context context, AttributeSet attrs) {super (context, attrs); screenW = ScreenUtil. getScreenW (context); screenH = ScreenUtil. getScreenH (context); init ();} public StripMeiZi (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr);} private void init () {// The image behind the image. Here, make it full screen mBackBitmap = BitmapFactory. decodeResource (getResources (), R. mipmap. meizi_back); mBackBitmap = Bitmap. createScaledBitmap (mBackBitmap, screenW, screenH, false); // draw the preceding image on the Canvas. mBeforeBitmap = Bitmap. createBitmap (screenW, screenH, Bitmap. config. ARGB_8888); mCanvas = new Canvas (mBeforeBitmap); mCanvas. drawBitmap (BitmapFactory. decodeResource (getResources (), R. mipmap. meizi_before), null, new RectF (0, 0, screenW, screenH), null); // set mPaint for the paint brush. setAntiAlias (true); mPaint. setDither (true); mPaint. setStyle (Paint. style. STROKE); mPaint. setStrokeJoin (Paint. join. ROUND); // rounded corner mPaint. setStrokeCap (Paint. cap. ROUND); // rounded corner mPaint. setStrokeWidth (80); // set the paint width} private void drawPath () {mPaint. setXfermode (mXfermode); mCanvas. drawPath (mPath, mPaint) ;}@ Override protected void onDraw (Canvas canvas) {canvas. drawBitmap (mBackBitmap, 0, 0, null); drawPath (); canvas. drawBitmap (mBeforeBitmap, 0, 0, null);} @ Override public boolean onTouchEvent (MotionEvent event) {int action = event. getAction (); int x = (int) event. getX (); int y = (int) event. getY (); switch (action) {case MotionEvent. ACTION_DOWN: mLastX = x; mLastY = y; mPath. moveTo (mLastX, mLastY); break; case MotionEvent. ACTION_MOVE: int dx = Math. abs (x-mLastX); int dy = Math. abs (y-mLastY); if (dx> 3 | dy> 3) mPath. lineTo (x, y); mLastX = x; mLastY = y; break;} invalidate (); return true ;}}