Android 使用 Canvas 和 Paint 实现圆形图片

学习笔记

效果展示:

全部代码:

public class YuanActivity extends AppCompatActivity {private ActivityYuanBinding binding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 通过 DataBinding 获取布局文件binding = ActivityYuanBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());// 设置返回按钮的点击事件,点击时跳转到 MainActivitybinding.fanhuiYuan.setOnClickListener(v -> {Intent intent = new Intent(YuanActivity.this, MainActivity.class);startActivity(intent);});// 加载原始图片(从资源文件加载)Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.userphoto);// 获取圆形裁剪后的图片,这里 500 是圆角的半径Bitmap roundedBitmap = getRoundedCornerBitmap(bitmap, 500);// 设置 ImageView 显示圆形裁剪后的图片binding.yuanjiaophotoYuan.setImageBitmap(roundedBitmap);}/*** 将原始 Bitmap 转换为圆角图片(这里实际是圆形图片)** @param bitmap 原始图片* @param radius 圆角半径* @return 圆角(圆形)图片*/private Bitmap getRoundedCornerBitmap(Bitmap bitmap, float radius) {// 获取原始图片的宽高int width = bitmap.getWidth();int height = bitmap.getHeight();// 创建一个新的 Bitmap,用于保存圆角效果的图像// 使用 ARGB_8888 配置,支持透明度,效果较好Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);// 创建一个 Canvas 对象,用于在新 Bitmap 上绘制Canvas canvas = new Canvas(output);// 创建 Paint 对象,设置绘制样式Paint paint = new Paint();paint.setAntiAlias(true); // 启用抗锯齿,以确保绘制出来的圆角平滑paint.setFilterBitmap(true); // 启用图像过滤,提高图像质量paint.setDither(true); // 启用抖动,使图像颜色更平滑paint.setColor(Color.BLACK); // 设置画笔颜色为黑色// 创建一个矩形区域,作为圆角矩形的边界RectF rectF = new RectF(0, 0, width, height);// 绘制一个圆角矩形(实际绘制的是一个圆形矩形)// 这里的 radius 就是圆角的半径,设置为较大的值会形成圆形效果canvas.drawRoundRect(rectF, radius, radius, paint);// 设置 Xfermode(混合模式),使得图片绘制在圆角矩形内// SRC_IN 表示仅保留矩形与原图片交集部分的内容,超出部分透明paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));// 将原始图片绘制到圆角矩形区域内canvas.drawBitmap(bitmap, 0, 0, paint);// 返回处理后的圆角图片return output;}
}

学习笔记:使用 CanvasPaint 实现圆角图片

在 Android 中,CanvasPaint 是用于图形绘制的基础类,利用这两者可以对图片进行各种裁剪和样式处理。实现圆角图片的关键是对原始图片进行裁剪,使其边角变圆。通过绘制一个圆角矩形,将图片内容限制在这个矩形内,即可实现圆角效果。

基本概念
  • Canvas:用于绘制图形的画布,可以用来绘制矩形、圆形、图片等内容。
  • Paint:控制绘制的样式,包括颜色、线条宽度、抗锯齿等。
  • Bitmap:位图对象,表示图片的数据,可以对其进行操作(例如裁剪、旋转等)。

步骤说明:实现圆角图片

1. 创建新的 Bitmap

为了将原图裁剪为圆角图像,首先需要创建一个新的 Bitmap,它的宽度和高度与原图相同,并且格式为 ARGB_8888,以保证图片质量。

2. 绘制圆角矩形

使用 CanvasPaint 绘制一个圆角矩形。圆角的半径通过传入的参数来控制,矩形的大小与原始图片相同。

3. 使用 Xfermode 实现图像裁剪

Xfermode 控制图形的混合模式。在这里,使用 PorterDuff.Mode.SRC_IN 可以确保图片只绘制在圆角矩形区域内,其他部分会变成透明。

4. 将原始图片绘制到圆角区域

最后,我们将原始图片绘制到上面创建的圆角矩形区域,从而实现圆角效果。


