Android学习记录045_PorterDuff
一、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
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13