Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
Diolor committed Jul 16, 2017
2 parents 8d5b16c + 43029af commit 42339f8
Show file tree
Hide file tree
Showing 15 changed files with 222 additions and 94 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Fotoapparat
.into(cameraView) // view which will draw the camera preview
.previewScaleType(ScaleType.CENTER_CROP) // we want the preview to fill the view
.photoSize(biggestSize()) // we want to have the biggest photo possible
.previewScaleType(centerCropped()) // we want the preview to fill the view
.lensPosition(back()) // we want back camera
.focusMode(firstAvailable( // (optional) use the first focus mode which is supported by device
continuousFocus(),
Expand Down
1 change: 1 addition & 0 deletions fotoapparat/src/main/java/io/fotoapparat/Fotoapparat.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ static Fotoapparat create(FotoapparatBuilder builder) {
StartCameraRoutine startCameraRoutine = new StartCameraRoutine(
cameraDevice,
builder.renderer,
builder.scaleType,
builder.lensPositionSelector,
screenOrientationProvider,
initialParametersProvider,
Expand Down
11 changes: 11 additions & 0 deletions fotoapparat/src/main/java/io/fotoapparat/FotoapparatBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import io.fotoapparat.parameter.Flash;
import io.fotoapparat.parameter.FocusMode;
import io.fotoapparat.parameter.LensPosition;
import io.fotoapparat.parameter.ScaleType;
import io.fotoapparat.parameter.Size;
import io.fotoapparat.parameter.selector.FlashSelectors;
import io.fotoapparat.parameter.selector.SelectorFunction;
Expand Down Expand Up @@ -51,6 +52,8 @@ public class FotoapparatBuilder {
);
SelectorFunction<Flash> flashSelector = FlashSelectors.off();

ScaleType scaleType = ScaleType.CENTER_CROP;

FrameProcessor frameProcessor = null;

Logger logger = Loggers.none();
Expand Down Expand Up @@ -85,6 +88,14 @@ public FotoapparatBuilder previewSize(@NonNull SelectorFunction<Size> selector)
return this;
}

/**
* @param scaleType of preview inside the view.
*/
public FotoapparatBuilder previewScaleType(ScaleType scaleType) {
this.scaleType = scaleType;
return this;
}

/**
* @param selector selects focus mode from list of available modes.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ private Set<FocusMode> extractFocusModes(Camera.Parameters parameters) {
}

result.add(FocusMode.FIXED);

return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,78 +23,78 @@
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class CapabilitiesFactory implements CapabilitiesOperator {

private final CameraConnection cameraConnection;

public CapabilitiesFactory(CameraConnection cameraConnection) {
this.cameraConnection = cameraConnection;
}

@Override
public Capabilities getCapabilities() {
return new Capabilities(
availableJpegSizes(),
availablePreviewSizes(),
availableFocusModes(),
availableFlashModes()
);
}

@SuppressWarnings("ConstantConditions")
private Set<Size> availableJpegSizes() {
return characteristics().getJpegOutputSizes();
}

@SuppressWarnings("ConstantConditions")
private Set<Size> availablePreviewSizes() {
HashSet<Size> filteredOutputSizes = new HashSet<>();
for (Size outputSize : characteristics().getSurfaceOutputSizes()) {
if (outputSize.width <= PreviewSizeInfo.MAX_PREVIEW_WIDTH && outputSize.height <= PreviewSizeInfo.MAX_PREVIEW_HEIGHT) {
filteredOutputSizes.add(outputSize);
}
}

return filteredOutputSizes;
}

@SuppressWarnings("ConstantConditions")
private Set<FocusMode> availableFocusModes() {
Set<FocusMode> focusModes = new HashSet<>();
for (int afMode : characteristics().autoFocusModes()) {
focusModes.add(FocusConverter.afModeToFocus(afMode));
}

return focusModes;
}

@SuppressWarnings("ConstantConditions")
private Set<Flash> availableFlashModes() {
if (characteristics().isFlashAvailable()) {
return availableFlashUnitModes();
}
return Collections.singleton(Flash.OFF);

}

@SuppressWarnings("ConstantConditions")
private Set<Flash> availableFlashUnitModes() {
Set<Flash> flashes = new HashSet<>();
flashes.add(Flash.OFF);
flashes.add(Flash.TORCH);

int[] autoExposureModes = characteristics().autoExposureModes();

for (int autoExposureMode : autoExposureModes) {
Flash flash = exposureModeToFlash(autoExposureMode);
if (flash != null) {
flashes.add(flash);
}
}

return flashes;
}

private Characteristics characteristics() {
return cameraConnection.getCharacteristics();
}
private final CameraConnection cameraConnection;

public CapabilitiesFactory(CameraConnection cameraConnection) {
this.cameraConnection = cameraConnection;
}

@Override
public Capabilities getCapabilities() {
return new Capabilities(
availableJpegSizes(),
availablePreviewSizes(),
availableFocusModes(),
availableFlashModes()
);
}

@SuppressWarnings("ConstantConditions")
private Set<Size> availableJpegSizes() {
return characteristics().getJpegOutputSizes();
}

@SuppressWarnings("ConstantConditions")
private Set<Size> availablePreviewSizes() {
HashSet<Size> filteredOutputSizes = new HashSet<>();
for (Size outputSize : characteristics().getSurfaceOutputSizes()) {
if (outputSize.width <= PreviewSizeInfo.MAX_PREVIEW_WIDTH && outputSize.height <= PreviewSizeInfo.MAX_PREVIEW_HEIGHT) {
filteredOutputSizes.add(outputSize);
}
}

return filteredOutputSizes;
}

@SuppressWarnings("ConstantConditions")
private Set<FocusMode> availableFocusModes() {
Set<FocusMode> focusModes = new HashSet<>();
for (int afMode : characteristics().autoFocusModes()) {
focusModes.add(FocusConverter.afModeToFocus(afMode));
}

return focusModes;
}

@SuppressWarnings("ConstantConditions")
private Set<Flash> availableFlashModes() {
if (characteristics().isFlashAvailable()) {
return availableFlashUnitModes();
}
return Collections.singleton(Flash.OFF);

}

@SuppressWarnings("ConstantConditions")
private Set<Flash> availableFlashUnitModes() {
Set<Flash> flashes = new HashSet<>();
flashes.add(Flash.OFF);
flashes.add(Flash.TORCH);

int[] autoExposureModes = characteristics().autoExposureModes();

for (int autoExposureMode : autoExposureModes) {
Flash flash = exposureModeToFlash(autoExposureMode);
if (flash != null) {
flashes.add(flash);
}
}

return flashes;
}

private Characteristics characteristics() {
return cameraConnection.getCharacteristics();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public boolean equals(Object o) {
RendererParameters that = (RendererParameters) o;

return frameRotation == that.frameRotation && (previewSize != null ? previewSize.equals(that.previewSize) : that.previewSize == null);

}

@Override
Expand Down
20 changes: 20 additions & 0 deletions fotoapparat/src/main/java/io/fotoapparat/parameter/ScaleType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.fotoapparat.parameter;

/**
* The scale type of the preview relatively to the view.
*/
public enum ScaleType {

/**
* The preview will be scaled so as its one dimensions will be equal and the other one equal or
* larger than the corresponding dimension of the view
*/
CENTER_CROP,

/**
* The preview will be scaled so as its one dimensions will be equal and the other one equal or
* smaller than the corresponding dimension of the view
*/
CENTER_INSIDE

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.fotoapparat.hardware.CameraException;
import io.fotoapparat.hardware.orientation.ScreenOrientationProvider;
import io.fotoapparat.parameter.LensPosition;
import io.fotoapparat.parameter.ScaleType;
import io.fotoapparat.parameter.provider.InitialParametersProvider;
import io.fotoapparat.parameter.selector.SelectorFunction;
import io.fotoapparat.view.CameraRenderer;
Expand All @@ -16,19 +17,22 @@ public class StartCameraRoutine implements Runnable {

private final CameraDevice cameraDevice;
private final CameraRenderer cameraRenderer;
private final ScaleType scaleType;
private final SelectorFunction<LensPosition> lensPositionSelector;
private final ScreenOrientationProvider screenOrientationProvider;
private final InitialParametersProvider initialParametersProvider;
private final CameraErrorCallback cameraErrorCallback;

public StartCameraRoutine(CameraDevice cameraDevice,
CameraRenderer cameraRenderer,
ScaleType scaleType,
SelectorFunction<LensPosition> lensPositionSelector,
ScreenOrientationProvider screenOrientationProvider,
InitialParametersProvider initialParametersProvider,
CameraErrorCallback cameraErrorCallback) {
this.cameraDevice = cameraDevice;
this.cameraRenderer = cameraRenderer;
this.scaleType = scaleType;
this.lensPositionSelector = lensPositionSelector;
this.screenOrientationProvider = screenOrientationProvider;
this.initialParametersProvider = initialParametersProvider;
Expand Down Expand Up @@ -56,8 +60,8 @@ private void tryToStartCamera() {
cameraDevice.setDisplayOrientation(
screenOrientationProvider.getScreenRotation()
);
cameraRenderer.setScaleType(scaleType);
cameraRenderer.attachCamera(cameraDevice);
cameraDevice.startPreview();
}

}
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package io.fotoapparat.view;

import io.fotoapparat.hardware.CameraDevice;
import io.fotoapparat.parameter.ScaleType;

/**
* Renders the stream from {@link io.fotoapparat.Fotoapparat}.
*/
public interface CameraRenderer {

/**
* Sets the scale type of the preview to the renderer. This method will be called from camera
* thread, so it is safe to perform blocking operations here.
*/
void setScaleType(ScaleType scaleType);

/**
* Attaches renderer to camera, so that it will display the preview when camera is started. This
* method will be called from camera thread, so it is safe to perform blocking operations here.
Expand Down
6 changes: 6 additions & 0 deletions fotoapparat/src/main/java/io/fotoapparat/view/CameraView.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import android.widget.FrameLayout;

import io.fotoapparat.hardware.CameraDevice;
import io.fotoapparat.parameter.ScaleType;

/**
* Displays stream from camera.
Expand Down Expand Up @@ -55,6 +56,11 @@ private void init() {
addView(rendererView);
}

@Override
public void setScaleType(ScaleType scaleType) {
rendererView.setScaleType(scaleType);
}

@Override
public void attachCamera(CameraDevice camera) {
rendererView.attachCamera(camera);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import io.fotoapparat.hardware.CameraDevice;
import io.fotoapparat.parameter.RendererParameters;
import io.fotoapparat.parameter.ScaleType;
import io.fotoapparat.parameter.Size;

/**
Expand All @@ -29,6 +30,7 @@ class TextureRendererView extends FrameLayout implements CameraRenderer {
private TextureView textureView;

private Size previewSize = null;
private ScaleType scaleType;

public TextureRendererView(@NonNull Context context) {
super(context);
Expand Down Expand Up @@ -74,6 +76,11 @@ private void tryToInitializeSurfaceTexture(TextureView textureView) {
}
}

@Override
public void setScaleType(ScaleType scaleType) {
this.scaleType = scaleType;
}

@Override
public void attachCamera(CameraDevice camera) {
awaitSurfaceTexture();
Expand All @@ -82,7 +89,7 @@ public void attachCamera(CameraDevice camera) {
camera.setDisplaySurface(textureView);
}

private void updateLayout(CameraDevice camera) {
private void updateLayout(final CameraDevice camera) {
final Size previewSize = toPreviewSize(
camera.getRendererParameters()
);
Expand Down Expand Up @@ -117,11 +124,39 @@ private void awaitSurfaceTexture() {

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (previewSize == null) {
if (previewSize == null || scaleType == null) {
super.onLayout(changed, left, top, right, bottom);
return;
}

if (scaleType == ScaleType.CENTER_INSIDE) {
centerInside(previewSize);
} else {
centerCrop(previewSize);
}
}

private void centerInside(Size previewSize) {
final float scale = Math.min(
getMeasuredWidth() / (float) previewSize.width,
getMeasuredHeight() / (float) previewSize.height
);

final int width = (int) (previewSize.width * scale);
final int height = (int) (previewSize.height * scale);

final int extraX = Math.max(0, getMeasuredWidth() - width);
final int extraY = Math.max(0, getMeasuredHeight() - height);

getChildAt(0).layout(
extraX / 2,
extraY / 2,
width + (extraX / 2),
height + (extraY / 2)
);
}

private void centerCrop(Size previewSize) {
final float scale = Math.max(
getMeasuredWidth() / (float) previewSize.width,
getMeasuredHeight() / (float) previewSize.height
Expand Down
Loading

0 comments on commit 42339f8

Please sign in to comment.