Android:绘制自定义View人脸识别框

这篇具有很好参考价值的文章主要介绍了Android:绘制自定义View人脸识别框。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.绘制矩形框实现

项目开发需要自定义View实现一个人脸框,代码实现很平常,一些细节记录一下,方便以后查阅。

代码实现:

1.1 自定义人脸识别框:

FaceView.java

package com.android.example.ui.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.android.example.R;

import java.util.List;

public class FaceView extends View {

    //人脸识别框数组
    private List<Rect> mRectList;
    //画笔
    private Paint mPaint;

    public FaceView(Context context) {
        super(context);
        init();
    }

    /* 这个构造函数不能缺失,否则会编译报错
     * View走的构造函数也是这个,第一个构造函数反而没走
     */
    public FaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public FaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mPaint = new Paint();
        //设置抗锯齿
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(3);
        mPaint.setColor(Color.RED);
    }

    public void setFaceRects(List<Rect> mRectList) {
        this.mRectList = mRectList;
        //请求更新,View会自动执行onDraw进行绘制
        invalidate();
        //同样是请求更新,该方法表示在主线程发起绘制请求
        //postInvalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mRectList != null) {
            for (Rect rect : mRectList) {
                canvas.drawRect(rect, mPaint);
            }
        }
    }
}

1.2 布局文件中添加FaceView:

<com.android.example.ui.view.FaceView
    android:id="@+id/face_rects_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

注意:

这里我把FaceView的layout_width、layout_height都设置成了"match_parent"

这里面有个容易踩到
本次开发时,xml中FaceView控件往上一直到第一层父布局宽、高的设置都是:
layout_width="match_parent"
layout_height="wrap_content"

导致View的width、height无法确定,所以onDraw()一直不被执行
后来才发现是这里的问题
将控件FaceView控件宽高设置为固定大小就可以了

<com.android.example.ui.view.FaceView
    android:id="@+id/face_rects_view"
    android:layout_width="800dp"
    android:layout_height="800dp"/>

也就是说如果自定义View的宽高无法被确定,OnDraw()是不会执行的
这时候就需要排查设置宽高,或者修改布局配置使其值能够被确定。

1.3 代码调用:

List<Rect> rectlist = new ArrayList<Rect>();
Rect rect1 = new Rect(300, 300, 500, 500);
rectlist.add(rect1);

FaceView faceRectsView = findViewById(R.id.face_rects_view);
faceRectsView.setFaceRects(rectlist);

1.4 实现效果

Android:绘制自定义View人脸识别框

一个完整的自定义人脸识别框FaceView到此就实现了

顺带手在onDraw里可以做出其他不同的效果

二.绘制线段实现

使用canvas.drawLine()函数绘制线段,使用实现一个只显示四个角的人脸识别框

2.1 代码:

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

	if (mRectList != null) {
		for (Rect rect : mRectList) {
			/*左上角竖线*/
			canvas.drawLine(rect.left, rect.top, rect.left, rect.top + 20, mPaint);
			/*左上角横线*/
			canvas.drawLine(rect.left, rect.top, rect.left + 20, rect.top, mPaint);
			/*右上角竖线*/
			canvas.drawLine(rect.right, rect.top, rect.right - 20, rect.top, mPaint);
			/*右上角横线*/
			canvas.drawLine(rect.right, rect.top, rect.right, rect.top + 20, mPaint);
			/*左下角竖线*/
			canvas.drawLine(rect.left, rect.bottom, rect.left, rect.bottom - 20, mPaint);
			/*左下角横线*/
			canvas.drawLine(rect.left, rect.bottom, rect.left + 20, rect.bottom, mPaint);
			/*右下角竖线*/
			canvas.drawLine(rect.right, rect.bottom, rect.right, rect.bottom - 20, mPaint);
			/*右下角横线*/
			canvas.drawLine(rect.right, rect.bottom, rect.right - 20, rect.bottom, mPaint);
		}
	}
}

2.2 效果

Android:绘制自定义View人脸识别框

还有其他有趣的效果:圆形、椭圆等,就不一一列举了。

三.绘制Bitmap实现

3.1 实现过程

上一节讲述的都是用画布Cavas、画笔Paint自带的绘制线段、矩形等Api实现人脸框

