Paint过渡模式
参考资料:http://blog.csdn.net/aigestudio/article/details/41316141
在前面介绍了Paint画笔的一个方法颜色过滤器setColorFilter(ColorFilter filter),这里介绍Paint的另一个方法,过渡模式。
setXfermode(Xfermode xfermode)也就是图像混合模式,Xfermode与颜色过滤器参数一样有三种类的实现。分别是 AvoidXfermode、PixelXorXfermode和PorterDuffXfermode,由于前两种已经过时,节省学习成本,不再去研究了。
1、PorterDuffXfermode
PorterDuffXfermode(PorterDuff.Mode mode)在前面色彩混合时已经使用了部分模式,并提到如果使用了图形混合将会无效。那么这里就是可以使用图像混合模式的方法了。图像的混合方法有很多种,如下图

图片的说明:src为源图,Dis为目标图,那么后面图片可以理解为将源图绘制到目标图上的显示效果。
2、PorterDuff.Mode.DST_IN
源图像的范围中只绘制与其相交的目标图像
View的离屏缓冲,为了不影响混合以外的图像,将其放到一个独立的图层。其他的操作也遵循,先绘制目标图,再绘制源图,模式使用完复原。
目标图,不再贴代码

DST_IN模式代码
public class DisInView extends View{
private Paint mPaint;
private Bitmap bitmapDis, bitmapSrc;
private PorterDuffXfermode porterDuffXfermode;
public DisInView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bitmapDis = BitmapFactory.decodeResource(getResources(), R.mipmap.a);
bitmapSrc = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
// 图形混合前先保存到新图层,否则会连同之前内容一起计算
int sc = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
canvas.drawBitmap(bitmapDis, 0, 0, mPaint);
mPaint.setXfermode(porterDuffXfermode);
canvas.drawBitmap(bitmapSrc, 0, 120, mPaint);
mPaint.setXfermode(null);
// 还原画布
canvas.restoreToCount(sc);
}
}
效果图

3、PorterDuff.Mode.DST_OUT
在源图范围内只绘制与目标图不相交部分
public class DisOutView extends View{
private Paint mPaint;
private Bitmap bitmapDis, bitmapSrc;
private PorterDuffXfermode porterDuffXfermode;
public DisInView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bitmapDis = BitmapFactory.decodeResource(getResources(), R.mipmap.a);
bitmapSrc = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
// 图形混合前先保存到新图层,否则会连同之前内容一起计算
int sc = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
canvas.drawBitmap(bitmapDis, 0, 0, mPaint);
mPaint.setXfermode(porterDuffXfermode);
canvas.drawBitmap(bitmapSrc, 0, 120, mPaint);
mPaint.setXfermode(null);
// 还原画布
canvas.restoreToCount(sc);
}
}

4、PorterDuff.Mode.SCREEN
滤色效果
public class ScreenView extends View {
private Paint mPaint;
private Bitmap bitmapSrc;
private PorterDuffXfermode porterDuffXfermode;
public ScreenView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bitmapSrc = BitmapFactory.decodeResource(getResources(), R.mipmap.a);
porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.SCREEN);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
int sc = canvas.saveLayer(0,0,getWidth(),getHeight(),null,Canvas.ALL_SAVE_FLAG);
canvas.drawColor(0xccDD45C8);
mPaint.setXfermode(porterDuffXfermode);
canvas.drawBitmap(bitmapSrc, 0, 0, mPaint);
mPaint.setXfermode(null);
canvas.restoreToCount(sc);
}
}

浙公网安备 33010602011771号