代码实现:

 
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private ImageView imageView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);imageView = findViewById(R.id.imageView);// 加载原始图片Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.your_image);// 获取圆角裁剪后的图片Bitmap roundedBitmap = getRoundedCornerBitmap(bitmap, 30); // 30是圆角的半径// 显示圆角图片imageView.setImageBitmap(roundedBitmap);}/*** 将 Bitmap 转换为圆角图片** @param bitmap 原始图片* @param radius 圆角半径* @return 圆角图片*/private Bitmap getRoundedCornerBitmap(Bitmap bitmap, float radius) {// 获取图片的宽高int width = bitmap.getWidth();int height = bitmap.getHeight();// 创建一个新的 Bitmap,用于保存圆角效果Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);// 创建一个 Canvas 用来绘制圆角图像Canvas canvas = new Canvas(output);// 创建一个 Paint 对象Paint paint = new Paint();paint.setAntiAlias(true); // 抗锯齿paint.setFilterBitmap(true); // 使用过滤器paint.setDither(true); // 使用抖动paint.setColor(Color.BLACK); // 设置画笔颜色为黑色// 创建一个矩形,作为圆角矩形的边界RectF rectF = new RectF(0, 0, width, height);// 绘制圆角矩形canvas.drawRoundRect(rectF, radius, radius, paint);// 设置 Xfermode 使图像绘制在圆角矩形区域内paint.setXfermode(new android.graphics.PorterDuffXfermode(android.graphics.PorterDuff.Mode.SRC_IN));// 绘制原始图片canvas.drawBitmap(bitmap, 0, 0, paint);return output;}
}

学习笔记:如何实现圆形图片裁剪

概述

本篇学习笔记将讲解如何使用 Android 中的 CanvasPaint 实现圆形图片裁剪的功能。具体实现通过绘制圆形区域并结合 PorterDuff.Mode.SRC_IN 混合模式,将图片裁剪成圆形,并显示在 ImageView 中。

核心概念
  • Canvas:用于绘制图形的画布。所有的绘制操作(如绘制圆形、矩形、图片等)都需要借助 Canvas 对象来进行。
  • Paint:设置绘图样式(如颜色、字体、抗锯齿等)的对象。在绘制时,Paint 控制着图形的样式和外观。
  • PorterDuffXfermode:图像合成模式,控制绘制多个图形时的合成方式。SRC_IN 模式让图像仅在两个区域重叠的地方显示(即保留图像的交集部分)。
  • Bitmap:在 Android 中,图片以 Bitmap 对象的形式存储和处理。通过 Bitmap 对象可以对图片进行裁剪、缩放等处理。
实现步骤
  1. 加载原始图片

    • 使用 BitmapFactory.decodeResource() 从资源中加载图片。这里我们使用了一张图片资源 userphoto
     
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.userphoto);
    

  2. 创建 CanvasPaint 对象

    • Canvas 用于在新的 Bitmap 上绘制图形。我们创建一个新的 Bitmap,大小为图片的最小边长,以确保圆形能够完整地显示。
    • Paint 用于设置绘图样式,setAntiAlias(true) 开启抗锯齿,setFilterBitmap(true) 启用图像过滤,使图像更加平滑。
     
    Canvas canvas = new Canvas(output);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setFilterBitmap(true);
    paint.setDither(true);
    paint.setColor(Color.BLACK);
    

  3. 绘制圆形

    • 我们绘制一个圆形,圆心位置为 (width / 2, width / 2),半径为 width / 2,确保圆形正好填满整个 Bitmap
     
    canvas.drawCircle(width / 2f, width / 2f, width / 2f, paint);
    

  4. 设置 Xfermode(图像合成模式)

    • 设置 PorterDuffXfermodeSRC_IN,意味着我们只保留源图像(原始图片)和目标图像(当前圆形区域)交集的部分,其他部分会被透明填充。
    • SRC_IN 模式非常适合用于图片裁剪,因为它只显示重叠的部分。
     
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    

  5. 绘制原始图片到圆形区域

    • 使用 canvas.drawBitmap() 方法将原始图片绘制到指定区域。在这里我们计算了一个矩形区域 Rect,将图片绘制到这个区域内。
     
    canvas.drawBitmap(bitmap, null, rect, paint);
    

  6. 返回处理后的圆形图片

    • 完成绘制后,返回最终的圆形图片 output,可以在 UI 上展示。
     
    return output;
    

代码实现
 
public class YuanActivity extends AppCompatActivity {private ActivityYuanBinding binding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);binding = ActivityYuanBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());// 返回按钮点击事件binding.fanhuiYuan.setOnClickListener(v -> {Intent intent = new Intent(YuanActivity.this, MainActivity.class);startActivity(intent);});// 加载原始图片Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.userphoto);// 获取圆形裁剪后的图片Bitmap circularBitmap = getCircularBitmap(bitmap);// 显示圆形图片binding.yuanxinphotoYuan.setImageBitmap(circularBitmap);}// 将图片裁剪为圆形private Bitmap getCircularBitmap(Bitmap bitmap) {// 获取原始图片的最小边长int width = Math.min(bitmap.getWidth(), bitmap.getHeight());// 创建一个新的 Bitmap,用于保存圆形效果的图像Bitmap output = Bitmap.createBitmap(width, width, Bitmap.Config.ARGB_8888);// 创建 Canvas 对象以便在新的 Bitmap 上绘制Canvas canvas = new Canvas(output);// 创建 Paint 对象设置绘图样式Paint paint = new Paint();paint.setAntiAlias(true); // 启用抗锯齿paint.setFilterBitmap(true); // 启用图像过滤paint.setDither(true); // 启用抖动paint.setColor(Color.BLACK); // 设置绘制圆形的颜色为黑色// 绘制圆形canvas.drawCircle(width / 2f, width / 2f, width / 2f, paint);// 设置 Xfermode 只保留源图像与圆形区域交集部分paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));// 计算图片放置区域Rect rect = new Rect(0, 0, width, width);// 绘制原始图片,只有圆形区域内的部分会显示canvas.drawBitmap(bitmap, null, rect, paint);return output; // 返回圆形图片}
}

