Skip to content

Commit

Permalink
Merge pull request #85 from Fotoapparat/feature/zoom
Browse files Browse the repository at this point in the history
Zoom
  • Loading branch information
dmitry-zaitsev authored Aug 26, 2017
2 parents da7ebf7 + d32dfc7 commit c7c0173
Show file tree
Hide file tree
Showing 19 changed files with 353 additions and 24 deletions.
31 changes: 29 additions & 2 deletions fotoapparat/src/main/java/io/fotoapparat/Fotoapparat.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.fotoapparat;

import android.content.Context;
import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;

import java.util.concurrent.Executor;
Expand Down Expand Up @@ -28,6 +29,7 @@
import io.fotoapparat.routine.focus.AutoFocusRoutine;
import io.fotoapparat.routine.parameter.UpdateParametersRoutine;
import io.fotoapparat.routine.picture.TakePictureRoutine;
import io.fotoapparat.routine.zoom.UpdateZoomLevelRoutine;

/**
* Camera. Takes pictures.
Expand All @@ -45,6 +47,7 @@ public class Fotoapparat {
private final AutoFocusRoutine autoFocusRoutine;
private final CheckAvailabilityRoutine checkAvailabilityRoutine;
private final UpdateParametersRoutine updateParametersRoutine;
private final UpdateZoomLevelRoutine updateZoomLevelRoutine;
private final Executor executor;

private boolean started = false;
Expand All @@ -58,6 +61,7 @@ public class Fotoapparat {
AutoFocusRoutine autoFocusRoutine,
CheckAvailabilityRoutine checkAvailabilityRoutine,
UpdateParametersRoutine updateParametersRoutine,
UpdateZoomLevelRoutine updateZoomLevelRoutine,
Executor executor) {
this.startCameraRoutine = startCameraRoutine;
this.stopCameraRoutine = stopCameraRoutine;
Expand All @@ -68,6 +72,7 @@ public class Fotoapparat {
this.autoFocusRoutine = autoFocusRoutine;
this.checkAvailabilityRoutine = checkAvailabilityRoutine;
this.updateParametersRoutine = updateParametersRoutine;
this.updateZoomLevelRoutine = updateZoomLevelRoutine;
this.executor = executor;
}

Expand Down Expand Up @@ -151,6 +156,10 @@ static Fotoapparat create(FotoapparatBuilder builder) {
cameraDevice
);

UpdateZoomLevelRoutine updateZoomLevelRoutine = new UpdateZoomLevelRoutine(
cameraDevice
);

return new Fotoapparat(
startCameraRoutine,
stopCameraRoutine,
Expand All @@ -161,6 +170,7 @@ static Fotoapparat create(FotoapparatBuilder builder) {
autoFocusRoutine,
checkAvailabilityRoutine,
updateParametersRoutine,
updateZoomLevelRoutine,
SERIAL_EXECUTOR
);
}
Expand Down Expand Up @@ -216,8 +226,7 @@ public PendingResult<FocusResult> focus() {
}

/**
* Asynchronously updates parameters of the camera. Must be called only after
* {@link Fotoapparat#start()}.
* Asynchronously updates parameters of the camera. Must be called only after {@link #start()}.
*/
public void updateParameters(@NonNull final UpdateRequest updateRequest) {
ensureStarted();
Expand All @@ -230,6 +239,24 @@ public void run() {
});
}

/**
* Asynchronously updates zoom level of the camera. Must be called only after {@link #start()}.
* <p>
* If zoom is not supported by the device - does nothing.
*
* @param zoomLevel zoom level of the camera. A value between 0 and 1.
*/
public void setZoom(@FloatRange(from = 0f, to = 1f) final float zoomLevel) {
ensureStarted();

executor.execute(new Runnable() {
@Override
public void run() {
updateZoomLevelRoutine.updateZoomLevel(zoomLevel);
}
});
}

