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

news2025/1/11 20:00:31

学习笔记

效果展示:

全部代码:

public class YuanActivity extends AppCompatActivity {

    private ActivityYuanBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 通过 DataBinding 获取布局文件
        binding = ActivityYuanBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        // 设置返回按钮的点击事件,点击时跳转到 MainActivity
        binding.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;

    @Override
    protected 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;

    @Override
    protected 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.coloradmin.cn/o/2254750.html

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

相关文章

鸿蒙DevEco Profiler无法识别设备

一、问题 DevEco Studio运行项目处可以识别到设备信息,但是Profiler工具无法识别 二、背景知识 注意 DevEco Profiler工具不支持模拟器进行调优。macOS 12及以上系统版本支持使用DevEco Profiler工具。 知识来源:文档中心 三、解决方案 重启DevEco …

微信小程序版小米商城的搭建流程详解!

很多初学微信小程序语法的同学,可能不知道如何布局和搭建一个项目,下面我将讲解初学者如何搭建项目和注意事项。 目录 一、 app.json的配置 二、引入vant 三、主页banner携带参数跳转 四、点击商品项跳转详情页 一、 app.json的配置 {"pages&q…

第30天:安全开发-JS 应用NodeJS 指南原型链污染Express 框架功能实现审计0

时间轴: 演示案例: 环境搭建-NodeJS-解析安装&库安装 功能实现-NodeJS-数据库&文件&执行 安全问题-NodeJS-注入&RCE&原型链 案例分析-NodeJS-CTF 题目&源码审计 开发指南-NodeJS-安全 SecGuide 项目、 环境搭建-NodeJ…

LongVU:用于长视频语言理解的空间时间自适应压缩

晚上闲暇时间看到一种用于长视频语言理解的空间时间自适应压缩机制的研究工作LongVU,主要内容包括: 背景与挑战:多模态大语言模型(MLLMs)在视频理解和分析方面取得了进展,但处理长视频仍受限于LLM的上下文长…

Observability:用 OpenTelemetry 自动检测 Python 应用程序

作者:来自 Elastic Bahubali Shetti 了解如何使用 OpenTelemetry 自动检测 Python 应用程序。使用 Docker 文件中的标准命令,可以快速检测应用程序,而无需在多个位置编写代码,从而实现快速更改、扩展和更轻松的管理。 更多阅读&a…

JVM, JRE 和 JDK

JRE: Java Runtime Environment, Java 运行环境. JDK: Java Development Kit, Java 开发工具包. JRE JVM 核心类库 运行工具 JDK JVM 核心类库 开发工具 JVM: Java Virtual Machine, Java 虚拟机. 核心类库: Java 已经写好的东西, 直接拿来用即可. 开发工具: 包括 …

Ubuntu 22.04.5 + kubeadm:Kubernetes v1.28.2集群部署企业实战

文章目录 Ubuntu 22.04.5 kubeadm:Kubernetes v1.28.2集群部署企业实战一、环境准备1.1 机器规划1.2 环境配置1.2.1 设置主机名1.2.2 安装依赖工具1.2.3 配置时间同步1.2.4 关闭swap分区1.2.5 停止和禁用防火墙1.2.6 配置内核转发及网桥过滤1.2.7 安装配置ipset及i…

Mac环境下brew安装LNMP

安装不同版本PHP 在Mac环境下同时运行多个版本的PHP,同Linux环境一样,都是将后台运行的php-fpm设置为不同的端口号,下面将已php7.2 和 php7.4为例 添加 tap 目的:homebrew仅保留最近的php版本,可能没有你需要的版本…

【Python网络爬虫笔记】8- (BeautifulSoup)抓取电影天堂2024年最新电影,并保存所有电影名称和链接

目录 一. BeautifulSoup的作用二. 核心方法介绍2.1 构造函数2.2 find()方法2.3 find_all()方法2.4 select()方法 三. 网络爬虫中使用BeautifulSoup四、案例爬取结果 一. BeautifulSoup的作用 解析HTML/XML文档:它可以将复杂的HTML或XML文本转换为易于操作的树形结构…

解决LED显示屏水波纹的方法

在拍摄LED显示屏时,水波纹和扫描线的出现常常让人误以为是显示屏质量问题,但实际上这些现象往往与拍摄角度和焦距有关。本文将探讨水波纹的成因,并提供一些有效的解决方法。 1. 水波纹与扫描线现象的区别 水波纹通常呈现无规则的弧形扩散状态…

【MySQL — 数据库基础】深入理解数据库服务与数据库关系、MySQL连接创建、客户端工具及架构解析

目录 1. 数据库服务&数据库&表之间的关系 1.1 复习 my.ini 1.2 MYSQL服务基于mysqld启动而启动 1.3 数据库服务的具体含义 1.4 数据库服务&数据库&表之间的关系 2. 客户端工具 2.1 客户端连接MySQL服务器 2.2 客…

记录关于阿里云智能媒体预览pdf文件的问题

pdf仅支持预览,不支持编辑,需要将权限设置成只读。 readonly参数一定要传,不能不传!!!! readonly的设置一定要用示例提供的方法!!!! 用WebofficeP…

FlyHttp 的设计思想:前端 API 自动化构建工具

FlyHttp的相关文章: FlyHttp 的诞生:从认识各种网络请求开始 FlyHttp 的设计思想:前端 API 自动化构建工具 FlyHttp 的使用:如何高效使用 FlyHttp,支持 JS、TS 项目 FlyHttp 的最佳实践:加速项目级 API…

WHLUG丨deepin、华中科技大学开放原子开源俱乐部、 RustSBI 和清华大学开源操作系统训练营共话开源新生代成长之路

2024年11月30日下午,由 deepin(深度)社区联合华中科技大学开放原子开源俱乐部、 RustSBI 开源社区和清华大学开源操作系统训练营共同举办的WHLUG(武汉Linux用户组)线下沙龙在华中科技大学成功举办。 本次活动聚集了50余…

K8S离线部署Nacos集群【Oracle作外部数据源】

一、前言 由于公司的要求下要使Nacos集群以Oracle作为外部数据源,前期咱们已经阐述了如何在本地搭建(Nacos集群搭建【Oracle作外部数据源】),本次将带领大家在k8s上部署Nacos集群并以Oracle作为外部数据源。 二、软件包 nacos-f…

MperReduce学习笔记下

自定义InputFormat合并小文件 案例需求 无论hdfs还是mapreduce,对于小文件都有损效率,实践中,又难免面临处理大量小文件的场景,此时,就需要有相应解决方案。 案例分析 小文件的优化无非以下几种方式: …

Junit5 单元测试入门

基础知识 常用注解含义 Test:标记一个方法为测试方法BeforeEach:标记的方法会在每个测试方法执行前执行AfterEach:标记的方法会在每个测试方法执行后执行BeforeAll:标记的方法会在所有测试方法执行前执行一次AfterAll&#xff1…

【CSS in Depth 2 精译_065】第四部分:CSS 视觉增强技术 + 第 11 章 颜色与对比概述 + 11.1 通过对比进行交流

当前内容所在位置(可进入专栏查看其他译好的章节内容) 第四部分 视觉增强技术 ✔️【第 11 章 颜色与对比】 ✔️ 11.1 通过对比进行交流 ✔️ 11.1.1 模式的建立 ✔️11.1.2 还原设计稿 ✔️ 11.2 颜色的定义 文章目录 第四部分 视觉增强技术 Visual e…

Java项目实战II基于微信小程序的作品集展示(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着移动互联网技术的飞速…

基于rpcapd与wireshark的远程实时抓包的方法

基于rpcapd与wireshark的远程实时抓包的方法 服务端安装wireshark侧设置 嵌入式设备或服务器上没有图形界面,通常使用tcpdump抓包保存为pcap文件后,导出到本地使用wireshark打开分析,rpcapd可与wireshark配合提供一种远程实时抓包的方案&…