fix(android): use device orientation for images/videos instead of display orientation (#1992)

* fix(android): use device orientation for images/videos instead of display orientation

* fix(android): landscape rotation
This commit is contained in:
Laurin Quast 2018-12-13 21:16:56 +01:00 committed by Sibelius Seraphini
parent cc8338565b
commit 513bfe860b
5 changed files with 72 additions and 19 deletions

View File

@ -98,6 +98,8 @@ class Camera1 extends CameraViewImpl implements MediaRecorder.OnInfoListener,
private int mDisplayOrientation;
private int mDeviceOrientation;
private int mOrientation = Constants.ORIENTATION_AUTO;
private float mZoom;
@ -156,7 +158,7 @@ class Camera1 extends CameraViewImpl implements MediaRecorder.OnInfoListener,
mMediaRecorder = null;
if (mIsRecording) {
int deviceOrientation = displayOrientationToOrientationEnum(mDisplayOrientation);
int deviceOrientation = displayOrientationToOrientationEnum(mDeviceOrientation);
mCallback.onVideoRecorded(mVideoPath, mOrientation != Constants.ORIENTATION_AUTO ? mOrientation : deviceOrientation, deviceOrientation);
mIsRecording = false;
}
@ -436,7 +438,7 @@ class Camera1 extends CameraViewImpl implements MediaRecorder.OnInfoListener,
void takePictureInternal(final ReadableMap options) {
if (!isPictureCaptureInProgress.getAndSet(true)) {
if (options.hasKey("orientation")) {
if (options.hasKey("orientation") && options.getInt("orientation") != Constants.ORIENTATION_AUTO) {
mOrientation = options.getInt("orientation");
int rotation = orientationEnumToRotation(mOrientation);
mCameraParameters.setRotation(calcCameraRotation(rotation));
@ -461,7 +463,7 @@ class Camera1 extends CameraViewImpl implements MediaRecorder.OnInfoListener,
}
mOrientation = Constants.ORIENTATION_AUTO;
mCallback.onPictureTaken(data, displayOrientationToOrientationEnum(mDisplayOrientation));
mCallback.onPictureTaken(data, displayOrientationToOrientationEnum(mDeviceOrientation));
}
});
}
@ -503,9 +505,7 @@ class Camera1 extends CameraViewImpl implements MediaRecorder.OnInfoListener,
return;
}
mDisplayOrientation = displayOrientation;
if (isCameraOpened() && mOrientation == Constants.ORIENTATION_AUTO) {
mCameraParameters.setRotation(calcCameraRotation(displayOrientation));
mCamera.setParameters(mCameraParameters);
if (isCameraOpened()) {
final boolean needsToStopPreview = mShowingPreview && Build.VERSION.SDK_INT < 14;
if (needsToStopPreview) {
mCamera.stopPreview();
@ -518,6 +518,18 @@ class Camera1 extends CameraViewImpl implements MediaRecorder.OnInfoListener,
}
}
@Override
void setDeviceOrientation(int deviceOrientation) {
if (mDeviceOrientation == deviceOrientation) {
return;
}
mDeviceOrientation = deviceOrientation;
if (isCameraOpened() && mOrientation == Constants.ORIENTATION_AUTO) {
mCameraParameters.setRotation(calcCameraRotation(deviceOrientation));
mCamera.setParameters(mCameraParameters);
}
}
@Override
public void setPreviewTexture(SurfaceTexture surfaceTexture) {
try {
@ -624,7 +636,7 @@ class Camera1 extends CameraViewImpl implements MediaRecorder.OnInfoListener,
if (mOrientation != Constants.ORIENTATION_AUTO) {
mCameraParameters.setRotation(calcCameraRotation(orientationEnumToRotation(mOrientation)));
} else {
mCameraParameters.setRotation(calcCameraRotation(mDisplayOrientation));
mCameraParameters.setRotation(calcCameraRotation(mDeviceOrientation));
}
setAutoFocusInternal(mAutoFocus);
@ -706,12 +718,12 @@ class Camera1 extends CameraViewImpl implements MediaRecorder.OnInfoListener,
* @return Number of degrees to rotate image in order for it to view correctly.
*/
private int calcCameraRotation(int screenOrientationDegrees) {
if (mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
return (mCameraInfo.orientation + screenOrientationDegrees) % 360;
} else { // back-facing
final int landscapeFlip = isLandscape(screenOrientationDegrees) ? 180 : 0;
return (mCameraInfo.orientation + screenOrientationDegrees + landscapeFlip) % 360;
}
if (mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
return (mCameraInfo.orientation + screenOrientationDegrees) % 360;
}
// back-facing
final int landscapeFlip = isLandscape(screenOrientationDegrees) ? 180 : 0;
return (mCameraInfo.orientation + screenOrientationDegrees + landscapeFlip) % 360;
}
/**
@ -824,7 +836,7 @@ class Camera1 extends CameraViewImpl implements MediaRecorder.OnInfoListener,
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Camera.Size previewSize = mCameraParameters.getPreviewSize();
mCallback.onFramePreview(data, previewSize.width, previewSize.height, mDisplayOrientation);
mCallback.onFramePreview(data, previewSize.width, previewSize.height, mDeviceOrientation);
}
private void setUpMediaRecorder(String path, int maxDuration, int maxFileSize, boolean recordAudio, CamcorderProfile profile) {
@ -847,7 +859,7 @@ class Camera1 extends CameraViewImpl implements MediaRecorder.OnInfoListener,
setCamcorderProfile(CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_HIGH), recordAudio);
}
mMediaRecorder.setOrientationHint(calcCameraRotation(mOrientation != Constants.ORIENTATION_AUTO ? orientationEnumToRotation(mOrientation) : mDisplayOrientation));
mMediaRecorder.setOrientationHint(calcCameraRotation(mOrientation != Constants.ORIENTATION_AUTO ? orientationEnumToRotation(mOrientation) : mDeviceOrientation));
if (maxDuration != -1) {
mMediaRecorder.setMaxDuration(maxDuration);
@ -873,7 +885,7 @@ class Camera1 extends CameraViewImpl implements MediaRecorder.OnInfoListener,
mMediaRecorder = null;
}
int deviceOrientation = displayOrientationToOrientationEnum(mDisplayOrientation);
int deviceOrientation = displayOrientationToOrientationEnum(mDeviceOrientation);
if (mVideoPath == null || !new File(mVideoPath).exists()) {
mCallback.onVideoRecorded(null, mOrientation != Constants.ORIENTATION_AUTO ? mOrientation : deviceOrientation, deviceOrientation);
return;

View File

@ -233,6 +233,8 @@ class Camera2 extends CameraViewImpl implements MediaRecorder.OnInfoListener, Me
private int mDisplayOrientation;
private int mDeviceOrientation;
private float mFocusDepth;
private float mZoom;
@ -618,6 +620,13 @@ class Camera2 extends CameraViewImpl implements MediaRecorder.OnInfoListener, Me
mPreview.setDisplayOrientation(mDisplayOrientation);
}
@Override
void setDeviceOrientation(int deviceOrientation) {
mDeviceOrientation = deviceOrientation;
mPreview.setDisplayOrientation(mDeviceOrientation);
}
/**
* <p>Chooses a camera ID by the specified camera facing ({@link #mFacing}).</p>
* <p>This rewrites {@link #mCameraId}, {@link #mCameraCharacteristics}, and optionally

View File

@ -119,8 +119,9 @@ public class CameraView extends FrameLayout {
// Display orientation detector
mDisplayOrientationDetector = new DisplayOrientationDetector(context) {
@Override
public void onDisplayOrientationChanged(int displayOrientation) {
public void onDisplayOrientationChanged(int displayOrientation, int deviceOrientation) {
mImpl.setDisplayOrientation(displayOrientation);
mImpl.setDeviceOrientation(deviceOrientation);
}
};
}

View File

@ -85,6 +85,8 @@ abstract class CameraViewImpl {
abstract void setDisplayOrientation(int displayOrientation);
abstract void setDeviceOrientation(int deviceOrientation);
abstract void setFocusDepth(float value);
abstract float getFocusDepth();

View File

@ -44,6 +44,8 @@ abstract class DisplayOrientationDetector {
private int mLastKnownDisplayOrientation = 0;
private int mLastKnownDeviceOrientation = 0;
public DisplayOrientationDetector(Context context) {
mOrientationEventListener = new OrientationEventListener(context) {
@ -56,9 +58,35 @@ abstract class DisplayOrientationDetector {
mDisplay == null) {
return;
}
boolean hasChanged = false;
/** set device orientation */
final int deviceOrientation;
if (orientation > 315 || orientation < 45) {
deviceOrientation = 0;
} else if (orientation > 45 && orientation < 135) {
deviceOrientation = 90;
} else if (orientation > 135 && orientation < 225) {
deviceOrientation = 180;
} else if (orientation > 225 && orientation < 315) {
deviceOrientation = 270;
} else {
deviceOrientation = 0;
}
if (mLastKnownDeviceOrientation != deviceOrientation) {
mLastKnownDeviceOrientation = deviceOrientation;
hasChanged = true;
}
/** set screen orientation */
final int rotation = mDisplay.getRotation();
if (mLastKnownRotation != rotation) {
mLastKnownRotation = rotation;
hasChanged = true;
}
if (hasChanged) {
dispatchOnDisplayOrientationChanged(DISPLAY_ORIENTATIONS.get(rotation));
}
}
@ -83,14 +111,15 @@ abstract class DisplayOrientationDetector {
void dispatchOnDisplayOrientationChanged(int displayOrientation) {
mLastKnownDisplayOrientation = displayOrientation;
onDisplayOrientationChanged(displayOrientation);
onDisplayOrientationChanged(displayOrientation, mLastKnownDeviceOrientation);
}
/**
* Called when display orientation is changed.
*
* @param displayOrientation One of 0, 90, 180, and 270.
* @param deviceOrientation One of 0, 90, 180, and 270.
*/
public abstract void onDisplayOrientationChanged(int displayOrientation);
public abstract void onDisplayOrientationChanged(int displayOrientation, int deviceOrientation);
}