/**
* Starts camera.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.fotoapparat.hardware;

import android.support.annotation.FloatRange;

import java.util.List;

import io.fotoapparat.hardware.operators.AutoFocusOperator;
Expand All @@ -13,21 +15,23 @@
import io.fotoapparat.hardware.operators.PreviewStreamOperator;
import io.fotoapparat.hardware.operators.RendererParametersOperator;
import io.fotoapparat.hardware.operators.SurfaceOperator;
import io.fotoapparat.hardware.operators.ZoomOperator;
import io.fotoapparat.hardware.provider.AvailableLensPositionsProvider;
import io.fotoapparat.lens.FocusResult;
import io.fotoapparat.parameter.LensPosition;
import io.fotoapparat.parameter.Parameters;
import io.fotoapparat.parameter.RendererParameters;
import io.fotoapparat.photo.Photo;
import io.fotoapparat.preview.PreviewStream;
import io.fotoapparat.lens.FocusResult;

/**
* Abstraction for camera hardware.
*/
public interface CameraDevice extends CaptureOperator,
PreviewOperator, CapabilitiesOperator, OrientationOperator, ParametersOperator,
ConnectionOperator, SurfaceOperator, PreviewStreamOperator, RendererParametersOperator,
ExposureMeasurementOperator, AutoFocusOperator, AvailableLensPositionsProvider {
ExposureMeasurementOperator, AutoFocusOperator, AvailableLensPositionsProvider,
ZoomOperator {

@Override
void open(LensPosition lensPosition);
Expand Down Expand Up @@ -71,4 +75,7 @@ public interface CameraDevice extends CaptureOperator,
@Override
List<LensPosition> getAvailableLensPositions();

@Override
void setZoom(@FloatRange(from = 0f, to = 1f) float level);

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,18 @@ public class Capabilities {
private final Set<FocusMode> focusModes;
@NonNull
private final Set<Flash> flashModes;
private final boolean zoomSupported;

public Capabilities(@NonNull Set<Size> photoSizes,
@NonNull Set<Size> previewSizes,
@NonNull Set<FocusMode> focusModes,
@NonNull Set<Flash> flashModes) {
@NonNull Set<Flash> flashModes,
boolean zoomSupported) {
this.photoSizes = photoSizes;
this.previewSizes = previewSizes;
this.focusModes = focusModes;
this.flashModes = flashModes;
this.zoomSupported = zoomSupported;
}

/**
Expand All @@ -41,7 +44,8 @@ public static Capabilities empty() {
Collections.<Size>emptySet(),
Collections.<Size>emptySet(),
Collections.<FocusMode>emptySet(),
Collections.<Flash>emptySet()
Collections.<Flash>emptySet(),
false
);
}

Expand Down Expand Up @@ -73,14 +77,22 @@ public Set<Flash> supportedFlashModes() {
return flashModes;
}

/**
* @return {@code true} if zoom feature is supported. {@code false} if it is not supported.
*/
public boolean isZoomSupported() {
return zoomSupported;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

Capabilities that = (Capabilities) o;

return photoSizes.equals(that.photoSizes)
return zoomSupported == that.zoomSupported
&& photoSizes.equals(that.photoSizes)
&& previewSizes.equals(that.previewSizes)
&& focusModes.equals(that.focusModes)
&& flashModes.equals(that.flashModes);
Expand All @@ -93,6 +105,7 @@ public int hashCode() {
result = 31 * result + previewSizes.hashCode();
result = 31 * result + focusModes.hashCode();
result = 31 * result + flashModes.hashCode();
result = 31 * result + (zoomSupported ? 1 : 0);
return result;
}

Expand All @@ -103,6 +116,7 @@ public String toString() {
", previewSizes=" + previewSizes +
", focusModes=" + focusModes +
", flashModes=" + flashModes +
", zoomSupported=" + zoomSupported +
'}';
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.fotoapparat.hardware.operators;

import android.support.annotation.FloatRange;

/**
* Modifies zoom level of the camera.
*/
public interface ZoomOperator {

/**
* Changes zoom level of the camera. Must be called only if zoom is supported.
*
* @param level normalized zoom level. Value in range [0..1].
*/
void setZoom(@FloatRange(from = 0f, to = 1f) float level);

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package io.fotoapparat.hardware.v1;

import android.hardware.Camera;
import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.SurfaceView;
import android.view.TextureView;

Expand Down Expand Up @@ -52,6 +54,11 @@ public class Camera1 implements CameraDevice {
private Throwable lastStacktrace;
private int imageRotation;

@Nullable
private Capabilities cachedCapabilities = null;
@Nullable
private Camera.Parameters cachedZoomParameters = null;

public Camera1(Logger logger) {
this.capabilitiesFactory = new CapabilitiesFactory();
this.parametersConverter = new ParametersConverter();
Expand Down Expand Up @@ -123,6 +130,8 @@ private int facingForLensPosition(LensPosition lensPosition) {
public void close() {
recordMethod();

cachedCapabilities = null;

if (isCameraOpened()) {
camera.release();
}
Expand Down Expand Up @@ -207,6 +216,8 @@ public void updateParameters(Parameters parameters) {
recordMethod();

parametersOperator().updateParameters(parameters);

cachedZoomParameters = null;
}

@NonNull
Expand All @@ -231,11 +242,19 @@ private SwitchOnFailureParametersOperator parametersOperator() {

@Override
public Capabilities getCapabilities() {
if (cachedCapabilities != null) {
return cachedCapabilities;
}

recordMethod();

return capabilitiesFactory.fromParameters(
Capabilities capabilities = capabilitiesFactory.fromParameters(
camera.getParameters()
);

cachedCapabilities = capabilities;

return capabilities;
}

private void trySetDisplaySurface(Object displaySurface) throws IOException {
Expand Down Expand Up @@ -353,6 +372,31 @@ public List<LensPosition> getAvailableLensPositions() {
return availableLensPositionsProvider.getAvailableLensPositions();
}

@Override
public void setZoom(@FloatRange(from = 0f, to = 1f) float level) {
try {
setZoomUnsafe(level);
} catch (Exception e) {
logFailedZoomUpdate(level, e);
}
}

private void setZoomUnsafe(@FloatRange(from = 0f, to = 1f) float level) {
if (cachedZoomParameters == null) {
cachedZoomParameters = camera.getParameters();
}

cachedZoomParameters.setZoom(
(int) (cachedZoomParameters.getMaxZoom() * level)
);

camera.setParameters(cachedZoomParameters);
}

private void logFailedZoomUpdate(float level, Exception e) {
logger.log("Unable to change zoom level to " + level + " e: " + e.getMessage());
}

private Size previewSize() {
Camera.Size previewSize = camera.getParameters().getPreviewSize();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public Capabilities fromParameters(Camera.Parameters parameters) {
extractPictureSizes(parameters),
extractPreviewSizes(parameters),
extractFocusModes(parameters),
extractFlashModes(parameters)
extractFlashModes(parameters),
parameters.isZoomSupported()
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.fotoapparat.hardware.v2;

import android.os.Build;
import android.support.annotation.FloatRange;
import android.support.annotation.RequiresApi;

import java.util.List;
Expand Down Expand Up @@ -172,6 +173,11 @@ public List<LensPosition> getAvailableLensPositions() {
return availableLensPositionsProvider.getAvailableLensPositions();
}

@Override
public void setZoom(@FloatRange(from = 0f, to = 1f) float level) {
throw new UnsupportedOperationException("Not implemented. We do not actively support Camera2 at the moment.");
}

private void recordMethod() {
Exception lastStacktrace = new Exception();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ public Capabilities getCapabilities() {
availableJpegSizes(),
availablePreviewSizes(),
availableFocusModes(),
availableFlashModes()
availableFlashModes(),
false
);
}

Expand Down
Loading

0 comments on commit c7c0173

Please sign in to comment.