自定义View之基础篇——PorterDuff

本文介绍了Android自定义View中PorterDuff颜色渲染器的使用,通过核心代码示例解释了直接用canvas绘制和使用Bitmap绘图的两种方法,并详细比较了不同PorterDuff模式的效果,包括SRC、DST、SRC_OVER等。文中还提到了硬件加速对某些模式的影响以及相关参考资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

本章主要介绍颜色渲染器PorterDuff。

PorterDuff其实来自两个人名:Tomas Porter和Tom Duff利用PorterDuff.Mode,我们可以实现图片的任意叠加混合,eg.实现画图中的橡皮擦功能、显示圆形图片等等

 

1、核心代码

以圆和矩形为例。dst为下层,是先画的图形(这里我选择的是灰色的圆);src为上层,后画的图形(我选用的是蓝色矩形)。实验时,设置的圆的直径与矩形宽高相等,这样重叠起来方便看效果。

(1)核心代码1(直接用canvas绘制):

int sc = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);//创建一个新的layer
// canvas.drawARGB(255, 139, 197, 186);//画布颜色

//先绘制一个下层图像
canvas.drawCircle(100,100,100,dstPaint);

//绘制上层图像
PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
srcPaint.setXfermode(mode);
// canvas.drawRect(new Rect(0,0,200,200),srcPaint);//圆和矩形位置重叠
canvas.drawRect(new Rect(100,100,300,300),srcPaint);//圆和矩形位置稍有偏移

srcPaint.setXfermode(null); // 还原混合模式
canvas.restoreToCount(sc);  // 将这个layer绘制到canvas默认的layer

注意蓝色代码:

 

 int sc = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);//创建一个新的layer

 srcPaint.setXfermode(null); // 还原混合模式

 canvas.restoreToCount(sc);  // 将这个layer绘制到canvas默认的layer

    这段代码最好加上,否则某些模式下原本不该显示的地方出现白色填充。特别是如果设置了画布颜色,效果会很明显,eg.CLEAR,会显示一个灰色圆和白色矩形(除非新建一个图层,也就是上面这点代码,这样就可以变成原来的效果)。具体原因参见 Android中Canvas绘图之PorterDuffXfermode使用及工作原理详解 or Android PorterDuffXfermode使用中的一些坑

 

(2)核心代码2(使用Bitmap绘制)

 

int sc = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);//创建一个新的layer

Bitmap dstBm= Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
Bitmap srcBm= Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);

Canvas dstCanvas = new Canvas(dstBm);//将画布内容转换为bitmap
Canvas srcCanvas= new Canvas(srcBm);

//先绘制一个下层图像
dstCanvas .drawCircle(100,100,100,dstPaint);
canvas.drawBitmap(dstBm,0,0,dstPaint);

//绘制上层图像
srcCanvas.drawRect(new Rect(100,100,300,300),srcPaint);//圆和矩形位置稍有偏移

PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
srcPaint.setXfermode(mode);
// canvas.drawRect(new Rect(0,0,200,200),srcPaint);//圆和矩形位置重叠
canvas.drawBitmap(srcBm,0,0,srcPaint); 

(3)重点说明

    对于网上疯传的下面两种不同模式图,本人亲测,双方各有道理。只不过,前者是用采用canvas直接绘图导致的;后者是官方推荐的一种写法,也就是上下层均用bitmap实现。本文将就上述两种方法,分别进行测试。

纠正一下,CLEAR效果两个方式得到的都一样。不一样的是:SRC、SRC_IN、DST_IN、SRC_OUT、DST_ATOP、MULTIPLY这六个,本文会在第三点进行比对显示,方便区分。

 

2、使用canvas直接画图

2.1 总结

橙色部分为两种方法的不同地方。

PorterDuff.Mode

 

说明

 

SRC

 

显示上层区域;若此时下层区域存在没有

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值