Glide自定义Transformation实现图片部分圆角

Android 玩转Glide4---Transformation篇 前言 系列文章专栏: 玩转Glide4 基础使用篇:Android 玩转Glide4—基础使用篇 进阶使用篇:Android 玩转Glide4—进阶使用篇 概述 再基础篇和进阶篇中,我们简单介绍了Glide4的用法,和一些进阶的使用。 本篇Transformation转换篇,将给大家介绍Glide4强大的转换功能。 Glide自带的转换效果 <ImageView a... 阅读详情

自定义Glide的Transformation实现部分圆角的文章和代码在网上有很多,原本我也是随便在网上找一份Glide 加载部分圆角图片在项目中直接使用,但在使用过程居然遇到Bug,所以去查看了官方文档,发现自定义的Transformation忘掉了最关键的部分,即重写equals()/hashCode()两个函数,虽然在一般场景下可以正常使用,但在RecyclerView这种会加载大量图片的场景下,自定义的transform且未重写equals()/hashCode()会导致Bug。

(emmm,具体是什么Bug我忘了,大概是滑动卡顿?因为是很久之前遇到的问题,现在补的文章)

先来看看官方文档:
官方文档

官方文章中注明equals()/hashCode()/updateDiskCacheKey()三个方法是必须被重写以使得磁盘和内存缓存正确地工作。不重写equals()/hashCode()磁盘缓存就可能无法正常工作,虽然可以通过编译,但使用时会引起内存泄露等问题。

最后附上修改后的RoundedCornersTransform,目前可以正常使用:

//Koltin版本
class RoundedCornersTransform(
    context: Context?,
    var radius: Float,
    var leftTop: Boolean = true,
    var rightTop: Boolean = true,
    var leftBottom: Boolean = true,
    var rightBottom: Boolean = true
) :
    Transformation<Bitmap?> {
    private val mBitmapPool: BitmapPool = Glide.get(context!!).bitmapPool

    private val id = javaClass.name
    private val idBytes = id.toByteArray(Charsets.UTF_8);

    override fun transform(
        context: Context,
        resource: Resource<Bitmap?>,
        outWidth: Int,
        outHeight: Int
    ): Resource<Bitmap?> {
        val source: Bitmap = resource.get()
        var finalWidth: Int
        var finalHeight: Int
        //输出目标的宽高或高宽比例
        var scale: Float
        if (outWidth > outHeight) {
            //如果 输出宽度 > 输出高度 求高宽比
            scale = outHeight.toFloat() / outWidth.toFloat()
            finalWidth = source.width
            //固定原图宽度,求最终高度
            finalHeight = (source.width.toFloat() * scale).toInt()
            if (finalHeight > source.height) {
                //如果 求出的最终高度 > 原图高度 求宽高比
                scale = outWidth.toFloat() / outHeight.toFloat()
                finalHeight = source.height
                //固定原图高度,求最终宽度
                finalWidth = (source.height.toFloat() * scale).toInt()
            }
        } else if (outWidth < outHeight) {
            //如果 输出宽度 < 输出高度 求宽高比
            scale = outWidth.toFloat() / outHeight.toFloat()
            finalHeight = source.height
            //固定原图高度,求最终宽度
            finalWidth = (source.height.toFloat() * scale).toInt()
            if (finalWidth > source.width) {
                //如果 求出的最终宽度 > 原图宽度 求高宽比
                scale = outHeight.toFloat() / outWidth.toFloat()
                finalWidth = source.width
                finalHeight = (source.width.toFloat() * scale).toInt()
            }
        } else {
            //如果 输出宽度=输出高度
            finalHeight = source.height
            finalWidth = finalHeight
        }

        //修正圆角
        radius *= finalHeight.toFloat() / outHeight.toFloat()
        val outBitmap: Bitmap = mBitmapPool[finalWidth, finalHeight, Bitmap.Config.ARGB_8888]
        val canvas = Canvas(outBitmap)
        val paint = Paint()
        //关联画笔绘制的原图bitmap
        val shader = BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
        //计算中心位置,进行偏移
        val width: Int = (source.width - finalWidth) / 2
        val height: Int = (source.height - finalHeight) / 2
        if (width != 0 || height != 0) {
            val matrix = Matrix()
            matrix.setTranslate((-width).toFloat(), (-height).toFloat())
            shader.setLocalMatrix(matrix)
        }
        paint.shader = shader
        paint.isAntiAlias = true
        val rectF = RectF(0.0f, 0.0f, canvas.width.toFloat(), canvas.height.toFloat())
        //先绘制圆角矩形
        canvas.drawRoundRect(rectF, radius, radius, paint)

        //左上角圆角
        if (!leftTop) {
            canvas.drawRect(0f, 0f, radius, radius, paint)
        }
        //右上角圆角
        if (!rightTop) {
            canvas.drawRect(canvas.width - radius, 0f, canvas.width.toFloat(), radius, paint)
        }
        //左下角圆角
        if (!leftBottom) {
            canvas.drawRect(0f, canvas.height - radius, radius, canvas.height.toFloat(), paint)
        }
        //右下角圆角
        if (!rightBottom) {
            canvas.drawRect(
                canvas.width - radius,
                canvas.height - radius,
                canvas.width.toFloat(),
                canvas.height.toFloat(),
                paint
            )
        }
        return BitmapResource.obtain(outBitmap, mBitmapPool)!!
    }

    /** must override */
    override fun equals(other: Any?): Boolean {
        return other is RoundedCornersTransform
    }

    /** must override */
    override fun hashCode(): Int {
        return id.hashCode()
    }

    /** must override */
    override fun updateDiskCacheKey(messageDigest: MessageDigest) {
        messageDigest.update(idBytes)
    }
}

RoundedCornersTransform使用:

//默认裁剪四个圆角,不需要设置圆角,对应参数设为false
Glide.with(context)
            .load(item.coverUrl)
            .apply(
                RequestOptions().transform(
                    CenterCrop(), RoundedCornersTransform(
                        context, 8f,
                        leftBottom = false,
                        rightBottom = false
                    )
                )
            )
            .into(holder.getView(R.id.img_icon))
Glide 自定义圆角与FitXY适配:解决图片变形与圆角失效的实战方案 本文深入解析了Android图片加载库Glide中常见的图片变形与圆角失效问题,并提供了实战解决方案。通过自定义FitXYTransformation和整合了多种缩放模式与圆角绘制的GlideRoundTransform类,开发者可以精确控制图片的适配与圆角效果,有效避免变换覆盖与缓存问题,提升应用UI表现。 阅读详情

相关推荐

Glide 自定义圆角、铺满FitXY

圆角或者使图片完全填充

白高林的专栏 1518

Android 图片加载库之Coil的详解与使用

Android 图片加载库之Coil的详解与使用

7862

Glide图片加载避坑指南:为什么你的圆角设置总是不生效?

本文深入剖析了在Android开发中使用Glide图片加载库时,圆角效果设置失效的常见原因与解决方案。核心问题常源于变换调用顺序错误、与ImageView的scaleType属性冲突或自定义变换实现不当。文章提供了详细的代码示例和最佳实践,特别是如何正确使用自定义圆角变换,帮助开发者彻底解决这一常见痛点。

yoga7的博客 862

Android Glide 4.9 常见方法总结

DrawableImageViewTarget 代替原来的 SimpleTarget。图片会缩放 ,铺满 imageView , 四周会被裁剪。图片保持原来比例,在 imageView 中居中显示。submit 有两个方法。

赵彦军 1561

Vercel静态站被墙别慌!手把手教你用Cloudflare免费CDN+域名解析搞定DNS污染

本文详细介绍了如何利用Cloudflare免费CDN和域名解析解决Vercel静态网站遭遇DNS污染的问题。通过诊断DNS污染、设计Cloudflare解决方案架构、实战配置步骤以及高级调优技巧,帮助用户快速恢复站点访问并提升防护能力。

weixin_27442001的博客 677

ESP32-BLE学习1-建立简单的server

start 学习之前,我想尝试使用ESP32的demo建立一个简单的server与手机接进行最基本的数据通信。 这里有BLE的简单讲解BLE资料 因为BLE的连接是具有主从机特性的,就像SPI,USB一些请求只能由主机端发起,连接也需要主机端发起。所以手机要想连上ESP32,就得将ESP32设置为从机模式。 从资料上可以看到,从机端通过Notify通知主机,所以从机就是GATT Server。 在进行ESP32 的demo学习之前,得大体看下ESP32的蓝牙组成,ESP32支持经典蓝牙和低功耗蓝牙4.2,

Spark的博客 1842

Android Glide加载四周圆角图

Android Glide加载四周圆角图需要引入:implementation 'jp.wasabeef:glide-transformations:3.3.0'上层Java代码:package zhangphil.test; import android.os.Bundle; import android.support.annotation.Nullable; import android....

Zhang Phil 2695

【SOC估计】基于EKF与二阶RC等效电路模型的锂电池SOC在线估计算法实现与仿真分析

本文详细介绍了基于扩展卡尔曼滤波(EKF)与二阶RC等效电路模型的锂电池SOC在线估计算法。通过Matlab仿真分析,展示了该算法如何实现高精度SOC估计,相比传统方法显著提升估计精度与鲁棒性,适用于电动汽车、储能系统等关键领域。

1098

glide加载圆角和自定义圆角view_Glide自定义Transformation实现四个不同圆角图片

CaseGlide4.8想要实现加载图片导四个不同的圆角。如下图1图片1实现思路在Canvas的四个图层分别绘制四个不同的圆角矩形(RoundRect),然后分别截取(clipRect)左上、右上、右下、左下四个部分,最终在Canvas上组合起来(save->restore)关键步骤详解步骤一:原图bitmap关联画笔:Paint paint =new Paint();// source 为...

weixin_39926394的博客 515

【暂时完结】Prescan学习笔记

Prescan学习记录1. Prescan基础知识1.1 Conventions·坐标1.2 Road segment·道路片段1.2.1 让一个路段连接其他两个路段1.2.2 配置车道线1.2.3 Road marking·道路标志1.3 Trajectory·轨迹1.3.1 建立一个Path·路径1.3.2 配置Speedprofile1.3.3 Synchronization of Trajectories·轨迹同步1.3.4 Multiple trajectories · 多轨迹分配 1. Pres

dreautumn的博客 1万+

第二十届全国大学生智能车竞赛-地瓜机器人智慧医疗挑战赛技术解析与实战指南

本文深入解析了第二十届全国大学生智能车竞赛-地瓜机器人智慧医疗挑战赛的核心技术。内容涵盖从零搭建数字孪生环境、实现AI视觉任务(二维码识别、引导线追踪、目标检测)、在边缘设备部署轻量化大模型进行图生文描述,到遥操作与自主控制的平滑切换,并提供了基于ROS2的系统集成与赛场实战指南,助力参赛者高效备赛。

weixin_29252171的博客 2777

让Glide输出指定位置的圆角图片

使用过Glide的应该都知道,Glide可以通过自定义Transformation来修改最终显示的Bitmap,今天要实现的效果如下图所示: 可以看到,整个效果的四个顶角都是圆角的,这个界面其实就是一个ImageView和一个TextView,布局如下: <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:...

热爱不止,前行不息 9892

【2026年得物春招算法岗- 4月18日 -第二题- 老张爬山】(题目+思路+Java&C++&Python解析+在线测试)

这篇文章介绍了一个动态规划问题,解决老张在n天内安排爬山计划以最大化愉悦值的问题。题目允许最多k次打破"不能连续两天爬山"的规则限制。 摘要要点: 使用三维动态规划数组dp[i][j][s],表示第i天结束时已用j次机会、当天状态为s(0不爬/1爬)时的最大愉悦值 状态转移考虑两种情况:当天不爬山时取前一天两种状态的最大值;当天爬山时分别处理前一天不爬山和爬山(需消耗机会)的情况 最终结果为考虑所有可能用掉的k次机会后,最后一天两种状态的最大值 提供了Python、Java和C++三种实

m0_73659489的博客 1357

Android Glide加载圆形图片、圆角图片,部分圆角图片的使用方法

效果如图左上角和右上角为圆角,左下右下为直角,其实现稍微有些复杂;效果如图,只需要设置requestoption即可,添加bitmapTransform(new RoundedCorners(20);只需要设置requestoption即可,添加circleCropTransform();此处实现的时候用了一个工具类DipPx中dip2px,将dp值转化为像素值;

qq_39033800的博客 3210

QMK键盘固件开发零基础教程(2025全新重制版)

《QMK键盘固件开发零基础教程(2025全新重制版)》是一套专为键盘爱好者和开发者设计的全面教程,旨在帮助用户从零基础快速掌握最新的QMK固件开发技术。教程基于2025年最新的QMK版本(0.19.8+),解决了旧版教程中的诸多问题,如概念不清、步骤缺失和代码过时等。新版教程提供了详细的图解、完整的项目源码以及从环境配置到高级功能开发的全流程指导。此外,教程还涵盖了2024年QMK生态的重大变革,包括键码系统的重构、编译工具链的更新以及Config文件格式的改变等。付费版教程额外提供独家内容,如新特性解析、

Despacito0o的博客 1121

Java全栈:电影数据检索与推荐系统实战

全文检索个性化推荐数据缓存容器化部署通过这个项目,我们不仅实践了Java全栈开发的各项技术,还接触了推荐系统的核心算法实现。用户历史行为数据物品特征数据上下文信息实时反馈算法的准确性推荐的多样性系统的实时性冷启动问题性能优化效果评估VIEW, // 浏览CLICK, // 点击SEARCH, // 搜索RATE, // 评分COMMENT, // 评论SHARE, // 分享WATCH_TIME, // 观看时长。

exlink2012的专栏 891

Android 圆角图片,基于Glide4.9 的 BitmapTransformation,可任意设置某个角

Glide中的 Transformation,多次设置,后面的会覆盖前面的。 如果 ImageView的 scaleType = “centerCrop”,会在 into()方法前自动加上 centerCrop(),即会调用 CenterCrop#transform()。

打渔还是晒网 —— stone 7499

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Android Glide设置四个角圆角或个别的是圆角

import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Pain...

qq_41880248的博客 2357

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Glide加载Gif圆角图多次后出现黑边

使用Glide加载Gif图且要求圆角图时,加载多次发现圆角背后多了黑色方角,说具体点就是首次加载会有圆角,第二次加载就会圆角+方角黑边。就像这样: 到这里,问题也描述的差不多了,有遇到同样问题&心急的朋友可能反手就是一拖鞋 先给解决方案:加上.diskCacheStrategy(DiskCacheStrategy.SOURCE)即可。 下面是顺便记录下圆角实现过程和遇到的疑惑点: Gl...

iblade的博客 3030

玩转Glide 4.x之Transformation变换

写在开头 公司老项目决定从ImageLoader替换为当前流行框架Glide,准备单独开发成图片组件,目前正在学习中,总结一波,希望能和大家共同进步,也希望大家提供更好的封装及思路共同完善这个组件,方便你我的使用。 图片组件地址:https://github.com/loveAndroidAndroid/GlideMoudle(包含图片变换,进度监听,图片(gif)加载等等,还希望大家能一起补...

say_from_wen的博客 6766

从图片加载到高效转换:Glide中的Transformation操作终极指南

在Android应用开发中,**Glide**作为一款功能强大的图片加载库,其**Transformation**功能是提升用户体验的关键所在。通过Transformation,开发者可以对图片进行各种变换处理,从简单的裁剪到复杂的滤镜效果,让应用界面更加精美和专业。本文将为你全面解析Glide中的Transformation操作,帮助你掌握这一强大的图片处理利器。🎯 ## 🔥 什么是Gli

gitblog_00844的博客 663

3行代码实现Android图片高级变换:Glide圆角/模糊/灰度全攻略

你是否还在为Android应用中的图片处理效果发愁?加载网络图片时想添加圆角边框却不知从何下手?需要快速实现图片模糊或灰度效果时找不到简洁方案?本文将通过Glide的图片变换(Transformation)功能,教你用极简代码实现三种实用效果,让普通图片瞬间提升视觉质感。 ## 认识Glide图片变换系统 Glide作为Android平台主流的图片加载库,其核心优势之一就是灵活的图片变换机制。...

gitblog_00964的博客 477

Gilde 设置圆角失败排查方向

Gilde设置圆角功能方案,如果设置不成功,排查方向。

qq_30974087的博客 1379

Kotlin之Glide的自定义BitmapTransformation

Kotlin之Glide的自定义BitmapTransformation

s1991721的博客 2104

android图片圆角,Android图片圆角的实现方案

一、 参考glide的实现方法RequestOptions options = new RequestOptions().bitmapTransform(new RoundedCorners(30));//图片圆角为30Glide.with(this).load(bitmap) //图片地址.apply(options).into(iv_normal);通过RoundedCorners的Trans...

weixin_36364248的博客 499

详细使用Transformations实现圆角或圆形图片

现在基本上每个应用的头像都是圆形,可是真实的图片却不是,需要我们自己处理,原来的处理方式是自定义ImageView或者使用第三方库,比如:CircleImageView ,但这里我们讲的是使用Glide来实现这样的效果,框架默认是没有提供这样的实现,但是这个框架提供了很灵活的框架,我们可以很方便的来自定义图片处理过程,官方的教程在这里,他只是实现了Fit center

Pich的博客 7024
上一篇: Android 常用的第三方框架和组件
下一篇: Android MVVM架构搭建
CheatGZ
博客等级 码龄10年 1粉丝 8原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CheatGZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值