With Legacy Camera API (android.hardware.Camera
) I can get the current zoom level using next lines
Camera.Parameters p = mCamera.getParameters();
int zoom = p.getZoomRatios().get(p.getZoom());
How can I do it with Camera2 API (android.hardware.camera2
)?
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
...
I've found that the easiest way to know the current zoom is actually to keep track of it whenever changing it.
The next zoom controller can be used for both computing a new zoom and getting the current zoom which is in fact only a cached value that is passed to the .set() method:
public final class Zoom
{
private static final float DEFAULT_ZOOM_FACTOR = 1.0f;
@NonNull
private final Rect mCropRegion = new Rect();
public final float maxZoom;
private float mCurrentZoomFactor = Zoom.DEFAULT_ZOOM_FACTOR;
@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 set(@NonNull final CaptureRequest.Builder builder, final float newZoom)
{
if (this.hasSupport == false)
{
return;
}
this.mCurrentZoomFactor = MathUtils.clamp(newZoom, 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()) / this.mCurrentZoomFactor);
final int deltaY = (int)((0.5f * this.mSensorSize.height()) / this.mCurrentZoomFactor);
this.mCropRegion.set(centerX - deltaX,
centerY - deltaY,
centerX + deltaX,
centerY + deltaY);
builder.set(CaptureRequest.SCALER_CROP_REGION, this.mCropRegion);
}
public float get()
{
return this.mCurrentZoomFactor;
}
}
After calling zoom.set(...), use the next snippet in order to commit and make effective the new zoom factor into the active camera session. It needs to be done for both the active preview session, and then the capture session whenever taking a photo:
yourCameraSession.setRepeatingRequest(builder.build(), yourPreviewOrCaptureSessionCallback, yourCameraThreadHandler);