Zoom photo preview
freakdragon opened this issue · 3 comments
Trying to add slider zoomer to Camera for photos.
Added to CameraController:
float getCurrentZoom();
void setCurrentZoom(float zoom);
float getMaxZoom();
Added to Camera1Controller
@Override
public float getCurrentZoom() {
return cameraManager.getCurrentZoom();
}
@Override
public float getMaxZoom() {
return cameraManager.getMaxZoom();
}
@Override
public void setCurrentZoom(float zoom) {
cameraManager.setCurrentZoom(zoom);
}
Added to Camera2Controller
@Override
public float getCurrentZoom() {
return camera2Manager.getCurrentZoom();
}
@Override
public float getMaxZoom() {
return camera2Manager.getMaxZoom();
}
@Override
public void setCurrentZoom(float zoom) {
camera2Manager.setCurrentZoom(zoom);
}
Added to CameraManager
float getCurrentZoom();
void setCurrentZoom(float zoom);
float getMaxZoom();
Added to AnncaCameraActivity
protected float getCurrentZoom() {
return getCameraController().getCurrentZoom();
}
protected float getMaxZoom() {
return getCameraController().getMaxZoom();
}
protected void setCurrentZoom(float zoom) {
getCameraController().setCurrentZoom(zoom);
}
I'm getting value of it by max zoom of camera1
Camera.Parameters parameter = camera.getParameters();
if(parameter.isZoomSupported()) {
return parameter.getMaxZoom();
}
and camera2
(manager.getCameraCharacteristics(this.currentCameraId).get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM))*10
SeekBar impementation:
minZoom = getMinZoom();
maxZoom = getMaxZoom() - 1;
final int step = 1;
seekBarBottom.setMax(Math.round(maxZoom - minZoom));
seekBarBottom.setOnSeekBarChangeListener(
new SeekBar.OnSeekBarChangeListener()
{
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
setCurrentZoom(Math.round(minZoom + (progress * step)));
}
}
);
I've added to Camera1Manager
public void setCurrentZoom(float zoom) {
Camera.Parameters parameter = camera.getParameters();
if(getCurrentZoom() < getMaxZoom()) {
parameter.setZoom(Math.round(zoom));
camera.setParameters(parameter);
}
}
Works fine.
I've added to Camera2Manager
protected int zoomLevel = 1;
public void setCurrentZoom(float zoomLevel) {
try {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(this.currentCameraId);
float maxZoom = (characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM))*10;
Rect m = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
if((zoomLevel <= maxZoom) && (zoomLevel > 1)) {
int minW = (int) (m.width() / maxZoom);
int minH = (int) (m.height() / maxZoom);
int difW = m.width() - minW;
int difH = m.height() - minH;
int cropW = difW / 100 * (int) zoomLevel;
int cropH = difH / 100 * (int) zoomLevel;
cropW -= cropW & 3;
cropH -= cropH & 3;
Rect zoom = new Rect(cropW, cropH, m.width() - cropW, m.height() - cropH);
try {
previewRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoom);
captureSession.capture(previewRequestBuilder.build(), captureCallback, backgroundHandler);
} catch (Exception e) {
Log.e(TAG, "Error updating preview: ", e);
}
this.zoomLevel = (int) zoomLevel;
}
} catch (Exception e) {
Log.e(TAG, "Error during camera init");
}
}
It zooms but immediately returns to normal state. Is there some listener that changes its state back?
changed
captureSession.capture(previewRequestBuilder.build(), captureCallback, backgroundHandler);
to
captureSession.setRepeatingRequest(previewRequestBuilder.build(), captureCallback, backgroundHandler);
and it worked.
Now I'm fighting with zoom. It doesn't crop zoomed image. I'll write again, if I'll gain a victory
Hi, I'll take a look, thank you for reporting.
changed function in Camera2Manager to
@Override
public void setCurrentZoom(float zoomLevel) {
Rect zoomRect = getZoomRect(zoomLevel);
if(zoomRect != null) {
try {
previewRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoomRect);
captureSession.setRepeatingRequest(previewRequestBuilder.build(), captureCallback, backgroundHandler);
} catch (Exception e) {
Log.e(TAG, "Error updating preview: ", e);
}
this.zoomLevel = (int) zoomLevel;
}
}
private Rect getZoomRect(float zoomLevel) {
try {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(this.currentCameraId);
float maxZoom = (characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM)) * 10;
Rect activeRect = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
if((zoomLevel <= maxZoom) && (zoomLevel > 1)) {
int minW = (int) (activeRect.width() / maxZoom);
int minH = (int) (activeRect.height() / maxZoom);
int difW = activeRect.width() - minW;
int difH = activeRect.height() - minH;
int cropW = difW / 100 * (int) zoomLevel;
int cropH = difH / 100 * (int) zoomLevel;
cropW -= cropW & 3;
cropH -= cropH & 3;
return new Rect(cropW, cropH, activeRect.width() - cropW, activeRect.height() - cropH);
} else if(zoomLevel == 0){
return new Rect(0, 0, activeRect.width(), activeRect.height());
}
return null;
} catch (Exception e) {
Log.e(TAG, "Error during camera init");
return null;
}
}
and added cropping to CaptureStillPicture() function in Camera2Manager
private void captureStillPicture() {
try {
if (null == cameraDevice) {
return;
}
final CaptureRequest.Builder captureBuilder =
cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(imageReader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getPhotoOrientation(configurationProvider.getSensorPosition()));
Rect zoomRect = getZoomRect(zoomLevel);
if(zoomRect == null) {
zoomRect = getZoomRect(0);
}
captureBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoomRect);
CameraCaptureSession.CaptureCallback CaptureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
Log.d(TAG, "onCaptureCompleted: ");
}
};
captureSession.stopRepeating();
captureSession.capture(captureBuilder.build(), CaptureCallback, null);
setCurrentZoom(0);
} catch (CameraAccessException e) {
Log.e(TAG, "Error during capturing picture");
}
}
Works fine with photos (didn't try with video). Check it. And add zooming to this library if you want.
P.S. I'm setting zoom to 0, because zoom resets after taking photo. And that's why after take photo I'm setting my zoom seekbar's progress to 0 too. Don't know why it's so.