ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
关于图像混合模式,这里记住一个模板: ~~~kotlin override fun onDraw(canvas: Canvas?) { super.onDraw(canvas) canvas?.apply { // this == canvas // 新建图层 val saveLayerId = saveLayer(0f, 0f, width.toFloat(), height.toFloat(), mRectPaint) // 绘制目标图像 canvas.drawBitmap(resBitmap, 100f, 100f, mRectPaint) // 设置图像混合模式 mRectPaint.xfermode = // PorterDuffXfermode(PorterDuff.Mode.MULTIPLY) // 绘制源图像 drawBitmap(bitmap, 100f, 100f, mRectPaint) // 清空图像混合模式 mRectPaint.xfermode = null restoreToCount(saveLayerId) } } ~~~ 对应的效果模板: ![](https://img.kancloud.cn/87/71/8771be27e349916548aafdcb00475aa7_800x1352.png) 上图来自博客:[Android 混合模式之 PorterDuffXfermode](https://blog.csdn.net/leilifengxingmw/article/details/105351758) 目标图像是黄色的圆,源图像是正方形蓝色矩形。 对于其模式,这里简单理解记录一下: ~~~undefined Sa:全称为Source alpha,表示源图的Alpha通道; Sc:全称为Source color,表示源图的颜色; Da:全称为Destination alpha,表示目标图的Alpha通道; Dc:全称为Destination color,表示目标图的颜色. ~~~ > PorterDuff.Mode.CLEAR;\[0, 0\],alpha通道和颜色值均为0,什么都不显示; PorterDuff.Mode.SRC;\[Sa, Sc\],显示源图像; PorterDuff.Mode.DST;\[Da, Dc\],显示目标图像; PorterDuff.Mode.SRC_OVER;\[Sa + (1 - Sa)\*Da, Rc = Sc + (1 - Sa)\*Dc\],正常绘制显示,目标图上绘制源图; PorterDuff.Mode.DST_OVER;\[Sa + (1 - Sa)\*Da, Rc = Dc + (1 - Da)\*Sc\],与SRC_OVER相反,此模式是目标图像被绘制在源图像的上方; PorterDuff.Mode.SRC_IN;\[Sa \* Da, Sc \* Da\],取两层绘制交集,且绘制效果受到目标图像对应地方透明度的影响 PorterDuff.Mode.DST_IN;\[Sa \* Da, Sa \* Dc\],取两层绘制交集。在两者相交的地方绘制目标图像,并且绘制的效果会受到源图像对应地方透明度的影响 PorterDuff.Mode.SRC_OUT;\[Sa \* (1 - Da), Sc \* (1 - Da)\],表示如果相交处的目标色的alpha是完全不透明的,这时候源图像会完全被过滤掉,否则会受到相交处目标色 alpha 影响,呈现出对应色值。 PorterDuff.Mode.DST_OUT;\[Da \* (1 - Sa), Dc \* (1 - Sa)\],可以类比SRC\_OUT , 在不相交的地方绘制目标图像,相交处根据源图像alpha进行过滤,完全不透明处则完全过滤,完全透明则不过滤 PorterDuff.Mode.SRC_ATOP;\[Da, Sc \* Da + (1 - Sa) \* Dc\],源图像和目标图像相交处绘制源图像,不相交的地方绘制目标图像,并且相交处的效果会受到源图像和目标图像alpha的影响 PorterDuff.Mode.DST_ATOP;取上层非交集部分与下层交集部分 PorterDuff.Mode.XOR;异或:去除两图层交集部分 PorterDuff.Mode.DARKEN;取两图层全部区域,交集部分颜色加深 PorterDuff.Mode.LIGHTEN;取两图层全部,点亮交集部分颜色 PorterDuff.Mode.MULTIPLY;正片叠底,取两图层交集部分叠加后颜色 PorterDuff.Mode.SCREEN;滤色,取两图层全部区域,交集部分变为透明色 更详细的可以参考:《Android自定义控件开发入门与实战》