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 在白色背景上挖出一个圆形洞,使圆形区域内的摄像头预览画面可见,而圆形区域外显示白色背景
相关推荐
咖啡Beans3 小时前
SpringBoot集成Clickhouse
java·spring boot
天若有情6733 小时前
【Android】Android项目目录结构及其作用
android
kobe_t3 小时前
数据安全系列6:从SM4国密算法谈到Bouncy Castle
java
灿烂阳光g3 小时前
Android Automotive OS架构
android
從南走到北3 小时前
JAVA露营基地预约户外露营预约下单系统小程序
java·开发语言·小程序
曹牧3 小时前
Java:实现List的定长截取
java·开发语言·list
水无痕simon3 小时前
8 shiro的web整合
java
CodeCraft Studio4 小时前
全球知名的Java Web开发平台Vaadin上线慧都网
java·开发语言·前端·vaadin·java开发框架·java全栈开发·java ui 框架
我是华为OD~HR~栗栗呀4 小时前
前端面经-高级开发(华为od)
java·前端·后端·python·华为od·华为·面试