关键概念详细解释
  1. Bitmap

    • Bitmap 是 Android 中表示图片的对象。它可以通过文件、资源或其他方式生成。在本示例中,我们从资源中加载了一张图片 R.drawable.userphoto,并将其转换为 Bitmap
  2. CanvasPaint

    • Canvas 是一个画布,用于绘制图形。所有的绘制操作(如绘制圆形、矩形、图片等)都是通过 Canvas 完成的。
    • Paint 用于设置绘图时的样式,比如颜色、抗锯齿、过滤器等。
  3. PorterDuff.Mode.SRC_IN

    • PorterDuff 是图像合成的模式。SRC_IN 模式意味着只保留源图像(原图)与目标图像(圆形区域)交集的部分,其余部分会变成透明。这个模式非常适合做图片裁剪,特别是圆形裁剪。
  4. drawCircle

    • Canvas.drawCircle() 用于绘制一个圆形。在裁剪圆形图片时,我们在 Canvas 上绘制一个圆形,作为裁剪的边界。
  5. Xfermode

    • Xfermode 用于定义图形绘制时如何合成。通过设置 SRC_IN 模式,我们确保只有圆形区域内的图片内容被显示,其他区域会被透明填充,从而实现圆形裁剪效果。

总结

通过结合 CanvasPaintPorterDuffXfermode,我们可以灵活地对图片进行裁剪,并实现如圆形、圆角矩形等效果。此方法非常适用于在 Android 中处理图像,并能够快速实现视觉效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/34922.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

python怎么将字母大写

Python中有三种将字母转换为大写的方法:upper()、capitalize()、title()。 下面通过实例给大家介绍具体用法: str "www.php.com" print(str.upper()) # 把所有字符中的小写字母转换成大写字母 print(str.lower()) # 把所有字…

鸿蒙Next星河版高级用例之网络请求和自适应布局以及响应式布局

目录: 1、发起网络请求的两种方式第一种使用httpRequest发送http的请求:1.1、在进行网络请求前,您需要在module.json5文件中申明网络访问权限1.2、GET 请求1.3、POST请求1.4、处理响应的结果第二种使用axios发送http的请求:1.1、在…

ClouderaManager 集群搭建

