Xfermode 图像混合模式

2020-02-21  本文已影响0人  什么龟

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;

    }

}

上一篇下一篇

猜你喜欢

热点阅读