美文网首页自定义控件
高级UI<第十六篇>:Xfermode 详解

高级UI<第十六篇>:Xfermode 详解

作者: NoBugException | 来源:发表于2019-11-28 22:03 被阅读0次

    文章参考了各个击破搞明白PorterDuff.Mode这篇文章,所以本人只演示效果:

    案例中涉及到图层,了解图层的使用请看高级UI<第十七篇>:Canvas图层的概念(saveLayer)

    代码

    public class PorterDuffXfermodeView extends View {
    
        private Paint mPaint;
        private Xfermode mXfermode;
        private PorterDuff.Mode xfermodemode = PorterDuff.Mode.CLEAR;    //混合模式常量
        private int measureWidth;//父布局宽度
        private int measureHeight;//父布局高度
        private int OFFSET = 100;//偏移量
    
        public PorterDuffXfermodeView(Context context) {
        super(context);
        init();
        }
    
        public PorterDuffXfermodeView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    
        }
    
        public PorterDuffXfermodeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
        }
    
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        public PorterDuffXfermodeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
        }
    
        /**
         * 初始化数据
         */
        private void init(){
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
        //生成混合模式对象
        mXfermode = new PorterDuffXfermode(xfermodemode);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
        measureWidth = MeasureSpec.getSize(widthMeasureSpec);
        measureHeight = MeasureSpec.getSize(heightMeasureSpec);
    
        }
    
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.parseColor("#cc99ff"));
        int saveCount1 = canvas.saveLayer(OFFSET,OFFSET,measureWidth - OFFSET,measureHeight - OFFSET,mPaint, Canvas.ALL_SAVE_FLAG);
        mPaint.setColor(Color.YELLOW);
        canvas.drawCircle(300, 300, 100, mPaint);
        canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.dst),null, new RectF(100, 100, 500, 500), mPaint);
        mPaint.setXfermode(mXfermode);
        canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.src), null, new RectF(100, 100, 500, 500), mPaint);
        mPaint.setXfermode(null);
        canvas.restoreToCount(saveCount1);
    
        }
    }
    

    混合模式的代码已经注释,效果如下


    图片.png
    • 这里新建了一个图层,分别画了三个图形,假设分别为A(黄)、B(绿)、C(红 )
    • 代码中将红色图片设置了混合模式,所以红色图片为源图,黄色图片和绿色图片的并集为目标图
    Sa:全称为Source alpha,表示源图的Alpha通道;
    Sc:全称为Source color,表示源图的颜色;
    Da:全称为Destination alpha,表示目标图的Alpha通道;
    Dc:全称为Destination color,表示目标图的颜色.
    
    (1)混合模式之CLEAR

    将注释打开, 常量设置如下:

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.CLEAR;    //混合模式常量
    

    效果如下


    图片.png

    现象:
    清除源图的所有alpha和颜色值;

    (2)混合模式之SRC

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SRC;    //混合模式常量
    

    效果如下


    图片.png

    现象:
    只绘制源图的alpha和颜色值

    (3)混合模式之DST

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DST;    //混合模式常量
    

    效果如下


    图片.png

    现象:
    只绘制目标图

    (4)混合模式之SRC_OVER

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SRC_OVER;    //混合模式常量
    

    效果如下


    图片.png

    现象:

    在目标图像的顶部绘制源图像。

    (5)混合模式之DST_OVER

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DST_OVER;    //混合模式常量
    

    效果如下


    图片.png

    现象:

    在源图像的顶部绘制目标图像

    (6)混合模式之SRC_IN

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SRC_IN;    //混合模式常量
    

    效果如下


    图片.png

    现象:
    只在源图像和目标图像相交的地方绘制源图像

    (7)混合模式之DST_IN

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DST_IN;    //混合模式常量
    

    效果如下


    图片.png

    现象:
    只在源图像和目标图像相交的地方绘制目标图像

    (8)混合模式之SRC_OUT

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SRC_OUT;    //混合模式常量
    

    效果如下


    图片.png

    现象:
    只在源图像和目标图像不相交的地方绘制源图像

    (9)混合模式之DST_OUT

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DST_OUT;    //混合模式常量
    

    效果如下


    图片.png

    现象:
    只在源图像和目标图像不相交的地方绘制目标图像

    (10)混合模式之SRC_ATOP

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SRC_ATOP;    //混合模式常量
    

    效果如下


    图片.png

    现象:
    在源图像和目标图像相交的地方绘制源图像,在不相交的地方绘制目标图像

    (11)混合模式之DST_ATOP

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DST_ATOP;    //混合模式常量
    

    效果如下


    图片.png

    现象:
    在源图像和目标图像相交的地方绘制目标图像,在不相交的地方绘制源图像

    (12)混合模式之XOR

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.XOR;    //混合模式常量
    

    效果如下


    图片.png

    现象:
    在源图像和目标图像重叠之外的任何地方绘制他们,而在不重叠的地方不绘制任何内容

    (13)混合模式之MULTIPLY

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.MULTIPLY;    //混合模式常量
    

    效果如下


    图片.png

    现象:
    将每个位置的两个像素相乘,除以255,然后使用该值创建一个新的像素进行显示。结果颜色=顶部颜色*底部颜色/255

    (14)混合模式之ADD

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.ADD;    //混合模式常量
    

    效果如下


    图片.png

    现象:饱和度相加

    (15)混合模式之SCREEN

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SCREEN;    //混合模式常量
    

    效果如下


    图片.png

    现象:
    反转每个颜色,执行相同的操作(将他们相乘并除以255),然后再次反转。结果颜色=255-(((255-顶部颜色)*(255-底部颜色))/255)

    (16)混合模式之LIGHTEN

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.LIGHTEN;    //混合模式常量
    

    效果如下

    图片.png

    现象:
    获得每个位置上两幅图像中最亮的像素并显示

    (17)混合模式之DARKEN

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DARKEN;    //混合模式常量
    

    效果如下


    图片.png

    现象:
    获得每个位置上两幅图像中最暗的像素并显示

    (18)混合模式之OVERLAY

    常量设置如下

    private PorterDuff.Mode xfermodemode = PorterDuff.Mode.OVERLAY ;    //混合模式常量
    

    效果如下


    图片.png

    现象:

    叠加。

    [本章完...]

    相关文章

      网友评论

        本文标题:高级UI<第十六篇>:Xfermode 详解

        本文链接:https://www.haomeiwen.com/subject/pcmiwctx.html