• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Android学习记录045_PorterDuff

武飞扬头像
Duckdan
帮助1

一、PorterDuff.Mode

1.1 PorterDuff.Mode.DST

/**
* The source pixels are discarded, leaving the destination intact.
*/ 
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  DST:[Da, Dc]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
     	//混合过后,混合区域中有颜色的结果值是0xffff0000
    }
学新通
学新通

1.2 PorterDuff.Mode.DST_IN

/**
*Keeps the destination pixels that cover source pixels, discards the remaining source and destination pixels.
*/ 
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  DST_IN:[Sa * Da, Sa * Dc]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
        //混合过后,混合区域中有颜色的结果值是0x7fff0000
    }
学新通
学新通

1.3 PorterDuff.Mode.DST_OUT

/**
*
个人认为这个说法有问题,因为跟得到的结果不一致
Keeps the destination pixels that are not covered by source pixels. Discards destination pixels that are covered by source pixels. Discards all source pixels.
*/
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  DST_OUT:[Da * (1 - Sa), Dc * (1 - Sa)]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
        //混合过后,混合区域中有颜色的结果值是0x80ff0000
    }
学新通
学新通

1.4 PorterDuff.Mode.DST_ATOP

/**
* 
个人认为说法有问题,因为跟结果不一致。
Discards the destination pixels that are not covered by source pixels. Draws remaining destination pixels over source pixels.
*/  
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  DST_ATOP:[Sa, Sa * Dc   Sc * (1 - Da)]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
      //混合过后,混合区域中有颜色的结果值是0x7fff0000
    }
学新通
学新通

1.5 PorterDuff.Mode.SRC

/**
* The source pixels replace the destination pixels
*/ 
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  SRC:[Sa, Sc]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
        //混合过后,混合区域中有颜色的结果值是0x7f00ff00
    }
学新通
学新通

1.6 PorterDuff.Mode.SRC_IN

/**
* Keeps the source pixels that cover the destination pixels, discards the remaining source and destination pixels.
*/ 
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  SRC_IN:[Sa * Da, Sc * Da]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
     	//混合过后,混合区域中有颜色的结果值是0x7f00ff00
    }
学新通
学新通

1.7 PorterDuff.Mode.SRC_OUT

/**
* Keeps the source pixels that do not cover destination pixels. Discards source pixels that cover destination pixels. Discards all destination pixels.
*/  
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  SRC_OUT:[Sa * (1 - Da), Sc * (1 - Da)]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
      //混合过后,混合区域中有颜色的结果值是0x00000000
    }
学新通
学新通

1.8 PorterDuff.Mode.SRC_ATOP

/**
* Discards the source pixels that do not cover destination pixels. Draws remaining source pixels over destination pixels.
*/
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  SRC_ATOP:[Da, Sc * Da   (1 - Sa) * Dc]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
    	//混合过后,混合区域中有颜色的结果值是0xff807f00
    }
学新通
学新通

1.9 PorterDuff.Mode.SRC_OVER

/**
* The source pixels are drawn over the destination pixels.
*/
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  SRC_OVER:[Sa   (1 - Sa)*Da, Rc = Sc   (1 - Sa)*Dc]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
    	 //混合过后,混合区域中有颜色的结果值是0xff807f00
    }
学新通
学新通

1.10 PorterDuff.Mode.XOR

/**
* 
个人认为说法有问题,因为跟结果不一致。
Discards the source and destination pixels where source pixels cover destination pixels. Draws remaining source pixels.
*/ 
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  XOR:[Sa   Da - 2 * Sa * Da, Sc * (1 - Da)   (1 - Sa) * Dc]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
      //混合过后,混合区域中有颜色的结果值是0x80ff0000
    }
学新通
学新通

1.11 PorterDuff.Mode.DARKEN

/**
*Retains the smallest component of the source and destination pixels.
*/
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  DARKEN:[Sa   Da - Sa*Da, Sc*(1 - Da)   Dc*(1 - Sa)   min(Sc, Dc)]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
       //混合过后,混合区域中有颜色的结果值是0xff800000
    }
学新通
学新通

1.12 PorterDuff.Mode.LIGHTEN

/**
*Retains the largest component of the source and destination pixel.
*/ 
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  LIGHTEN:[Sa   Da - Sa*Da, Sc*(1 - Da)   Dc*(1 - Sa)   max(Sc, Dc)]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
     	//混合过后,混合区域中有颜色的结果值是0xffff7f00
    }
学新通
学新通

1.13 PorterDuff.Mode.MULTIPLY

/**
* Multiplies the source and destination pixels.
*/
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  MULTIPLY:[Sa * Da, Sc * Dc]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
    	//混合过后,混合区域中有颜色的结果值是0x7f000000
    }
学新通
学新通

1.14 PorterDuff.Mode.SCREEN

/**
* Adds the source and destination pixels, then subtracts the source pixels multiplied by the destination.
*/
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  SCREEN:[Sa   Da - Sa * Da, Sc   Dc - Sc * Dc]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
    	//混合过后,混合区域中有颜色的结果值是0xffff7f00
    }
学新通
学新通

1.15 PorterDuff.Mode.ADD

/**
*Adds the source pixels to the destination pixels and saturates the result.
*/ 
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  ADD:[max(0,min(Sa Da,1)),max(0,min(Sc Dc,1)]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
     	//混合过后,混合区域中有颜色的结果值是0xffff7f00
    }
