关于图像混合模式,这里记住一个模板:
~~~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自定义控件开发入门与实战》
- 介绍
- UI
- MaterialButton
- MaterialButtonToggleGroup
- 字体相关设置
- Material Design
- Toolbar
- 下拉刷新
- 可折叠式标题栏
- 悬浮按钮
- 滑动菜单DrawerLayout
- NavigationView
- 可交互提示
- CoordinatorLayout
- 卡片式布局
- 搜索框SearchView
- 自定义View
- 简单封装单选
- RecyclerView
- xml设置点击样式
- adb
- 连接真机
- 小技巧
- 通过字符串ID获取资源
- 自定义View组件
- 使用系统控件重新组合
- 旋转菜单
- 轮播图
- 下拉输入框
- 自定义VIew
- 图片组合的开关按钮
- 自定义ViewPager
- 联系人快速索引案例
- 使用ListView定义侧滑菜单
- 下拉粘黏效果
- 滑动冲突
- 滑动冲突之非同向冲突
- onMeasure
- 绘制字体
- 设置画笔Paint
- 贝赛尔曲线
- Invalidate和PostInvalidate
- super.onTouchEvent(event)?
- setShadowLayer与阴影效果
- Shader
- ImageView的scaleType属性
- 渐变
- LinearGradient
- 图像混合模式
- PorterDuffXfermode
- 橡皮擦效果
- Matrix
- 离屏绘制
- Canvas和图层
- Canvas简介
- Canvas中常用操作总结
- Shape
- 圆角属性
- Android常见动画
- Android动画简介
- View动画
- 自定义View动画
- View动画的特殊使用场景
- LayoutAnimation
- Activity的切换转场效果
- 属性动画
- 帧动画
- 属性动画监听
- 插值器和估值器
- 工具
- dp和px的转换
- 获取屏幕宽高
- JNI
- javah命令
- C和Java相互调用
- WebView
- Android Studio快捷键
- Bitmap和Drawable图像
- Bitmap简要介绍
- 图片缩放和裁剪效果
- 创建指定颜色的Bitmap图像
- Gradle本地仓库
- Gradle小技巧
- RxJava+Okhttp+Retrofit构建网络模块
- 服务器相关配置
- node环境配置
- 3D特效