package com.loaderman.customviewdemo.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View; import com.loaderman.customviewdemo.R; public class EraserView_SRCOUT extends View {
private Paint mBitPaint;
private Bitmap BmpDST, BmpSRC, BmpText;
private Path mPath;
private float mPreX, mPreY; public EraserView_SRCOUT(Context context, AttributeSet attrs) {
super(context, attrs);
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
mBitPaint = new Paint();
mBitPaint.setColor(Color.RED);
mBitPaint.setStyle(Paint.Style.STROKE);
mBitPaint.setStrokeWidth(45); BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2; BmpText = BitmapFactory.decodeResource(getResources(), R.drawable.guaguaka_text, null);
BmpSRC = BitmapFactory.decodeResource(getResources(), R.drawable.dog, options);
BmpDST = Bitmap.createBitmap(BmpSRC.getWidth(), BmpSRC.getHeight(), Bitmap.Config.ARGB_8888);
mPath = new Path();
} @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(BmpText, null, new RectF(0, 0, BmpDST.getWidth(), BmpDST.getHeight()), mBitPaint); int layerId = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG); //先把手指轨迹画到目标Bitmap上
Canvas c = new Canvas(BmpDST);
c.drawPath(mPath, mBitPaint); //然后把目标图像画到画布上
canvas.drawBitmap(BmpDST, 0, 0, mBitPaint); //计算源图像区域
mBitPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));//橡皮擦效果
canvas.drawBitmap(BmpSRC, 0, 0, mBitPaint); mBitPaint.setXfermode(null);
canvas.restoreToCount(layerId);
} @Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mPath.moveTo(event.getX(), event.getY());
mPreX = event.getX();
mPreY = event.getY();
return true;
case MotionEvent.ACTION_MOVE:
float endX = (mPreX + event.getX()) / 2;
float endY = (mPreY + event.getY()) / 2;
mPath.quadTo(mPreX, mPreY, endX, endY);
mPreX = event.getX();
mPreY = event.getY();
break;
case MotionEvent.ACTION_UP:
break;
}
postInvalidate();
return super.onTouchEvent(event);
}
}
  <com.loaderman.customviewdemo.view.EraserView_SRCOUT
android:layout_width="match_parent"
android:layout_height="match_parent" />

效果:

PorterDuffXfermode之PorterDuff.Mode.SRC_OUT的更多相关文章

  1. PorterDuffXfermode之PorterDuff.Mode.XOR入门学习

    package com.loaderman.customviewdemo.view; import android.content.Context; import android.graphics.* ...

  2. PorterDuffXfermode之PorterDuff.Mode.MULTIPLY

    package com.loaderman.customviewdemo.view; import android.content.Context; import android.graphics.B ...

  3. PorterDuffXfermode之PorterDuff.Mode.DST_IN

    package com.loaderman.customviewdemo.view; import android.animation.ValueAnimator; import android.co ...

  4. PorterDuffXfermode之PorterDuff.Mode.LIGHTEN

    package com.loaderman.customviewdemo.view; import android.content.Context; import android.graphics.B ...

  5. PorterDuffXfermode之PorterDuff.Mode.SRC_IN

    package com.loaderman.customviewdemo.view; import android.content.Context; import android.graphics.B ...

  6. PorterDuffXfermode的用法

    1.下面的Xfermode子类可以改变这种行为: AvoidXfermode  指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图). PixelXorXfermode  当覆盖 ...

  7. Android 颜色渲染PorterDuff及Xfermode详解

    在讲具体的使用之前补充一点知识,这就是 ProterDuff的由来: 相信大多数人看到这个ProterDuff单词很奇怪了吧,这肿么个意思呢,然后就用有道啊,金山啊开始翻译,但是翻译软件给出的结果肯定 ...

  8. PorterDuff及Xfermode初识

    图像合成,是将两幅退昂放在一起的动作,它使得我们能够同时看到两幅图像的特征. 我们可以首先在Canvas对象上绘制一个位图对象,然后再相同的Canvas对象上绘制第二个位图对象的方式来实现合成.不过这 ...

  9. Android 颜色渲染(九) PorterDuff及Xfermode详解

    版权声明:本文为博主原创文章,未经博主允许不得转载. Android 颜色渲染(九)  PorterDuff及Xfermode详解 之前已经讲过了除ComposeShader之外Shader的全部子类 ...

随机推荐

  1. apache 防盗链

    方法1:Apache防盗链的第一种实现方法,可以用rewrite实现 (1.)首先要确认Apache的rewrite module可用,打开 httpd.conf 文件,如果前面有注释去掉 LoadM ...

  2. Scala配置环境变量windows

    scala下载官网网址:http://www.scala-lang.org/download/ 1.下载scala-2.10.4.msi 2.点击安装scala,默认安装路径 3.配置环境变量   ( ...

  3. [转]对于BIO/NIO/AIO,你还只停留在烧开水的水平吗

    原文:https://www.javazhiyin.com/40106.html https://coding.imooc.com/class/381.html ------------------- ...

  4. Linux环境下安装mysql5.6(二进制包不是rpm格式)

    一.准备: 1.CentOS release 6.8 2.mysql-5.6.31-linux-glibc2.5-x86_64.tar.gz 3.Linux下MySQL5.6与MySQL5.7安装方法 ...

  5. TCL服务器端

    import socket def main(): # 创建套接字对象 tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STR ...

  6. __str__()方法

    只要定义了__str__(self)方法,那么就会打印从这个方法中return的数据 class Car: def __init__(self, newWheelNum, newColor): sel ...

  7. Luogu P4198 楼房重建 (李超线段树)

    题目 传送门 题解 首先转化成到(0,0)(0,0)(0,0)的斜率. 那么就是求多少个点是前缀最大值. 做法是线段树,用gao(i,x)gao(i,x)gao(i,x)表示在iii区间内,之前最大值 ...

  8. 02_Tutorial 2: Requests and Responses 请求和响应

    1.请求和响应 1.文档 https://www.django-rest-framework.org/tutorial/2-requests-and-responses/ https://q1mi.g ...

  9. bash: sz: command not found

    Linux系统中如果没有安装 lrzsz这个包,就会报rz.sz命令找不到,安装即可解决. 命令: yum install lrzsz 效果图:

  10. VIM--保存和退出等命令

    在 Linux 中使用 vim 时,输入 vim xxx.file 按 ESC,左下角就可以进行输入 :w 保存但不退出 :wq 保存并退出 :q 退出 :q! 强制退出,不保存 :e! 放弃所有修改 ...