使用 Camera2 API 的相机缩放设置
Camera zoom setting using Camera2 API
我正在尝试使用新的 Camera2 API 访问相机设置并应用缩放。
在旧的弃用相机 API 中,代码如下:
Camera.Parameters parameters = mCamera.getParameters();
parameters.setZoom(zoomValue);
mCamera.setParameters(parameters);
考虑到 CameraManager,我们如何才能达到同样的效果
是用来开摄像头的?
CameraManager.openCamera(cameraId, stateCallback, backgroundHandler);
使用下一个代码。使用您的目标 CaptureRequest.Builder 调用 setZoom,以便在需要时使用预览或图片跟踪生成器。
使用 maxZoom 获取您的 UI 应该计算缩放范围的阈值。
缩放范围将始终在 DEFAULT_ZOOM_FACTOR 和 maxZoom.
之间
调用 setZoom 后,要激活新的缩放功能,您仍然需要使用 重复请求[=] 将其发送到当前 CameraCaptureSession 30=].
计算新缩放因子的代码段:
public final class Zoom
{
private static final float DEFAULT_ZOOM_FACTOR = 1.0f;
@NonNull
private final Rect mCropRegion = new Rect();
public final float maxZoom;
@Nullable
private final Rect mSensorSize;
public final boolean hasSupport;
public Zoom(@NonNull final CameraCharacteristics characteristics)
{
this.mSensorSize = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
if (this.mSensorSize == null)
{
this.maxZoom = Zoom.DEFAULT_ZOOM_FACTOR;
this.hasSupport = false;
return;
}
final Float value = characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
this.maxZoom = ((value == null) || (value < Zoom.DEFAULT_ZOOM_FACTOR))
? Zoom.DEFAULT_ZOOM_FACTOR
: value;
this.hasSupport = (Float.compare(this.maxZoom, Zoom.DEFAULT_ZOOM_FACTOR) > 0);
}
public void setZoom(@NonNull final CaptureRequest.Builder builder, final float zoom)
{
if (this.hasSupport == false)
{
return;
}
final float newZoom = MathUtils.clamp(zoom, Zoom.DEFAULT_ZOOM_FACTOR, this.maxZoom);
final int centerX = this.mSensorSize.width() / 2;
final int centerY = this.mSensorSize.height() / 2;
final int deltaX = (int)((0.5f * this.mSensorSize.width()) / newZoom);
final int deltaY = (int)((0.5f * this.mSensorSize.height()) / newZoom);
this.mCropRegion.set(centerX - deltaX,
centerY - deltaY,
centerX + deltaX,
centerY + deltaY);
builder.set(CaptureRequest.SCALER_CROP_REGION, this.mCropRegion);
}
}
应用新计算缩放的代码段:
yourCameraSession.setRepeatingRequest(builder.build(), yourPreviewOrCaptureSessionCallback, yourCameraThreadHandler);
既然 PerraCollabs@ 已经提到如何使用 api,我将尝试解释范式转变。
在camera1API中,zoom是一个简单的center crop zoom,大概是这样的:
如您所见,api 只是裁剪到框架的中心并将结果缩放到屏幕。这就是 Android 定义应用程序和供应商 HAL API 的方式。供应商 HAL 将简单地获取缩放级别并自行计算裁剪值,而 android 框架只是将缩放值传递给相机 HAL。
在 Camera2 api 中,这更灵活,因为您可以裁剪画面的任何部分,然后进行缩放。所以本质上使用 camera2 api 类似的东西是可能的:
观察内部矩形如何不居中。使用 camera1 api.
无法完成此操作
虽然这对应用程序开发人员来说是一个很好的灵活性,但我认为 android 也可以为 camera2 CaptureRequest 中的直接用例提供 camera1 等效密钥。
我正在尝试使用新的 Camera2 API 访问相机设置并应用缩放。 在旧的弃用相机 API 中,代码如下:
Camera.Parameters parameters = mCamera.getParameters();
parameters.setZoom(zoomValue);
mCamera.setParameters(parameters);
考虑到 CameraManager,我们如何才能达到同样的效果 是用来开摄像头的?
CameraManager.openCamera(cameraId, stateCallback, backgroundHandler);
使用下一个代码。使用您的目标 CaptureRequest.Builder 调用 setZoom,以便在需要时使用预览或图片跟踪生成器。
使用 maxZoom 获取您的 UI 应该计算缩放范围的阈值。 缩放范围将始终在 DEFAULT_ZOOM_FACTOR 和 maxZoom.
之间调用 setZoom 后,要激活新的缩放功能,您仍然需要使用 重复请求[=] 将其发送到当前 CameraCaptureSession 30=].
计算新缩放因子的代码段:
public final class Zoom
{
private static final float DEFAULT_ZOOM_FACTOR = 1.0f;
@NonNull
private final Rect mCropRegion = new Rect();
public final float maxZoom;
@Nullable
private final Rect mSensorSize;
public final boolean hasSupport;
public Zoom(@NonNull final CameraCharacteristics characteristics)
{
this.mSensorSize = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
if (this.mSensorSize == null)
{
this.maxZoom = Zoom.DEFAULT_ZOOM_FACTOR;
this.hasSupport = false;
return;
}
final Float value = characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
this.maxZoom = ((value == null) || (value < Zoom.DEFAULT_ZOOM_FACTOR))
? Zoom.DEFAULT_ZOOM_FACTOR
: value;
this.hasSupport = (Float.compare(this.maxZoom, Zoom.DEFAULT_ZOOM_FACTOR) > 0);
}
public void setZoom(@NonNull final CaptureRequest.Builder builder, final float zoom)
{
if (this.hasSupport == false)
{
return;
}
final float newZoom = MathUtils.clamp(zoom, Zoom.DEFAULT_ZOOM_FACTOR, this.maxZoom);
final int centerX = this.mSensorSize.width() / 2;
final int centerY = this.mSensorSize.height() / 2;
final int deltaX = (int)((0.5f * this.mSensorSize.width()) / newZoom);
final int deltaY = (int)((0.5f * this.mSensorSize.height()) / newZoom);
this.mCropRegion.set(centerX - deltaX,
centerY - deltaY,
centerX + deltaX,
centerY + deltaY);
builder.set(CaptureRequest.SCALER_CROP_REGION, this.mCropRegion);
}
}
应用新计算缩放的代码段:
yourCameraSession.setRepeatingRequest(builder.build(), yourPreviewOrCaptureSessionCallback, yourCameraThreadHandler);
既然 PerraCollabs@ 已经提到如何使用 api,我将尝试解释范式转变。
在camera1API中,zoom是一个简单的center crop zoom,大概是这样的:
如您所见,api 只是裁剪到框架的中心并将结果缩放到屏幕。这就是 Android 定义应用程序和供应商 HAL API 的方式。供应商 HAL 将简单地获取缩放级别并自行计算裁剪值,而 android 框架只是将缩放值传递给相机 HAL。
在 Camera2 api 中,这更灵活,因为您可以裁剪画面的任何部分,然后进行缩放。所以本质上使用 camera2 api 类似的东西是可能的:
观察内部矩形如何不居中。使用 camera1 api.
无法完成此操作虽然这对应用程序开发人员来说是一个很好的灵活性,但我认为 android 也可以为 camera2 CaptureRequest 中的直接用例提供 camera1 等效密钥。