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
    }

执行结果:

相关推荐
子非衣1 小时前
MySQL修改JSON格式数据示例
android·mysql·json
openinstall全渠道统计5 小时前
免填邀请码工具:赋能六大核心场景,重构App增长新模型
android·ios·harmonyos
双鱼大猫5 小时前
一句话说透Android里面的ServiceManager的注册服务
android
双鱼大猫5 小时前
一句话说透Android里面的查找服务
android
双鱼大猫5 小时前
一句话说透Android里面的SystemServer进程的作用
android
双鱼大猫5 小时前
一句话说透Android里面的View的绘制流程和实现原理
android
双鱼大猫6 小时前
一句话说透Android里面的Window的内部机制
android
双鱼大猫6 小时前
一句话说透Android里面的为什么要设计Window?
android
双鱼大猫6 小时前
一句话说透Android里面的主线程创建时机,frameworks层面分析
android
苏金标7 小时前
android 快速定位当前页面
android