ConstraintLayout 中的ImageFilterView探索:处理图片圆角、亮度、饱和度、图片重叠等

ImageFilterView 是 ConstraintLayout 提供的一个功能丰富的 ImageView 扩展类,用于轻松实现对图片的滤镜效果,包括亮度、饱和度和色调调整等。其主要用于动态地调整图片的视觉效果,例如在UI中加入动态色调过渡效果、图片平移、缩放、旋转等。

ImageFilterView 作为自定义View,在XML中定义了常用属性如下:

kotlin 复制代码
<declare-styleable name="ImageFilterView">
        <attr format="reference" name="blendSrc"/>
        <attr format="reference" name="altSrc"/>
        <attr format="float" name="saturation"/>
        <attr format="float" name="brightness"/>
        <attr format="float" name="warmth"/>
        <attr format="float" name="contrast"/>
        <attr format="float" name="crossfade"/>
        <attr format="dimension" name="round"/>
        <attr format="boolean" name="overlay"/>
        <attr format="float" name="roundPercent"/>
        <attr format="float" name="imagePanX"/>
        <attr format="float" name="imagePanY"/>
        <attr format="float" name="imageZoom"/>
        <attr format="float" name="imageRotate"/>
    </declare-styleable>

常用属性的含义:

  • Saturation (饱和度):调整图像颜色的饱和度,1.0 表示不改变,0.1 将图像近乎去色,而 2.0 表示更高的饱和度。可以通过设置不同饱和度实现黑白效果或增强色彩鲜艳度。
  • Brightness (亮度):设置图像的亮度,1.0 为原亮度,2.0 增加亮度,0.5 则会暗化。适用于图片需要调整亮度的场景,比如在较暗环境下提升可见度。
  • Contrast (对比度):调节图像的对比度,1.0 为默认,值越大对比越强。适合需要增强对比的场景,让图像细节更清晰。
  • Warmth (色温):控制图像的冷暖色调,1.0 表示原色温,低于 1.0 使图像偏冷色,高于 1.0 偏暖色。适合营造冷暖色调效果,如模拟日出或夕阳光照。
  • Round (圆角):设置图像的圆角半径,以像素为单位,使边角更平滑。适用于给图像加圆角处理,常用于头像展示等场景。
  • Round Percent (百分比圆角):设置圆角程度的百分比,1.0f 表示完全圆形。用于制作圆形头像显示效果,适合于需要完美圆形的场景。
  • AltSrc (备用图像) :设置备用图像,并通过 crossfade 控制 src 和 altSrc 混合程度,比如crossfade = 0.5f 表示主图与备用图各占 50%。适合做图像淡入淡出效果,或者不同滤镜组合的效果。代码示例:
kotlin 复制代码
ivFilter.setAltImageResource(R.drawable.xxx)
ivFilter.crossfade = 0.5f
  • Overlay (叠加图像):在图像上叠加一个图层,用于应用更多视觉效果。适合需要叠加水印、阴影等效果的场景。
  • ImageRotate (旋转):旋转图像,单位为度,比如90f 表示顺时针旋转 90 度。用于图片旋转需求,例如左右旋转或倒置图像。
  • ImageZoom (缩放) :缩放图像,1.0 表示正常大小,0.5 为宽高缩小一半。适合缩放需求的场景,比如局部放大效果。

上述这些属性让 ImageFilterView 能实现复杂的图像处理效果,非常适合制作自定义图片展示和特效。使用示例:

kotlin 复制代码
    companion object {
        const val TYPE_SATURATION = 1 // 色彩饱和度
        const val TYPE_BRIGHT_NESS = 6 // 对比度
        const val TYPE_CONTRACT = 7 // 亮度
        const val TYPE_WARMTH = 2 // 色温
        const val TYPE_ROUND = 3 //  设置圆角
        const val TYPE_ROUND_PERCENT = 4 //圆角大小百分比
        const val TYPE_ALT_SCR = 5 //覆盖在src上面的交叉图片
        const val TYPE_IMG_ROTATE = 9 //图片旋转
        const val TYPE_IMG_ZOOM = 10 //图片缩放
        const val TYPE_OTHER = 11 //其他
    }
    data class ImageItem(val type: Int, val description: String)

    private val mRvImgFilter: RecyclerView by id(R.id.rv_img_filter)
    mRvImgFilter.layoutManager = GridLayoutManager(context, 3)

    // 示例数据
    val imageList = mutableListOf<ImageItem>().apply {
            add(ImageItem(TYPE_SATURATION, "色彩饱和度saturation=0.1f"))
            add(ImageItem(TYPE_BRIGHT_NESS, "亮度brightness=2f"))
            add(ImageItem(TYPE_CONTRACT, "对比度contrast=0.5f"))
            add(ImageItem(TYPE_WARMTH, "色温warmth=0.5f"))
            add(ImageItem(TYPE_ROUND, "圆角round=10dp"))
            add(ImageItem(TYPE_ROUND_PERCENT, "圆角百分比\nroundPercent=1.0f"))
            add(ImageItem(TYPE_ALT_SCR, "覆盖在src上面的交叉图片altSrc"))
            add(ImageItem(TYPE_IMG_ROTATE, "图片旋转\nimageRotate=90f"))
            add(ImageItem(TYPE_IMG_ZOOM, "图片缩放imageZoom=0.5f"))
        }
    mRvImgFilter.adapter = ImageAdapter(imageList)

    class ImageAdapter(private val imageList: List<ImageItem>) :
        RecyclerView.Adapter<ImageAdapter.ImageViewHolder>() {

        inner class ImageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
            val imgFilterView: ImageFilterView = itemView.findViewById(R.id.imageView)
            val textView: TextView = itemView.findViewById(R.id.textView)
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageViewHolder {
            val view = LayoutInflater.from(parent.context)
                .inflate(R.layout.item_image_filter_view, parent, false)
            return ImageViewHolder(view)
        }

        override fun onBindViewHolder(holder: ImageViewHolder, position: Int) {
            val item = imageList[position]
            val ivFilter = holder.imgFilterView
            when (item.type) {
                TYPE_SATURATION -> ivFilter.saturation = 0.1f
                TYPE_BRIGHT_NESS -> ivFilter.brightness = 2f
                TYPE_CONTRACT -> ivFilter.contrast = 0.5f
                TYPE_WARMTH -> ivFilter.warmth = 0.5f
                TYPE_ROUND -> ivFilter.round = 10.dp2px().toFloat()
                TYPE_ROUND_PERCENT -> ivFilter.roundPercent = 1.0f
                TYPE_ALT_SCR -> {
                    ivFilter.setAltImageResource(R.drawable.icon_cat_h)
                    //上方图片的透明度
                    ivFilter.crossfade = 0.5f
                }
                TYPE_IMG_ROTATE -> { ivFilter.imageRotate = 90f }
                TYPE_IMG_ZOOM -> { ivFilter.imageZoom = 0.5f }
            }
            holder.textView.text = item.description
        }

        override fun getItemCount(): Int = imageList.size
    }

执行结果:

相关推荐
TheNextByte137 分钟前
Android USB文件传输无法使用?5种解决方法
android
quanyechacsdn2 小时前
Android Studio创建库文件用jitpack构建后使用implementation方式引用
android·ide·kotlin·android studio·implementation·android 库文件·使用jitpack
程序员陆业聪3 小时前
聊聊2026年Android开发会是什么样
android
编程大师哥3 小时前
Android分层
android
极客小云4 小时前
【深入理解 Android 中的 build.gradle 文件】
android·安卓·安全架构·安全性测试
Juskey iii5 小时前
Android Studio Electric Eel | 2022.1.1 Patch 2 版本下载
android·ide·android studio
Android技术之家5 小时前
2025年度Android行业总结:AI驱动生态重构,跨端融合开启新篇
android·人工智能·重构
洞见前行5 小时前
Android第二代加固技术原理详解(附源码)
android
风清云淡_A5 小时前
【JetCompose】入门教程实战基础案例01之显隐动画
android
2501_916007475 小时前
iPhone APP 性能测试怎么做,除了Instruments还有什么工具?
android·ios·小程序·https·uni-app·iphone·webview