Camera2 前置摄像头预览旋转
Camera2 front camera preview rotation
我正在使用 camera2,但遇到了旋转问题。
在某些设备中,当切换到前置摄像头时,预览会旋转 180 度。
正在寻找 camera2 的 "setDefaultOrientation()" 方法,但找不到。
谢谢
你可以试试这个密码来打开你的相机
希望对您有所帮助
public void startPreview() {
try {
Log.i(TAG, "starting preview: " + started);
// ....
Camera.CameraInfo camInfo = new Camera.CameraInfo();
Camera.getCameraInfo(cameraIndex, camInfo);
int cameraRotationOffset = camInfo.orientation;
// ...
Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
Camera.Size previewSize = null;
float closestRatio = Float.MAX_VALUE;
int targetPreviewWidth = isLandscape() ? getWidth() : getHeight();
int targetPreviewHeight = isLandscape() ? getHeight() : getWidth();
float targetRatio = targetPreviewWidth / (float) targetPreviewHeight;
Log.v(TAG, "target size: " + targetPreviewWidth + " / " + targetPreviewHeight + " ratio:" + targetRatio);
for (Camera.Size candidateSize : previewSizes) {
float whRatio = candidateSize.width / (float) candidateSize.height;
if (previewSize == null || Math.abs(targetRatio - whRatio) < Math.abs(targetRatio - closestRatio)) {
closestRatio = whRatio;
previewSize = candidateSize;
}
}
int rotation = getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break; // Natural orientation
case Surface.ROTATION_90:
degrees = 90;
break; // Landscape left
case Surface.ROTATION_180:
degrees = 180;
break;// Upside down
case Surface.ROTATION_270:
degrees = 270;
break;// Landscape right
}
int displayRotation;
if (isFrontFacingCam) {
displayRotation = (cameraRotationOffset + degrees) % 360;
displayRotation = (360 - displayRotation) % 360; // compensate
// the
// mirror
} else { // back-facing
displayRotation = (cameraRotationOffset - degrees + 360) % 360;
}
Log.v(TAG, "rotation cam / phone = displayRotation: " + cameraRotationOffset + " / " + degrees + " = "
+ displayRotation);
this.camera.setDisplayOrientation(displayRotation);
int rotate;
if (isFrontFacingCam) {
rotate = (360 + cameraRotationOffset + degrees) % 360;
} else {
rotate = (360 + cameraRotationOffset - degrees) % 360;
}
Log.v(TAG, "screenshot rotation: " + cameraRotationOffset + " / " + degrees + " = " + rotate);
Log.v(TAG, "preview size: " + previewSize.width + " / " + previewSize.height);
parameters.setPreviewSize(previewSize.width, previewSize.height);
parameters.setRotation(rotate);
camera.setParameters(parameters);
camera.setPreviewDisplay(mHolder);
camera.startPreview();
Log.d(TAG, "preview started");
started = true;
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
您可以在 CaptureRequest
对象中设置正确的图像旋转,同时使用 CameraCharacterisitics
在 CameraCaptureSession.StateCallback
中捕获图像
CameraCharacterisitics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
像这样。
private CameraCaptureSession.StateCallback sessionStateCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
captureSession = session;
try {
CaptureRequest.Builder builder = session.getDevice().createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
builder.addTarget(imageReader.getSurface());
builder.set(CaptureRequest.JPEG_ORIENTATION, cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION));
session.capture(builder.build(), null, backgroundHandler);
} catch (CameraAccessException e) {
Log.d("tag", e.getMessage());
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
}
};
对于 GLSurfaceView,您大概是在使用 SurfaceTexture 将相机预览流映射到 GL 纹理,然后进行渲染。
纹理中的图像数据不会自动旋转为 'upright' - 首先,OS 无法知道您将如何渲染纹理。
但是,SurfaceTexture 有一个 getTransformMatrix 调用,当它连接到 camera2 API 时,将为您提供从相机方向到设备 native[ 的必要转换=18=] 方向(通常手机为纵向,平板电脑为横向,但并非总是如此)。然后,您必须将从本机方向到应用程序方向的变换添加到此矩阵,然后应用组合矩阵变换来调整预览图像。
我正在使用 camera2,但遇到了旋转问题。 在某些设备中,当切换到前置摄像头时,预览会旋转 180 度。 正在寻找 camera2 的 "setDefaultOrientation()" 方法,但找不到。
谢谢
你可以试试这个密码来打开你的相机
希望对您有所帮助
public void startPreview() {
try {
Log.i(TAG, "starting preview: " + started);
// ....
Camera.CameraInfo camInfo = new Camera.CameraInfo();
Camera.getCameraInfo(cameraIndex, camInfo);
int cameraRotationOffset = camInfo.orientation;
// ...
Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
Camera.Size previewSize = null;
float closestRatio = Float.MAX_VALUE;
int targetPreviewWidth = isLandscape() ? getWidth() : getHeight();
int targetPreviewHeight = isLandscape() ? getHeight() : getWidth();
float targetRatio = targetPreviewWidth / (float) targetPreviewHeight;
Log.v(TAG, "target size: " + targetPreviewWidth + " / " + targetPreviewHeight + " ratio:" + targetRatio);
for (Camera.Size candidateSize : previewSizes) {
float whRatio = candidateSize.width / (float) candidateSize.height;
if (previewSize == null || Math.abs(targetRatio - whRatio) < Math.abs(targetRatio - closestRatio)) {
closestRatio = whRatio;
previewSize = candidateSize;
}
}
int rotation = getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break; // Natural orientation
case Surface.ROTATION_90:
degrees = 90;
break; // Landscape left
case Surface.ROTATION_180:
degrees = 180;
break;// Upside down
case Surface.ROTATION_270:
degrees = 270;
break;// Landscape right
}
int displayRotation;
if (isFrontFacingCam) {
displayRotation = (cameraRotationOffset + degrees) % 360;
displayRotation = (360 - displayRotation) % 360; // compensate
// the
// mirror
} else { // back-facing
displayRotation = (cameraRotationOffset - degrees + 360) % 360;
}
Log.v(TAG, "rotation cam / phone = displayRotation: " + cameraRotationOffset + " / " + degrees + " = "
+ displayRotation);
this.camera.setDisplayOrientation(displayRotation);
int rotate;
if (isFrontFacingCam) {
rotate = (360 + cameraRotationOffset + degrees) % 360;
} else {
rotate = (360 + cameraRotationOffset - degrees) % 360;
}
Log.v(TAG, "screenshot rotation: " + cameraRotationOffset + " / " + degrees + " = " + rotate);
Log.v(TAG, "preview size: " + previewSize.width + " / " + previewSize.height);
parameters.setPreviewSize(previewSize.width, previewSize.height);
parameters.setRotation(rotate);
camera.setParameters(parameters);
camera.setPreviewDisplay(mHolder);
camera.startPreview();
Log.d(TAG, "preview started");
started = true;
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
您可以在 CaptureRequest
对象中设置正确的图像旋转,同时使用 CameraCharacterisitics
CameraCaptureSession.StateCallback
中捕获图像
CameraCharacterisitics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
像这样。
private CameraCaptureSession.StateCallback sessionStateCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
captureSession = session;
try {
CaptureRequest.Builder builder = session.getDevice().createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
builder.addTarget(imageReader.getSurface());
builder.set(CaptureRequest.JPEG_ORIENTATION, cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION));
session.capture(builder.build(), null, backgroundHandler);
} catch (CameraAccessException e) {
Log.d("tag", e.getMessage());
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
}
};
对于 GLSurfaceView,您大概是在使用 SurfaceTexture 将相机预览流映射到 GL 纹理,然后进行渲染。
纹理中的图像数据不会自动旋转为 'upright' - 首先,OS 无法知道您将如何渲染纹理。
但是,SurfaceTexture 有一个 getTransformMatrix 调用,当它连接到 camera2 API 时,将为您提供从相机方向到设备 native[ 的必要转换=18=] 方向(通常手机为纵向,平板电脑为横向,但并非总是如此)。然后,您必须将从本机方向到应用程序方向的变换添加到此矩阵,然后应用组合矩阵变换来调整预览图像。