android.jpg
前言
本篇文章是在上篇文章的基础之上,在预览的时使用Camera2自带的人脸检测功能实时检测人脸位置,并通过一个自定义view显示在预览画面上
实现思路
布局中使用 AutoFitTextureView 代替 TextureView。AutoFitTextureView 继承自 TextureView,能够根据传入的宽高值调整自身大小。目的是使预览画面不变形,否则在人脸坐标转换的时候会出现比较大的误差,这个后文中会提到
在创建预览会话的时候,开启人脸检测
在预览会话的状态回调中可以得到检测到的人脸信息
将检测到的人脸坐标进行相应的转换,并传递给FaceView
自定义一个FaceView,接收人脸位置并实时绘制出来
具体实现步骤
注: 由于本文是在上篇文章基础之上,故省略了很多相同的代码,完整代码在文末给出
一、定义一个AutoFitTextureView,并在布局中使用
/**
* A {@link TextureView} that can be adjusted to a specified aspect ratio.
*/
public class AutoFitTextureView extends TextureView {
private int mRatioWidth = 0;
private int mRatioHeight = 0;
public AutoFitTextureView(Context context) {
this(context, null);
}
public AutoFitTextureView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
* calculated from the parameters. Note that the actual sizes of parameters don't matter, that
* is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
*
* @param width Relative horizontal size
* @param height Relative vertical size
*/
public void setAspectRatio(int width, int height) {
if (width < 0 || height < 0) {
throw new IllegalArgumentException("Size cannot be negative.");
}
mRatioWidth = width;
mRatioHeight = height;
requestLayout();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
if (0 == mRatioWidth || 0 == mRatioHeight) {
setMeasuredDimension(width, height);
} else {
if (width < height * mRatioWidth / mRatioHeight) {