自动覆盖渐变蒙层遮罩的Fresco.SimpleDraweeView

2024-01-09 07:10

本文主要是介绍自动覆盖渐变蒙层遮罩的Fresco.SimpleDraweeView,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

项目里面需要展示一个Banner图片List。图片高度大约100dp高,全屏长,Banner上,垂直居中处需要显示标题文字,文字颜色纯白。如图所示:

无蒙层List
本来按正常来说,这图应该由美工提供,并且如果颜色不合适,由美工大大做类似《吃新鲜蔬菜》这张图的渐变蒙层叠加。

但考虑到之后工作量越来越大,美工大大可能会完全忙不过来,直接不处理就由运营上图,因此可能导致白字放在了浅色图片中,以至于看不见字的情况。

为了防止这种情况的发生,因此写了个自定义View来解决这个问题。

首先这个列表的图片展示是基于Facebook开源的Fresco库,SimpleDraweeView来进行的。
接着查到Google的Android Support系列包中提供了方法,可以高效的从Bitmap中获取特定风格的颜色色值,该方法为:

/** 获取bitmap中的活跃颜色,如果没获取到则为默认颜色#666666 */
Palette.from(bitmap).generate().getVibrantColor(Color.parseColor("#666666"))

这里我们将使用获取到的颜色作为遮罩渐变的起始颜色,为了防止获取到的颜色过浅,进行了如下处理:

int red = color >> 16 & 0xFF;
int green = color >> 8 & 0xFF;
int blue = color & 0xFF;if (red >= 0xA0 && green >= 0xA0 && blue >= 0xA0) {color = Color.rgb(Math.round(red * 0.8F), Math.round(green * 0.8F), Math.round(blue * 0.8F));
}

这里先获取该颜色的R、G、B值,如果都大于0xA0则认为太浅会影响文字显示,则将R、G、B每个值都乘以0.8降低亮度。

以上为这个码子产生的历史背景以及原因,接下来直接上码子。

注意,该码子基于AndroidX,如果您用的不是AndroidX,请自行适配。

首先module中的build.gradle加载Fresco与Palette的包:

implementation 'androidx.palette:palette-ktx:1.0.0'
implementation 'com.facebook.fresco:fresco:2.0.0'

