PorterDuffXfermode之PorterDuff.Mode.SRC_OUT
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的更多相关文章
- PorterDuffXfermode之PorterDuff.Mode.XOR入门学习
package com.loaderman.customviewdemo.view; import android.content.Context; import android.graphics.* ...
- PorterDuffXfermode之PorterDuff.Mode.MULTIPLY
package com.loaderman.customviewdemo.view; import android.content.Context; import android.graphics.B ...
- PorterDuffXfermode之PorterDuff.Mode.DST_IN
package com.loaderman.customviewdemo.view; import android.animation.ValueAnimator; import android.co ...
- PorterDuffXfermode之PorterDuff.Mode.LIGHTEN
package com.loaderman.customviewdemo.view; import android.content.Context; import android.graphics.B ...
- PorterDuffXfermode之PorterDuff.Mode.SRC_IN
package com.loaderman.customviewdemo.view; import android.content.Context; import android.graphics.B ...
- PorterDuffXfermode的用法
1.下面的Xfermode子类可以改变这种行为: AvoidXfermode 指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图). PixelXorXfermode 当覆盖 ...
- Android 颜色渲染PorterDuff及Xfermode详解
在讲具体的使用之前补充一点知识,这就是 ProterDuff的由来: 相信大多数人看到这个ProterDuff单词很奇怪了吧,这肿么个意思呢,然后就用有道啊,金山啊开始翻译,但是翻译软件给出的结果肯定 ...
- PorterDuff及Xfermode初识
图像合成,是将两幅退昂放在一起的动作,它使得我们能够同时看到两幅图像的特征. 我们可以首先在Canvas对象上绘制一个位图对象,然后再相同的Canvas对象上绘制第二个位图对象的方式来实现合成.不过这 ...
- Android 颜色渲染(九) PorterDuff及Xfermode详解
版权声明:本文为博主原创文章,未经博主允许不得转载. Android 颜色渲染(九) PorterDuff及Xfermode详解 之前已经讲过了除ComposeShader之外Shader的全部子类 ...
随机推荐
- Ubuntu apt-get锁定问题
- Mysql安装与问题合集
下载mysql https://dev.mysql.com/downloads/mysql/ 下载历史版本 看这篇文章 https://www.cnblogs.com/reyinever/p/8551 ...
- SOUL软件小结
soul 基于心灵的智能社交APP.功能是寻找最适合自己的灵魂伴侣 基于心灵测试给你智能匹配最简单的社交关系 匿名聊天软件一般都是没有机器人的,机器人一般不能对点聊很长时间 用户来源与动机 用户引流来 ...
- 链表实现队列(python)
# -*- coding: utf-8 -*- from collections import deque class Node(object): def __init__(self, value=N ...
- 《AlwaysRun!》第五次作业:项目需求分析改进与系统设计
项目 内容 这个作业属于哪个课程 2016级软件工程(西北师范大学) 这个作业的要求在哪里 实验九 团队作业5—团队项目需求改进与系统设计 团队名称 Always Run! 作业学习目标 (1)掌握 ...
- machine learning(9) -- classification:Decision boundary
machine learning(9) -- classification:Decision boundary 上图的decision boundary是一条直线,是属于预测函数的一个属性(当参数已经 ...
- Mybatis之动态SQL&OGNL表达式
1.接口 public interface MemberMapperDynamicSQL { public List<Members> selectMembersByIf(Members ...
- pandas 3
参考资料:https://mp.weixin.qq.com/s/9z3JVBkZpasC_F0ar_7JJA 删除多列:df.drop(col_names_list, axis=1, inplace= ...
- 用于异步事件驱动的 P 语言 P Language
微软最近开源了P语言,致力于在Linux.macOS和Windows上编写安全的异步事件驱动程序. 微软将P描述为一种领域特定语言,对异步系统的组件间通信进行建模,例如嵌入式.网络或分布式系统.P程序 ...
- Object.defineProperty 相关学习
Object.defineProperty 学习 描述: 方法直接在对象上定义一个新属性,或修改对象上的现有属性 并返回该对象.该方法允许精确地添加或修改对象上的属性: 语法: Object.de ...