Xfermode 图像混合模式
Xfermode只作用于源图像即SRC,如图2由于DST图层和SRC图层重叠,大小一致,DST未相交部分没有显示出来,如图3,DST大小为左上角三分之二,SRC为右下角三分之二(即从左三分一才开始绘制)
图1 图2 图3图层混合模式主要有三个方面的使用:1.ComposeShader
2.画笔Paint.setXfermode()
3.PorterDuffColorFilter
第一种ComposeShader在之前的Shader渲染器中mode中使用
第三种颜色过滤器设置图层混合模式,这个后续再演示怎么使用
接下来主要演示第二种模式,画笔工具使用图层混合模式。
图层混合模式有很多种模式,有些是不支持硬件加速,而android系统默认是开启硬件加速,所以在使用之前需将系统的硬件加速关闭,即:View.setLayerType(LAYER_TYPE_SOFTWARE, mPaint);
绘制图层时,需要将画布进行离屏操作,绘制完成后再恢复画布,否则若View的背景不是透明的,会将View的背景图层也进行了混合绘制。
离屏操作使用的方法为:int saveId = canvas.saveLayer(0, 0, getWidth(), getHeight(), mPaint, Canvas.ALL_SAVE_FLAG);返回saveId可用于恢复画布时使用:canvas.restoreToCount(saveId);
图4附上示例代码:
public class XferModeViewextends View {
private PaintmPaint;
private int mWidth;
private int mHeight;
public XferModeView(Context context) {
super(context);
initView();
}
public XferModeView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView();
}
public XferModeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
mPaint =new Paint();
mPaint.setColor(Color.RED);
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
this.mWidth = MeasureSpec.getSize(widthMeasureSpec);
this.mHeight = MeasureSpec.getSize(heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//关闭硬件加速
setLayerType(LAYER_TYPE_SOFTWARE, mPaint);
setBackgroundColor(Color.GRAY);
//离屏绘制,若不设置离屏绘制会将上面背景颜色一起加入绘制
int saveId = canvas.saveLayer(0, 0, getWidth(), getHeight(), mPaint, Canvas.ALL_SAVE_FLAG);
canvas.drawBitmap(createRectBitmap(mWidth,mHeight),0,0,mPaint);
//设置混合模式
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawBitmap(createCircleBitmap(mWidth,mHeight),0,0,mPaint);
//清除混合模式
mPaint.setXfermode(null);
//还原离屏绘制
canvas.restoreToCount(saveId);
}
//画矩形Dst
public BitmapcreateRectBitmap(int width, int height) {
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas =new Canvas(bitmap);
Paint dstPaint =new Paint(Paint.ANTI_ALIAS_FLAG);
dstPaint.setColor(0xFF66AAFF);
canvas.drawRect(new Rect(width /20, height /3, 2 * width /3, 19 * height /20), dstPaint);
return bitmap;
}
//画圆src
public BitmapcreateCircleBitmap(int width, int height) {
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas =new Canvas(bitmap);
Paint scrPaint =new Paint(Paint.ANTI_ALIAS_FLAG);
scrPaint.setColor(0xFFFFCC44);
canvas.drawCircle(width *2 /3, height /3, height /4, scrPaint);
return bitmap;
}
}