PorterDuffXfermode 丰富我们的绘图效果,PorterDuffXfermode 设置的是两个图层交集区域的显示方式,dst是先画的图形,而src是后话的图形;这里,使用一张图片作为另一张图片的遮罩层,通过控制遮罩层的图形,来控制下面被遮罩图形的显示效果。其中最常用的就是通过 DST_IN 、SRC_IN模式来京一个矩形图片变成圆角图片或者圆形图片的效果。

刮刮卡一般有两个图层,即上面用来被挂掉的图层和下面异常的图层。在初始状态下,上面的图层会将下面整个

图层覆盖,当你用手刮上面的图层的时候,下面的图层户慢慢显示出来,也像橡皮擦效果。使用PorterDuffXfermode 来实现

效果图:

android PorterDuffXfermode -------刮刮卡效果


首先做一下初始化工作,准备好图片,设置好Paint的一些属性,mPaint的一些设置

然后看一下,如何获取用户手指滑动所产生的的路径, 代码如下,使用path保存用户手指划过的路径。当然如果使用

贝塞尔曲线来做优化则会得到更好的显示效果,这里简单显示,就不用贝塞尔曲线了。

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;
}

最后,只需要使用DST_IN模式将路径绘制到前面覆盖的图层上即可。不过,还需要做最关键的一步,那就是将画笔的透明度

设置为 0 ,这样才能显示出擦除的效果。很多读者可能不太理解这里将透明度设置为0的原因,这是因为在使用PorterDuffXfermode  进行图层混合时,并不是简单的只进行图层的计算,同时也会去计算透明通道的值。正是由于混合了透明通道才形成了这样的效果。

public class GuaGuaView extends View {
private Bitmap mBgBitmap, mFgBitmap;
private Paint mPaint;
private Canvas canvas;
private Path mPath;

public GuaGuaView(Context context) {
super(context);
}

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

public void init(Context context) {
mPaint = new Paint();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeWidth(50);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPath = new Path();
//原图不可以随意进行操作 ,所以需要复制一个原图出来
mBgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);
mFgBitmap = Bitmap.createBitmap(mBgBitmap.getWidth(), mBgBitmap.getHeight(), Bitmap.Config.ARGB_8888);

canvas = new Canvas(mFgBitmap);
canvas.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;
}
canvas.drawPath(mPath, mPaint);
invalidate();
return true;
}

@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(mBgBitmap, 0, 0, null);
canvas.drawBitmap(mFgBitmap, 0, 0, null);
}
}

相关文章: