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. AD19新功能之ActiveRoute

    AD19新增了ActiveRoute功能(自动布线功能),强大而实用: 1.河流式布线模式 在PCB面板中选择相应的网络,选中飞线,或者按住 Alt 然后鼠标从右下往左上进行框选,选中对应的飞线 然后 ...

  2. Maven配置环境变量

    Windows: 1:新建系统M2_HOME变量,并把安装maven路径拷贝上去 ​ 2:配置path变量,并把maven路径拷贝上去,这次的maven路径到bin ​ 3:测试maven环境是否配置 ...

  3. G1垃圾收集器原理剖析【官方解读】

    继续基于上一次https://www.cnblogs.com/webor2006/p/11135005.html的官方G1文档进行解读,上一次分析到了这: 话不多说,继续往前读: When perfo ...

  4. 再战css

    1.盒模型的属性: 1.padding .box{ width: 200px; height: 200px; background-color: red; /*顺时针 上右下左*/ padding: ...

  5. 【最短路+较复杂处理】PAT-L3-005. 垃圾箱分布

    L3-005. 垃圾箱分布 大家倒垃圾的时候,都希望垃圾箱距离自己比较近,但是谁都不愿意守着垃圾箱住.所以垃圾箱的位置必须选在到所有居民点的最短距离最长的地方[此处为第一重排序选择的条件],同时还要保 ...

  6. 【转】angular使用代理解决跨域

    原文:https://www.cnblogs.com/sghy/p/9111293.html ----------------------------------------------------- ...

  7. Spring MVC 学习笔记(一)

    • 1.SpringMVC概述 • 2.SpringMVC的HelloWorld • 3.使用@RequestMapping映射请求 • 4.映射请求参数&请求头 • 5.处理模型数据 • 6 ...

  8. LOJ 103子串查找——用hash代替kmp算法

    题意 给出两个字符串 $s_1,s_2$,求 $s_2$ 在 $s_1$ 中出现的次数. 分析 预处理出两个字符串的哈希值,再逐位比较. 时间复杂度为 $O(n+m)$,和 $kmp$ 算法一样. 可 ...

  9. 安装pip的三种方式

    pip是python的一个工具,用来安装python包特别方便.Linux系统是是内置python程序,因为许多Linux内置文件都是使用python来编写的,比如说yum. 1.脚本安装 通过脚本的 ...

  10. 44、[源码]-Spring容器创建-BeanFactory预准备

    44.[源码]-Spring容器创建-BeanFactory预准备 @Override public void refresh() throws BeansException, IllegalStat ...