Android 实例 - Android 圆形蒙版(Android 圆形蒙版实现、圆形蒙版解读)

Android 圆形蒙版实现

1、View
java 复制代码
public class CircleMaskView extends View {

    private Paint paint;

    public CircleMaskView(Context context, AttributeSet attrs) {
        super(context, attrs);

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.TRANSPARENT);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int width = getWidth();
        int height = getHeight();
        int centerX = width / 2;
        int centerY = height / 2;
        int radius = Math.min(width, height) / 2;

        canvas.drawCircle(centerX, centerY, radius, paint);
    }
}
2、Layout
xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".fragment.UserFaceIdentifyFragment"
    tools:ignore="MissingConstraints">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="请面向屏幕上方摄像头"
        android:textColor="#ff262626"
        android:textSize="32sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/cl_preview_container"
        android:layout_width="380dp"
        android:layout_height="380dp"
        android:layout_marginTop="60dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_title">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="340dp"
            android:layout_height="340dp"
            android:orientation="horizontal"
            android:translationZ="100dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <SurfaceView
                android:id="@+id/sv_preview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <View
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/white"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <com.my.smallscreen.view.CircleMaskView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
        </androidx.constraintlayout.widget.ConstraintLayout>
    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

圆形蒙版解读

1、View
(1)类与变量
java 复制代码
public class CircleMaskView extends View {
    ...
}
  1. 实现自定义 View,继承 Android 的基础 View 类
java 复制代码
private Paint paint;
  1. 定义一个 Paint 对象,即画笔对象,Paint 类可以决定如何绘制图形,例如,颜色、风格、粗细等
(2)构造函数
java 复制代码
public CircleMaskView(Context context, AttributeSet attrs) {
    super(context, attrs);

    ...
}
  1. 调用父类 View 的构造函数,这是标准的用于确保 View 能正确地从 XML 布局属性中初始化的操作
java 复制代码
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
  1. 创建 Paint 对象,Paint.ANTI_ALIAS_FLAG 是抗锯齿,启用后,图形的边缘会变得更加平滑,不会出现锯齿状
java 复制代码
paint.setColor(Color.TRANSPARENT);
  1. 设置画笔的颜色为透明,用这支笔画出的任何形状本身都是透明的
(3)实现蒙版效果
java 复制代码
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
  1. setXfermode 方法用于定义当绘制一个新图形(源)到 Canvas 上时,如何与已经存在的图形(目标)进行组合

  2. PorterDuff.Mode.DST_IN 是 PorterDuff 混合模式中的一种,它的规则是,最终结果只保留目标图像中与源图像重叠,且源图像不透明的部分

  3. 简单来说,DST_IN 混合模式的效果就是: 用源图像的 Alpha(透明度)通道来裁剪目标图像

  4. 源图像透明的地方,目标图像就变透明;源图像不透明的地方,目标图像就保持原样

(4)onDraw 方法
java 复制代码
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    ...
}
  1. 调用父类的绘制方法,但是 View 类中的 onDraw 方法默认是空实现,所以可以省略
java 复制代码
int width = getWidth();
int height = getHeight();
int centerX = width / 2;
int centerY = height / 2;
  1. 获取当前 View 的宽度和高度,计算 View 的中心点坐标
java 复制代码
int radius = Math.min(width, height) / 2;
  1. 计算圆的半径,取宽和高中的较小值的一半,以确保圆形总能完全显示在 View 中,无论 View 是正方形还是长方形
java 复制代码
canvas.drawCircle(centerX, centerY, radius, paint);
  1. 执行绘制,使用之前配置好的 Paint 对象在 Canvas 上绘制一个圆形
2、Layout
xml 复制代码
<SurfaceView
    android:id="@+id/sv_preview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />
  1. 显示摄像头预览画面
xml 复制代码
<View
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />
  1. 用一个白色背景覆盖整个预览画面
xml 复制代码
<com.my.smallscreen.view.CircleMaskView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />
  1. 使用 CircleMaskView 在白色背景上挖出一个圆形洞,使圆形区域内的摄像头预览画面可见,而圆形区域外显示白色背景
相关推荐
一定要AK13 分钟前
Spring 入门核心笔记
java·笔记·spring
A__tao14 分钟前
Elasticsearch Mapping 一键生成 Java 实体类(支持嵌套 + 自动过滤注释)
java·python·elasticsearch
SharpCJ23 分钟前
Android 开发者为什么必须掌握 AI 能力?端侧视角下的技术变革
android·ai·aigc
KevinCyao27 分钟前
java视频短信接口怎么调用?SpringBoot集成视频短信及回调处理Demo
java·spring boot·音视频
迷藏49434 分钟前
**发散创新:基于Rust实现的开源合规权限管理框架设计与实践**在现代软件架构中,**权限控制(RBAC)** 已成为保障
java·开发语言·python·rust·开源
_李小白1 小时前
【OSG学习笔记】Day 38: TextureVisitor(纹理访问器)
android·笔记·学习
JJay.1 小时前
Kotlin 高阶函数学习指南
android·开发语言·kotlin
jinanwuhuaguo1 小时前
截止到4月8日,OpenClaw 2026年4月更新深度解读剖析:从“能力回归”到“信任内建”的范式跃迁
android·开发语言·人工智能·深度学习·kotlin
wuxinyan1232 小时前
Java面试题47:一文深入了解Nginx
java·nginx·面试题
新知图书2 小时前
搭建Spring Boot开发环境
java·spring boot·后端