然后是GradientSimpleDraweeView.java

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.net.Uri;
import android.util.AttributeSet;import androidx.palette.graphics.Palette;import com.facebook.drawee.controller.AbstractDraweeControllerBuilder;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.imagepipeline.common.ImageDecodeOptions;
import com.facebook.imagepipeline.common.RotationOptions;
import com.facebook.imagepipeline.request.BasePostprocessor;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequest.RequestLevel;
import com.facebook.imagepipeline.request.ImageRequestBuilder;public class GradientSimpleDraweeView extends SimpleDraweeView {public GradientSimpleDraweeView(Context context, GenericDraweeHierarchy hierarchy) {super(context, hierarchy);}public GradientSimpleDraweeView(Context context) {super(context);}public GradientSimpleDraweeView(Context context, AttributeSet attrs) {super(context, attrs);}public GradientSimpleDraweeView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}public GradientSimpleDraweeView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);}@Overridepublic void setImageURI(Uri uri, Object callerContext) {AbstractDraweeControllerBuilder adcb = getControllerBuilder();adcb = adcb.setOldController(getController()).setCallerContext(callerContext);ImageRequestBuilder imageRequestBuilder = null;ImageDecodeOptions imageDecodeOptions = null;imageDecodeOptions = ImageDecodeOptions.newBuilder().build();/** 构建自定义ImageRequest,以便于对即将渲染的Bitmap进行修改 */imageRequestBuilder = ImageRequestBuilder.newBuilderWithSource(uri).setImageDecodeOptions(imageDecodeOptions).setRotationOptions(RotationOptions.autoRotate()).setLocalThumbnailPreviewsEnabled(true).setLowestPermittedRequestLevel(RequestLevel.FULL_FETCH).setProgressiveRenderingEnabled(true);/** 设置Bitmap处理器 */imageRequestBuilder.setPostprocessor(new BasePostprocessor() {@Overridepublic void process(Bitmap bitmap) {super.process(bitmap);// 获取bitmap中活跃颜色值int color = Palette.from(bitmap).generate().getVibrantColor(Color.parseColor("#666666"));// 防止颜色值过浅,对其进行条件变暗处理int red = color >> 16 & 0xFF;int green = color >> 8 & 0xFF;int blue = color & 0xFF;if (red >= 0xA0 && green >= 0xA0 && blue >= 0xA0) {color = Color.rgb(Math.round(red * 0.8F), Math.round(green * 0.8F), Math.round(blue * 0.8F));}// 创建线性渐变蒙层,这就是我们需要叠加上去的遮罩蒙层拉// 其参数为以图片y的中点为起点,图片宽度的75%处为终点,起点颜色为// 上面运算后的颜色,终点为透明色进行渐变,渐变模式为CLAMPLinearGradient linearGradient = new LinearGradient(0, bitmap.getHeight() / 2, (int) (bitmap.getWidth() * 0.75f), bitmap.getHeight() / 2, color, Color.TRANSPARENT, Shader.TileMode.CLAMP);Paint paint = new Paint();paint.setShader(linearGradient);// 将bitmap捆到画板上,并在画板上绘制蒙层遮罩,高度为图片高度,长度为终点(即图片宽度的75%)Canvas canvas = new Canvas(bitmap);canvas.drawRect(0, 0, (int) (bitmap.getWidth() * 0.75f), bitmap.getHeight(), paint);}});ImageRequest imageRequest = imageRequestBuilder.build();//noinspection uncheckedadcb.setImageRequest(imageRequest);DraweeController controller = adcb.build();setController(controller);}
}

用法:

    <com.xxx.GradientSimpleDraweeViewandroid:id="@+id/sdv"android:layout_width="match_parent"android:layout_height="0dp"android:layout_marginLeft="15dp"android:layout_marginTop="6dp"android:layout_marginRight="15dp"android:layout_marginBottom="5dp"android:foregroundGravity="left"android:scaleType="centerInside"app:actualImageScaleType="centerCrop"app:backgroundImage="@color/white"app:failureImage="@drawable/pic_request_error"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintDimensionRatio="h,988:389"app:layout_constraintTop_toTopOf="parent"app:placeholderImage="@drawable/shape_bg_f2f5f7"app:placeholderImageScaleType="fitCenter"app:roundWithOverlayColor="#F2F5F7"app:roundedCornerRadius="2dp"tools:actualImageResource="@mipmap/demo_pic">

最终效果图

如图的第一张与第三张即为叠加了遮罩的比较明显的效果。其实第二张也叠加了遮罩,只是遮罩蒙层的颜色与美工的遮罩蒙层颜色基本一致,不太看得出来。
当然,毕竟是通过算法获取的活跃颜色,因此不一定满足美术规则,但至少不至于让标题看不见。这个可以通过增加接口字段,来决定是否需要本地遮罩来缓解这个问题。

这篇关于自动覆盖渐变蒙层遮罩的Fresco.SimpleDraweeView的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/586306

相关文章

Python脚本实现自动删除C盘临时文件夹

《Python脚本实现自动删除C盘临时文件夹》在日常使用电脑的过程中,临时文件夹往往会积累大量的无用数据,占用宝贵的磁盘空间,下面我们就来看看Python如何通过脚本实现自动删除C盘临时文件夹吧... 目录一、准备工作二、python脚本编写三、脚本解析四、运行脚本五、案例演示六、注意事项七、总结在日常使用

SpringBoot项目启动后自动加载系统配置的多种实现方式

《SpringBoot项目启动后自动加载系统配置的多种实现方式》:本文主要介绍SpringBoot项目启动后自动加载系统配置的多种实现方式,并通过代码示例讲解的非常详细,对大家的学习或工作有一定的... 目录1. 使用 CommandLineRunner实现方式:2. 使用 ApplicationRunne

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后

python实现自动登录12306自动抢票功能

《python实现自动登录12306自动抢票功能》随着互联网技术的发展,越来越多的人选择通过网络平台购票,特别是在中国,12306作为官方火车票预订平台,承担了巨大的访问量,对于热门线路或者节假日出行... 目录一、遇到的问题?二、改进三、进阶–展望总结一、遇到的问题?1.url-正确的表头:就是首先ur

Spring使用@Retryable实现自动重试机制

《Spring使用@Retryable实现自动重试机制》在微服务架构中,服务之间的调用可能会因为一些暂时性的错误而失败,例如网络波动、数据库连接超时或第三方服务不可用等,在本文中,我们将介绍如何在Sp... 目录引言1. 什么是 @Retryable?2. 如何在 Spring 中使用 @Retryable

Python绘制土地利用和土地覆盖类型图示例详解

《Python绘制土地利用和土地覆盖类型图示例详解》本文介绍了如何使用Python绘制土地利用和土地覆盖类型图,并提供了详细的代码示例,通过安装所需的库,准备地理数据,使用geopandas和matp... 目录一、所需库的安装二、数据准备三、绘制土地利用和土地覆盖类型图四、代码解释五、其他可视化形式1.

使用 Python 和 LabelMe 实现图片验证码的自动标注功能

《使用Python和LabelMe实现图片验证码的自动标注功能》文章介绍了如何使用Python和LabelMe自动标注图片验证码,主要步骤包括图像预处理、OCR识别和生成标注文件,通过结合Pa... 目录使用 python 和 LabelMe 实现图片验证码的自动标注环境准备必备工具安装依赖实现自动标注核心

QT实现TCP客户端自动连接

《QT实现TCP客户端自动连接》这篇文章主要为大家详细介绍了QT中一个TCP客户端自动连接的测试模型,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录版本 1:没有取消按钮 测试效果测试代码版本 2:有取消按钮测试效果测试代码版本 1:没有取消按钮 测试效果缺陷:无法手动停

最大流=最小割=最小点权覆盖集=sum-最大点权独立集

二分图最小点覆盖和最大独立集都可以转化为最大匹配求解。 在这个基础上,把每个点赋予一个非负的权值,这两个问题就转化为:二分图最小点权覆盖和二分图最大点权独立集。   二分图最小点权覆盖     从x或者y集合中选取一些点,使这些点覆盖所有的边,并且选出来的点的权值尽可能小。 建模:     原二分图中的边(u,v)替换为容量为INF的有向边(u,v),设立源点s和汇点t