学新通
学新通

1.16 PorterDuff.Mode.OVERLAY

/**
* Multiplies or screens the source and destination depending on the destination color.
*/ 
private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  OVERLAY:
         *  [
         *  Sa Da-Sa*Da,
         *  当2*Dc<Da时,2*Sc*Dc
         *  否则,Sa*Da-2(Da-Sc)(Sa-Dc)
         *  ]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.OVERLAY));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
     	//混合过后,混合区域中有颜色的结果值是0xffff0000
    }
学新通
学新通

二、源代码

package com.example.imagedemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;


import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import androidx.annotation.RequiresApi;

public class ViewDemo12 extends View {

    private int width = 350;
    private int height = 350;
    private Bitmap dstBmp;
    private Bitmap srcBmp;
    private Paint mPaint;

    public ViewDemo12(Context context, AttributeSet attrs) {
        super(context, attrs);
        dstBmp = makeDst(width, height);
        srcBmp = makeSrc(width, height);
        mPaint = new Paint();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    Paint paint = new Paint();

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
//        origin(canvas);
        test01(canvas);
        //test02(canvas);
    }

    private void origin(Canvas canvas) {
        //判断是否经过硬件加速
        //Log.e("View","===" canvas.isHardwareAccelerated());
        //默认画布的颜色
        canvas.drawColor(Color.WHITE);
//        paint.setColor(Color.RED);
//        canvas.drawRect(0,0,400,100,paint);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.DKGRAY);
        //目标
        // canvas.drawBitmap(dstBmp, 0, 0, mPaint);
        /**
         *
         * DST:[Da, Dc]
         * SRC:[Sa, Sc]
         * DST_OUT:[Da * (1 - Sa), Dc * (1 - Sa)]
         * SRC_OVER:[Sa   (1 - Sa)*Da, Sc   (1 - Sa)*Dc]
         *
         *
         */
        Log.e("View==Blend", "1 PorterDuff.Mode.SRC");
        /**
         * 什么时候调用setXfermode方法很重要
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST));
//        //源
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
//        //默认是SRC_OVER
//        Log.e("View==Blend","2 PorterDuff.Mode.DST_IN");
//        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        canvas.restore();
    }

    @RequiresApi(api = Build.VERSION_CODES.Q)
    private void test01(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.parseColor("#FFff0000"));
        /**
         *  什么时候调用setXfermode方法很重要
         *  DST:[Da, Dc]
         *  SRC:[Sa, Sc]
         *  SRC_OVER:[Sa   (1 - Sa)*Da, Rc = Sc   (1 - Sa)*Dc]
         *  DST_OVER:[Sa   (1 - Sa)*Da, Rc = Dc   (1 - Da)*Sc]
         *  SRC_IN:[Sa * Da, Sc * Da]
         *  DST_IN:[Sa * Da, Sa * Dc]
         *  SRC_OUT:[Sa * (1 - Da), Sc * (1 - Da)]
         *  DST_OUT:[Da * (1 - Sa), Dc * (1 - Sa)]
         *  SRC_ATOP:[Da, Sc * Da   (1 - Sa) * Dc]
         *  DST_ATOP:[Sa, Sa * Dc   Sc * (1 - Da)]
         *  XOR:[Sa   Da - 2 * Sa * Da, Sc * (1 - Da)   (1 - Sa) * Dc]
         *  DARKEN:[Sa   Da - Sa*Da, Sc*(1 - Da)   Dc*(1 - Sa)   min(Sc, Dc)]
         *  LIGHTEN:[Sa   Da - Sa*Da, Sc*(1 - Da)   Dc*(1 - Sa)   max(Sc, Dc)]
         *  MULTIPLY:[Sa * Da, Sc * Dc]
         *  SCREEN:[Sa   Da - Sa * Da, Sc   Dc - Sc * Dc],
         *  ADD:[max(0,min(Sa Da,1)),max(0,min(Sc Dc,1)]
         *  OVERLAY:
         *  [
         *  Sa Da-Sa*Da,
         *  当2*Dc<Da时,2*Sc*Dc
         *  否则,Sa*Da-2(Da-Sc)(Sa-Dc)
         *  ]
         *  此时DST是画布新建的layer层
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        //0x7F00FF00
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);
        canvas.restore();
    }



    private void test02(Canvas canvas) {
        canvas.drawColor(Color.WHITE);
        RectF rectF = new RectF(0, 0, 350, 350);
        canvas.saveLayer(rectF, mPaint);
        canvas.drawColor(Color.DKGRAY);

        //目标
        canvas.drawBitmap(dstBmp, 0, 0, mPaint);
        /**
         *
         * DST:[Da, Dc]
         */
        /**
         * 什么时候调用setXfermode方法很重要
         */
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        canvas.drawBitmap(srcBmp, 0, 0, mPaint);

        mPaint.setXfermode(null);
        canvas.restore();
    }

    static Bitmap makeDst(int w, int h) {
        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bm);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);

        p.setColor(0xFFFF0000);
        c.drawOval(new RectF(20, 20, 100, 100), p);
        return bm;
    }

    static Bitmap makeSrc(int w, int h) {
        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bm);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);

        p.setColor(0x7F00FF00);
        c.drawRect(0, 0, 250, 250, p);
        return bm;
    }

}


学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbkihh
系列文章
更多 icon
同类精品
更多 icon
继续加载