前提:服务器之前做过域名映射、免密登录 ClouderaManager 集群 1. 组件分布规划 服务器服务器h1zk、hdfs(dn)、yarn(nm)、spark、kafka、flumeh2hdfs(nn-standy)、yarn(rm-active)、sparkh3hdfs(nn-active)、yarn(rm-standy)、hive、sparkh4zk、hdfs(dn)、yarn(n…

如何获取谷歌新闻API密钥?

在信息获取和新闻传播领域,快速获取最新的新闻动态至关重要。谷歌新闻API为开发者提供了强大的工具,能够方便地集成全球各类新闻内容。通过使用该API,开发者可以实现对新闻的实时访问和管理,为用户提供丰富的信息服务。本文将指导…

IP 协议

IP协议 一、介绍1、IP协议2、IPv43、IPv6 二、主要功能三、协议格式1、示意图2、说明 四、网段划分1、介绍2、目的3、方法4、步骤 五、基于类别的IP地址分配方式1、示意图2、范围 六、CIDR1、介绍2、组成3、优点4、示意图 七、子网掩码1、介绍2、功能3、表示方法4、CIDR表示法5…

数据结构 (23)并查集与等价类划分

一、并查集 并查集(Union-Find Set或Disjoint Set)是一种数据结构,用于处理一些不相交集合(disjoint sets)的合并及查询问题。它通常表示为森林,并用数组来实现(类似于二叉堆)。在并…

Java 【数据结构】 哈希(Hash超详解)HashSetHashMap【神装】

登神长阶 第十神装 HashSet 第十一神装 HashMap 目录 👔一.哈希 🧥1.概念 🩳2.Object类的hashCode()方法: 👚3.String类的哈希码: 👠4.注意事项: 🎷二.哈希桶 🪗1.哈希桶原理 &#x…

lyapunov指数的绘制

有如下方程: %% 方程式 % x(n1)1y(n)-a*x(n)^2 % y(n1)b*x(n)绘制其对应的lyapunov指数。 MATLAB实现方式: clc; clearvars; close all;%% 方程式 % x(n1)1y(n)-a*x(n)^2 % y(n1)b*x(n)%% 代码 N 1000; a (0:0.001:1.4); b 0.3; na length(a…

LearnOpenGL学习(高级OpenGL -- 深度测试,模板测试,)

深度测试 深度缓冲用来防止被阻挡的面渲染到其他面的前面,深度缓冲就像颜色缓冲,在每个片段中储存了信息, 当深度测试(Depth Testing)被启用的时候,OpenGL会将一个片段的深度值与深度缓冲的内容进行对比。OpenGL会执行一个深度测…

【CSP CCF记录】202305-2第30次认证 矩阵运算

题目 样例输入 3 2 1 2 3 4 5 6 10 10 -20 -20 30 30 6 5 4 3 2 1 4 0 -5 样例输出 480 240 0 0 -2200 -1100 思路 我的初步想法是按照题目所给计算顺序,分为三步计算,即: 1. ,时间复杂度为 2. ,时间复杂度为 3.&a…

Tomcat,javaweb, servlet , springBoot

在server.xml里配置服务器 <scope>provided</scope>打包的时候&#xff0c;这个jar包不会被打进去&#xff0c;因为tomcat已将封装了这个jar包&#xff0c;没必要要这个

书生实战营第四期-进阶岛第一关-探索 InternLM 模型能力边界

任务一: InternThinker 挑战 Leetcode Leetcode题目链接 Prompt InternThinker 回答截图 Q1 仅含置位位的最小整数 - 力扣&#xff08;LeetCode&#xff09; 给你一个正整数 n。 返回 大于等于 n 且二进制表示仅包含 置位 位…

[SAP ABAP] ALV基础开发

ALV全称为SAP List Viewer&#xff0c;是SAP中常用的报表输出格式&#xff0c;输出结果以行和列展示&#xff0c;集成的功能有排序&#xff0c;求和&#xff0c;过滤&#xff0c;隐藏&#xff0c;筛选等功能 ALV格式的数据是以单元格为单位显示&#xff0c;这种方式便于数据导…

360全向触觉型灵巧手 Allegro Hand V5 亮相,Wonik 机器人助推前沿科技前行

在机器人技术持续演进的当下&#xff0c;Wonik Robotics 依靠自身技术实力&#xff0c;推出了新一代机器人手 Allegro Hand V5&#xff0c;为工业与科研领域带来新机遇。 Allegro Hand V5 具备诸多出色特性。 Allegro Hand V5 指尖配备的全方位触觉传感器是一大亮点&#xff0…

python 装饰器学习与实践

目录 装饰器学习1、最基本装饰器2、函数带参数的装饰器3、装饰器带参数4、类中函数的装饰器5、装饰器实践6、pyqt5类中方法的装饰器实现时遇到的问题 装饰器学习 先假定一个场景 在之前的一篇文章中&#xff0c;分享了一个pyqt5将日志实时展示在gui界面上的功能python在pyqt5l…

12.4深度学习_模型优化和迁移_awanb、tb

一、数据获取方法 1. 开源数据集 ​ 免费&#xff0c;成本低 PyTorch&#xff1a; https://pytorch.org/vision/stable/datasets.html 开源数据集imagenet&#xff1a;https://image-net.org/ Hugging Face数据集&#xff1a;https://huggingface.co/datasets kaggle数据集…

网络基础知识

172.16.24.100这个是ip地址&#xff0c;讲师机的IP地址。IP地址&#xff08;Internet Protocol Address&#xff09;是指互联网协议地址&#xff0c;又译为网际协议地址。每台电脑只要联网都会有ip地址。ip地址数量有限&#xff0c;不够给世界上每一台电脑分配ip地址&#xff0…

漫画之家系统:Spring Boot技术下的漫画发现引擎

4 系统设计 4.1系统设计主要功能 通过市场调研及咨询研究&#xff0c;了解了用户及管理者的使用需求&#xff0c;于是制定了管理员和用户等模块。功能结构图如下所示&#xff1a; 图4-1系统功能结构图 4.2数据库设计 4.2.1数据库设计规范 数据可设计要遵循职责分离原则&#…

漫画之家系统:Spring Boot框架下的漫画版权保护

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&a…

【python rich 超级牛终端中提供富文本和精美格式】

Rich 是一个 Python 库&#xff0c;可以为您在终端中提供富文本和精美格式。 》》》》官方代码和文档《《《《 Rich 的 API 让在终端输出颜色和样式变得很简单。此外&#xff0c;Rich 还可以绘制漂亮的表格、进度条、markdown、语法高亮的源代码以及栈回溯信息&#xff08;tr…