这一节讲怎么使用UI设计的图片绘制人脸框,其实也就是onDraw()中绘制Bitmap

人脸框图片facerect.png:

Android:绘制自定义View人脸识别框

onDraw()绘制Bitmap代码:

package com.android.example.ui.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.android.example.R;

import java.util.List;

public class FaceView extends View {

    private List<Rect> mRectList;
    private Paint mPaint;
    private Bitmap mFaceRectBitmap;

    public FaceView(Context context) {
        super(context);
        init();
    }

    public FaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public FaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mPaint = new Paint();
        //不需要再配置画笔
        /*mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(3);
        mPaint.setColor(Color.RED);*/

        /*图片解析成Bitmap
         *Android不允许直接修改res里面的图片,所以要用copy方法*/
        mFaceRectBitmap = BitmapFactory.decodeResource(getResources(),
                R.mipmap.perception_facerect).copy(Bitmap.Config.ARGB_8888, true);
    }

    public void setFaceRects(List<Rect> mRectList) {
        this.mRectList = mRectList;
        invalidate();
    }

    //不需要再绘制时调用,销毁资源
    public void clear() {
        mRectList = null;
        mFaceRectBitmap.recycle();
        mFaceRectBitmap = null;
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mRectList != null && mFaceRectBitmap != null) {
            for (Rect rect : mRectList) {
                //drawBitmap()有多个重载,接下来会详细讨论
                canvas.drawBitmap(mFaceRectBitmap, rect.left, rect.top, mPaint);
            }
        }
    }
}

注: 画笔Paint只需要有一个实例对象就行,不需要再进行配置

3.2 实现效果

Android:绘制自定义View人脸识别框

四.canvas.drawBitmap()

上一节代码注释中提到了,canvas.drawBitmap()这个函数有多个重载

下面就来详细研究一下Canvas里关于绘制Bitmap的方法:

  1. drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
  2. drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)
  3. drawBitmap(Bitmap bitmap, float left, float top, Paint paint)
  4. drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)

方法1方法2只有dst参数类型 Rect 和 RectF 的区别
这两个方法要实现的功能都是把Bitmap的src区域绘制到画布dst区域内
如果dst无法完全覆盖src,而src和dst比例不对称,就会出现拉伸或缩放

方法3是把(left, top)作为Bitmap的左上角进行绘制,不拉伸也不压缩,如果超出了画布就不绘制,佛系绘制。

方法4是使用矩阵matrix绘制Bitmap,绘制前先设置matrix的属性
该方法主要是对图片进行缩放旋转平移等操作时使用
示例:在坐标点(100,100),顺时针旋转45°绘制图片
关键代码:

//配置矩阵
Matrix matrix = new Matrix();
matrix.postTranslate(100f, 100f);
matrix.preRotate(45f);
//绘制       
canvas.drawBitmap(mFaceRectBitmap, matrix, mPaint);

实现效果:
Android:绘制自定义View人脸识别框

五.onDraw()不执行问题

在前文1.2小节里有提到,onDraw()出现不执行问题

实现自定义View时,这也是个常见的问题,一般可以尝试如下几种方法:

  • 主动调用invalidate()
  • 在构造方法里增加setWillNotDraw(false)方法
  • View的宽高是否能被系统确定,如果不能就需要设置确定的宽高,或者修改布局使其能被系统确定
  • 在onMeasure()方法中没设置控件的宽和高
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

六.结束

到此自定义人脸识别框FaceView及drawBitmap()相关扩展就讲解完了

canvas有十分丰富的功能,能实现多种多样的自定义View,这就要在实际开发中去具体运用了文章来源地址https://www.toymoban.com/news/detail-488707.html

