Today I've added my custom view(face detection) for my android camera app. Everything looked fine, no errors and all. However, I realized that my custom face detection appears only when the camera is in landscape mode. What I want to do is to show face detection view in portrait mode. I searched around the web for some hints but I couldn't find a useful information that can guide me to solve this problem. It would be great if there are some tips or solutions. I would love to hear from you!
I've added the sample code from my app.
(1. I'm adding my Custom view(CameraOverlayView) to the typical xml layout(Relative layout).
mCameraOverlayView = new CameraOverlayView(this, mSurfaceView);
this.addContentView(mCameraOverlayView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
(2. I use CameraOverLayView to show a rectangle in the preview
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. Just running the face detection in the surfaceCreated and in SurfaceChanged.
@Override
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open(currentCamera);
if (currentCamera != Camera.CameraInfo.CAMERA_FACING_FRONT) {
mCamera.setFaceDetectionListener(faceDetectionListener);
mCamera.startFaceDetection();
}
}
[Edited]
code for setting the camera orientation
/**
* 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() is used in the following location
@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
The following layout is the main layout for displaying the camera preview
<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>