今天我为我的Android相机应用程序添加了我的自定义视图(面部检测)。 一切看起来都很好,没有错误。但是,我意识到我的自定义面部检测仅在相机处于横向模式时出现。我想要做的是在纵向模式下显示面部检测视图。 我在网上搜索了一些提示,但我找不到可以指导我解决这个问题的有用信息。如果有一些提示或解决方案会很棒。我很乐意听到你的消息!
我已经从我的应用中添加了示例代码。
(1.我将自定义视图(CameraOverlayView)添加到典型的xml布局(相对布局)。
mCameraOverlayView = new CameraOverlayView(this, mSurfaceView);
this.addContentView(mCameraOverlayView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
(2.我使用CameraOverLayView在预览中显示一个矩形
public class CameraOverlayView extends View {
private Paint mPaint;
private Face[] mFaces;
private SurfaceView mSurfaceView;
public CameraOverlayView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize();
}
public CameraOverlayView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
public CameraOverlayView(Context context, SurfaceView surafaceView) {
super(context);
mSurfaceView = surafaceView;
initialize();
}
private void initialize() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.WHITE);
mPaint.setAlpha(128);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
}
public void setFaces(Face[] faces) {
mFaces = faces;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mFaces == null) {
return;
}
for (Face face : mFaces) {
if (face == null) {
continue;
}
Matrix matrix = new Matrix();
matrix.postScale(mSurfaceView.getWidth() / 2000f, mSurfaceView.getHeight() / 2000f);
matrix.postTranslate(mSurfaceView.getWidth() / 2f, mSurfaceView.getHeight() / 2f);
int saveCount = canvas.save();
canvas.concat(matrix);
canvas.drawRect(face.rect, mPaint);
canvas.restoreToCount(saveCount);
}
}
}
(3。只需在surfaceCreated和SurfaceChanged中运行面部检测。
@Override
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open(currentCamera);
if (currentCamera != Camera.CameraInfo.CAMERA_FACING_FRONT) {
mCamera.setFaceDetectionListener(faceDetectionListener);
mCamera.startFaceDetection();
}
}
[被修改]
设置相机方向的代码
/**
* Camera orientation
*/
public void setCameraDisplayOrientation() {
Camera.CameraInfo info = new Camera.CameraInfo();
mCamera.getCameraInfo(currentCamera, info);
int rotation = this.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
int resultA = 0, resultB = 0;
if(currentCamera == Camera.CameraInfo.CAMERA_FACING_BACK) {
resultA = (info.orientation - degrees + 360) % 360;
resultB = (info.orientation - degrees + 360) % 360;
mCamera.setDisplayOrientation(resultA);
} else {
resultA = (360 + 360 - info.orientation - degrees) % 360;
resultB = (info.orientation + degrees) % 360;
mCamera.setDisplayOrientation(resultA);
}
Camera.Parameters params = mCamera.getParameters();
params.setRotation(resultB);
mCamera.setParameters(params);
mCameraOrientation = resultB;
}
setCameraDisplayOrientation()用于以下位置
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
if (mPreviewRunning) {
mCamera.stopPreview();
}
if (mSurfaceHolder.getSurface() == null){
return;
}
Camera.Parameters p = mCamera.getParameters();
List<String> focusModes = p.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
p.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
p.setFlashMode(currentFlashMode);
mCamera.setParameters(p);
try {
if (mCamera != null) {
mCamera.setPreviewDisplay(arg0);
setCameraDisplayOrientation(); ← Here
以下布局是显示相机预览的主要布局
<RelativeLayout 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=".MainActivity"
>
<SurfaceView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/surfaceView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="false"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="false"
android:visibility="invisible" />
</RelativeLayout>