到了这里,关于Android:绘制自定义View人脸识别框的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android 对View 进行旋转、缩放、平移的属性变换后,获取外矩形顶点

    来张图 Android View 通过平移、旋转、缩放后,顶点映射 之前写的这个文章,里面用到的是 matrix.mapPoints() 通过 矩形的4个点来映射出新的4个点。 个人以为这就会得到正确的结果。 最近呢,就想着,验证一下这个是不是正确的 验证想法: “基于 变换后的 ltrb,加一个自定义

    2023年04月23日
    浏览(32)
  • Android自定义View之游戏摇杆键盘实现(一),快手android面试经验

    public class RemoteViewBg { private Bitmap bitmapBg; public RemoteViewBg(Bitmap bitmap) { bitmapBg = bitmap; } //背景的绘图函数 public void draw(Canvas canvas, Paint paint, Rect src0 ,Rect dst0 ) { canvas.drawBitmap(bitmapBg, src0, dst0, paint); } } 重写系统的触摸时间,判断触摸点在背景范围内还是背景范围外 @Override public b

    2024年04月12日
    浏览(37)
  • Android基于opencv4.6.0实现人脸识别功能

    步骤: 1.整合opencv 2.获取相机的SurfaceView传到native层去检测(亦或是不断的获取SurfaceView的Bitmap,传到native层) 3.检测人脸,在本地保存人脸特征信息 4.上传至后台(不实现) 人脸识别实现的思路(例:人脸登录) 1.人脸信息录入 1.1获取相机的Bitmap,检测人脸(保证人脸信息比较精准

    2024年02月03日
    浏览(36)
  • Android OpenGL 教程——窗口初始化&绘制矩形

    上节介绍了 Native 工程初始化,但是我们的窗口什么都没有,这节我们将 NativeActivity 创建的 window 绑定到 OpenGL 创建的 display 的 surface 上,并且绘制背景颜色和三角形,通过三角形绘制出一个矩形 初始化 绘制  只需要将三角形的索引改为6个即可 绘制 源码:OpenGLDemo#triangle 你

    2024年02月16日
    浏览(32)
  • 【Android】之【View绘制】

    简单的可以说,如 measure,layout,draw 分别对应测量,布局,绘制三个过程。 ① measure:测量。系统会先根据xml布局文件和代码中对控件属性的设置,来获取或者计算出每个View和ViewGrop的尺寸,并将这些尺寸保存下来。 ② layout:布局。根据测量出的结果以及对应的参数,来确

    2024年02月08日
    浏览(29)
  • Android中的view绘制流程,简单理解

    Android中的View类代表用户界面中基本的构建块。一个View在屏幕中占据一个矩形区域、并且负责绘制和事件处理。View是所有widgets的基础类,widgets是我们通常用于创建和用户交互的组件,比如按钮、文本输入框等等。子类ViewGroup是所有布局(layout)的基础类。layout是一个不看见

    2024年02月09日
    浏览(26)
  • Android中绘制的两个天气相关的View

    开发天气相关软件时候,做了两个自定义View,这里进行记录,由于涉及类较多,这里仅包含核心代码,需要调整后才可以运行,自定义View范围仅包含网格相关UI。需要注意的是横向坐标需要25个数据,来表示一天24小时。最后一个数据表示0点,效果如下: 降雨的效果: 该效果

    2024年02月15日
    浏览(23)
  • uniapp - 安卓|苹果App软件实现调用百度人脸识别接口服务及人脸活体认证功能,uniapp苹果ios、安卓Android手机app平台,人脸认证、活体检测、身份证与人脸验证(示例代码,一键复制

    在uniapp手机App开发中(安卓Android|苹果ios系统),利用百度人脸识别api接口对接uniapp APP进行人脸识别、人脸检测、活体验证、人脸对比、人脸搜索、身份证信息是否与人脸匹配,支持离线SDK集成、离线无网络正常使用功能、自定义人脸识别框附近的页面样式和大小等。 提供详

    2024年04月11日
    浏览(44)
  • Android自定义View流程

    在开发中,View视图具有非常重要的作用,它是直接呈现给使用者的,因此向用户展示精美高效的View视图很有意义。Android系统提供了丰富的视图组件,如TextView、ImageView、Button等,还提供了RelativeLayout、LinearLayout、FrameLayout等组合组件,使用这些组件搭配能实现良好的视图效果

    2024年04月11日
    浏览(33)
  • android 自定义圆角View

    public class CustomView extends View {     private float cornerRadius;     public CustomView(Context context) {         super(context);         init();     }     public CustomView(Context context, AttributeSet attrs) {         super(context, attrs);         TypedArray typedArray = context.obt

    2024年02月11日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包