Android裁剪图片为波浪形或者曲线形的ImageView
如果需要做一个自定义的波浪效果的进度条,裁剪图片,对ImageView的图片进行裁剪,比如下面2张图,如何实现?
先看下面的效果,看到其实只需要对第一张高亮的图片进行处理即可,灰色状态的作为背景图。
1、实现原理
这里首先想到的是自定义View,在Android中,使用二阶贝塞尔曲线可以实现我们想要的效果,关键的API就是Path的rQuadTo()方法。
path.reset()path.moveTo(startX, startY)path.quadTo(currentX, currentY, endX, endY)canvas.drawPath(path, curvePaint)
startX和startY,endX和endY为两个固定点,currentX和currentY就是控制点,通过改变控制点的位置来改变二阶贝塞尔曲线的形状。
a点和b点就是固定点,c点是控制点,我们可以改变c点的位置来改变曲线的形状。
在Android中,使用cubicTo来实现三阶贝塞尔。上面的需求方案使用二阶即可实现,三阶的可以自行了解。
2、事例分析
首先可以通过自定义一个贝赛尔曲线来了解一下:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;public class BezierCurveView extends View {private Paint paint;private Path path;public BezierCurveView(Context context) {super(context);init();}public BezierCurveView(Context context, AttributeSet attrs) {super(context, attrs);init();}public BezierCurveView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {paint = new Paint();paint.setColor(Color.BLUE);paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(5f);path = new Path();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int height = getHeight();int width = getWidth();float dx = width / 4f;float dy = height / 4f;path.reset();path.moveTo(0, height / 2f); // 起点path.rQuadTo(dx, -dy, 2 * dx, 0f); // 控制点、终点path.rQuadTo(dx, dy, 2 * dx, 0f); // 控制点、终点path.rQuadTo(dx, -dy, 2 * dx, 0f); // 控制点、终点path.rQuadTo(dx, dy, 2 * dx, 0f); // 控制点、终点path.lineTo(width, height);path.lineTo(0f, height);path.close();canvas.drawPath(path, paint);}
}
要使用这个自定义View
,你需要在布局文件中引用一下:
<com.example.myapp.BezierCurveViewandroid:layout_width="match_parent"android:layout_height="200dp" />
看下效果:
3、使用贝塞尔裁剪ImageView
1)自定义ImageView
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Path;
import android.util.AttributeSet;import androidx.annotation.Nullable;/*** 图片裁剪为贝赛尔曲线边缘ImageView*/
public class BezierImageView extends androidx.appcompat.widget.AppCompatImageView {private static final String TAG = "ArcImageView";public BezierImageView (Context context) {this(context, null);}public BezierImageView (Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public BezierImageView (Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);path = new Path();}private final Path path;/*** 进度值(0~100),默认100*/private int progress = 100;public void setProgress(int progress) {this.progress = progress;postInvalidate();}@Overrideprotected void onDraw(Canvas canvas) {final int width = getWidth();final int height = getHeight();float dx = width / 4f;float dy = height / 8f;float yOffset = (100 - progress) / 100f * height;float[] p1 = {0f, yOffset};float[] p2 = {dx, -dy};float[] p3 = {2 * dx, 0f};float[] p4 = {dx, dy};float[] p5 = {2 * dx, 0f};float[] p6 = {dx, -dy};float[] p7 = {2 * dx, 0f};float[] p8 = {dx, dy};float[] p9 = {2 * dx, 0f};path.reset();path.moveTo(p1[0], p1[1]);path.rQuadTo(p2[0], p2[1], p3[0], p3[1]);path.rQuadTo(p4[0], p4[1], p5[0], p5[1]);path.rQuadTo(p6[0], p6[1], p7[0], p7[1]);path.rQuadTo(p8[0], p8[1], p9[0], p9[1]);path.lineTo(width, height);path.lineTo(0f, height);path.close();canvas.clipPath(path);super.onDraw(canvas);}
}
2)如何使用?
<com.....BezierImageView android:id="@+id/bg"android:layout_width="200dp"android:layout_height="200dp"android:layout_centerInParent="true"android:scaleType="fitCenter"android:src="@drawable/bg_cover" />
bg.setProgress(50);
直接调用setProgress()方法,传入要裁剪的百分比即可。
效果如下所示:
4、使用sin()正弦函数实现波浪/曲线效果
基于3中,直接修改onDraw()中的关键代码即可:
@Overrideprotected void onDraw(Canvas canvas) {final int width = getWidth();final int height = getHeight();// 变量描述,可自己调整:// offset:Y轴偏移量// yHeight:可控制Y轴高度(值越小百分比显示越大)// countF:控制波数(越大波数越少)// xOffset:可控制波长幅度(值越大幅度越大,越小越平缓)float offset = 0.1f, yHeight = 1.0f, countF = 60.0f, xOffset = 0.04f;// 方案1:path.moveTo(0, height);for (int i = 0; i < width; i++) {path.lineTo(i, (float) (height * ((yHeight - offset) + Math.sin(i / countF + Math.PI) * xOffset)));}path.lineTo(width, height);path.lineTo(0f, height);path.close();canvas.clipPath(path);super.onDraw(canvas);}
使用sin()函数结合lineTo()方法,同样可以实现波浪曲线效果:
相关文章:

Android裁剪图片为波浪形或者曲线形的ImageView
如果需要做一个自定义的波浪效果的进度条,裁剪图片,对ImageView的图片进行裁剪,比如下面2张图,如何实现? 先看下面的效果,看到其实只需要对第一张高亮的图片进行处理即可,灰色状态的作为背景图。…...

Linux课程____shell脚本应用
:一、认识shell 常用解释器 Bash , ksh , csh 登陆后默认使用shell,一般为/bin/bash,不同的指令,运行的环境也不同 二、 编写简单脚本并使用 # vim /frist.sh //编写脚本文件,简单内容 #!/bin/bash …...

设计模式12--组合模式
定义 案例一 案例二 优缺点...

【微服务】软件架构的演变之路
目录 单体式架构的时代单体式架构(Monolithic)优点缺点适用场景单体式架构面临诸多问题1.宽带提速,网民增多2.Web2.0时代的特点问题描述优化方向 集群优点缺点适用场景搭建集群后面临诸多问题用户请求问题用户的登录信息数据查询 改进后的架构 垂直架构优点缺点 分布…...
安全算法 - 加密算法
加密算法是一种在信息安全领域中广泛应用的算法,能够将数据进行加密转换,以保证数据的保密性和安全性。 它具有保密性、对称加密和非对称加密、密钥管理、数据完整性和认证等重要特点和应用。 加密算法可以分为对称加密和非对称加密两种类型࿱…...
安全算法 - 国密算法
国密算法是中国自主研发的密码算法体系,包括对称加密算法、非对称加密算法和哈希算法。其中,国密算法采用SM4作为对称加密算法,SM2作为非对称加密算法,以及SM3作为哈希算法。国密算法在信息安全领域具有重要意义和广泛应用&#x…...
蓝桥杯2014年第十三届省赛真题-武功秘籍
一、题目 武功秘籍 小明到X山洞探险,捡到一本有破损的武功秘籍(2000多页!当然是伪造的)。他注意到:书的第10页和第11页在同一张纸上,但第11页和第12页不在同一张纸上。 小明只想练习该书的第81页到第92页的…...

Could not initialize class java.awt.Font
项目场景: 项目场景:java项目在web端导出Excel、Word、PDF等文档 问题描述 在Windows系统中开发以及运行文件导出正常,单机部署到Linux中或者使用docker部署后,导出报错。 异常: eleasing transactional SqlSession…...

Mysql or与in的区别
创建一个表格 内涵一千万条数据 这张表中,只有id有建立索引,且其余都没有 测试1:使用or的情况下,根据主键进行查询 可以看到根据主键id进行or查询 花费了30-114毫秒,后面30多毫秒可能是因为Mysql的Buffer Pool缓冲池的…...

STM32——USART
一、通信 1.1通信是什么; 通信是将一个设备的数据发送到另一个设备中,从而实现硬件的扩展; 1.2通信的目的是什么; 实现硬件的扩展-在STM32中集成了很多功能,例如PWM输出,AD采集,定时器等&am…...

WebCopilot:一款功能强大的子域名枚举和安全漏洞扫描工具
关于WebCopilot WebCopilot是一款功能强大的子域名枚举和安全漏洞扫描工具,该工具能够枚举目标域名下的子域名,并使用不同的开源工具检测目标存在的安全漏洞。 工具运行机制 WebCopilot首先会使用assetsfinder、submaster、subfinder、accumt、finddom…...

HarmonyOS实战开发-如何实现一个支持加减乘除混合运算的计算器。
介绍 本篇Codelab基于基础组件、容器组件,实现一个支持加减乘除混合运算的计算器。 说明: 由于数字都是双精度浮点数,在计算机中是二进制存储数据的,因此小数和非安全整数(超过整数的安全范围[-Math.pow(2, 53)&#…...
每日OJ题_子序列dp⑥_力扣873. 最长的斐波那契子序列的长度
目录 力扣873. 最长的斐波那契子序列的长度 解析代码 力扣873. 最长的斐波那契子序列的长度 873. 最长的斐波那契子序列的长度 难度 中等 如果序列 X_1, X_2, ..., X_n 满足下列条件,就说它是 斐波那契式 的: n > 3对于所有 i 2 < n&#x…...

病毒循环Viral Loop是什么?为何能实现指数增长
一、什么是病毒循环(Viral Loop)? 病毒循环(Viral Loop)是一种机制,它推动连续的推荐以实现持续增长。 它会促使你现有的客户推荐其他人,去认识你的品牌,然后让这些新客户进一步告诉…...

下载huggingface中数据集/模型(保存到本地指定路径)
一. snapshot_download # 1.安装huggingface_hub # pip install huggingface_hubimport osfrom huggingface_hub import snapshot_downloadprint(downloading entire files...) # 注意,这种方式仍然保存在cache_dir中 snapshot_download(repo_id"ibrahimhamam…...

HarmonyOS实战开发-使用List组件实现导航与内容联动的效果。
1 卡片介绍 使用ArkTS语言,实现一个导航与内容二级联动的效果。 2 标题 二级联动(ArkTS) 3 介绍 本篇Codelab是主要介绍了如何基于List组件实现一个导航和内容的二级联动效果。样例主要包含以下功能: 切换左侧导航ÿ…...

ArcGIS二次开发(一)——搭建开发环境以及第一个简单的ArcGIS Engine 程序
Arcgis10.2、Arcgis Engine10.2与Microsoft Visual Studio 2012的版本进行安装 1、推荐教程与安装包2、安装顺序3、安装成功测试VS新建项目可以创建ArcGIS项目,并且在VS中拖拽ArcGIS工具 4、搭建第一个简单的ArcGIS Engine 程序 ArcEngine和VS版本是有对应的&#x…...

Oracle 19c 高可用部署实战系列之Data Guard理论与实战
课程介绍 Oracle Data Guard确保企业数据的高可用性、数据保护和灾难恢复。 Oracle Data Guard提供了一组全面的服务,用于创建、维护、管理和监视一个或多个备用数据库,使生产Oracle数据库能够在灾难和数据损坏中幸存下来。Oracle Data Guard将这些备用…...
ubuntu常用记录
常用命令 ps aux |grep ... pip show pkgname nvidia-smi -l du -sh * df -h head -n 10 file.txt htop sudo apt install package_name kill process_id 软链接 在 Linux 中,软连接(Symbolic Link,也称为符号链接或软链接)是一…...
顺序表专题
文章目录 目录1. 数据结构相关概念1.1 什么是数据结构1.2 为什么需要数据结构 2. 顺序表的概念及结构3. 顺序表分类4. 实现动态顺序表4.1 初始化4.2 顺序表的尾部插入4.3 打印顺序表4.4 顺序表的头部插入4.5 顺序表的尾部删除4.6 顺序表的头部删除4.7 指定位置之前插入数据4.8 …...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...