繁体   English   中英

使用 Camera2 API 设置相机变焦

[英]Camera zoom setting using Camera2 API

我正在尝试使用新的 Camera2 API 来访问相机设置并应用缩放。 在旧的不推荐使用的 Camera 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_FACTORmaxZoom之间。

调用setZoom 后,要使新缩放处于活动状态,您仍然需要使用重复请求将其发送到当前的CameraCaptureSession

计算新缩放系数的代码段:

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,我将尝试解释范式转换。

在camera1 API中,zoom是一个简单的中心裁剪缩放,大概是这样的: 在此处输入图片说明

就像您看到的那样,api 只是简单地裁剪到框架的中心并将结果缩放到屏幕上。 这就是 Android 定义应用程序和供应商 HAL API 的方式。 供应商 HAL 将简单地获取缩放级别并自行计算裁剪值,而 android 框架仅将缩放值传递给相机 HAL。

在 Camera2 api 中,这更灵活,您可以裁剪框架的任何部分,然后进行缩放。 所以基本上使用camera2 api是可能的: 在此处输入图片说明

观察内部矩形如何不居中。 使用 camera1 api 无法做到这一点。

虽然这对应用程序开发人员来说是一个很好的灵活性,但我认为 android 也可以为 camera2 CaptureRequest 中的直接用例提供一个与 camera1 等效的键。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM