Fix crop center bug (#30)

pull/36/head
Mattia Iavarone 7 years ago committed by GitHub
parent cce8d6e621
commit 93b1f718db
  1. 25
      cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java
  2. 44
      cameraview/src/main/views/com/otaliastudios/cameraview/Preview.java

@ -450,6 +450,7 @@ class Camera1 extends CameraController {
@Override
boolean shouldFlipSizes() {
LOG.i("shouldFlip:", "mDeviceOrientation=", mDeviceOrientation, "mSensorOffset=", mSensorOffset);
return (mDeviceOrientation + mSensorOffset) % 180 != 0;
}
@ -510,7 +511,7 @@ class Camera1 extends CameraController {
// Choose the max size.
List<Size> captureSizes = sizesFromList(params.getSupportedPictureSizes());
Size maxSize = Collections.max(captureSizes);
LOG.i("computeCaptureSize:", "computed", maxSize, "from", captureSizes);
LOG.i("computeCaptureSize:", "computed", maxSize);
return Collections.max(captureSizes);
} else {
// Choose according to developer choice in setVideoQuality.
@ -768,7 +769,7 @@ class Camera1 extends CameraController {
for (Camera.Size size : sizes) {
result.add(new Size(size.width, size.height));
}
LOG.i("sizesFromList:", result.toArray());
LOG.i("sizesFromList:", result);
return result;
}
@ -802,13 +803,21 @@ class Camera1 extends CameraController {
LOG.i("matchSize:", "found big enough and consistent:", bigEnoughAndConsistent.size());
Size result;
if (biggestPossible) {
if (bigEnoughAndConsistent.size() > 0) return Collections.max(bigEnoughAndConsistent);
if (consistent.size() > 0) return Collections.max(consistent);
result = Collections.max(sizes);
if (bigEnoughAndConsistent.size() > 0) {
result = Collections.max(bigEnoughAndConsistent);
} else if (consistent.size() > 0) {
result = Collections.max(consistent);
} else {
result = Collections.max(sizes);
}
} else {
if (bigEnoughAndConsistent.size() > 0) return Collections.min(bigEnoughAndConsistent);
if (consistent.size() > 0) return Collections.max(consistent);
result = Collections.max(sizes);
if (bigEnoughAndConsistent.size() > 0) {
result = Collections.min(bigEnoughAndConsistent);
} else if (consistent.size() > 0) {
result = Collections.max(consistent);
} else {
result = Collections.max(sizes);
}
}
LOG.i("matchSize:", "returning result", result);
return result;

@ -9,6 +9,8 @@ import android.view.ViewGroup;
abstract class Preview {
private final static CameraLogger LOG = CameraLogger.create(Preview.class.getSimpleName());
// This is used to notify CameraImpl to recompute its camera Preview size.
// After that, CameraView will need a new layout pass to adapt to the Preview size.
interface SurfaceCallback {
@ -45,6 +47,7 @@ abstract class Preview {
// This is called by the CameraImpl.
// These must be alredy rotated, if needed, to be consistent with surface/view sizes.
void setDesiredSize(int width, int height) {
LOG.i("setDesiredSize:", "desiredW=", width, "desiredH=", height);
this.mDesiredWidth = width;
this.mDesiredHeight = height;
crop();
@ -60,6 +63,7 @@ abstract class Preview {
protected final void onSurfaceAvailable(int width, int height) {
LOG.i("onSurfaceAvailable:", "w=", width, "h=", height);
mSurfaceWidth = width;
mSurfaceHeight = height;
crop();
@ -70,6 +74,7 @@ abstract class Preview {
// As far as I can see, these are the view/surface dimensions.
// This is called by subclasses.
protected final void onSurfaceSizeChanged(int width, int height) {
LOG.i("onSurfaceSizeChanged:", "w=", width, "h=", height);
if (width != mSurfaceWidth || height != mSurfaceHeight) {
mSurfaceWidth = width;
mSurfaceHeight = height;
@ -87,30 +92,33 @@ abstract class Preview {
/**
* As far as I can see, this extends either width or height of the surface,
* to match the desired aspect ratio.
* This means that the external part of the surface will be cropped by the outer view.
* Here we must crop the visible part by applying a > 1 scale to one of our
* dimensions. This way our internal aspect ratio (mSurfaceWidth / mSurfaceHeight)
* will match the preview size aspect ratio (mDesiredWidth / mDesiredHeight).
*
* There might still be some absolute difference (e.g. same ratio but bigger / smaller).
* However that should be already managed by the framework.
*/
private final void crop() {
getView().post(new Runnable() {
@Override
public void run() {
if (mDesiredWidth != 0 && mDesiredHeight != 0) {
AspectRatio aspectRatio = AspectRatio.of(mDesiredWidth, mDesiredHeight);
float targetHeight = (float) mSurfaceWidth / aspectRatio.toFloat();
float scale = 1;
if (mSurfaceHeight > 0) {
scale = targetHeight / (float) mSurfaceHeight;
}
if (scale > 1) {
getView().setScaleX(1f);
getView().setScaleY(scale);
} else {
getView().setScaleX(1f / scale);
getView().setScaleY(1f);
}
if (mDesiredHeight == 0 || mDesiredWidth == 0) return;
if (mSurfaceHeight == 0 || mSurfaceWidth == 0) return;
float scaleX = 1f, scaleY = 1f;
AspectRatio current = AspectRatio.of(mSurfaceWidth, mSurfaceHeight);
AspectRatio target = AspectRatio.of(mDesiredWidth, mDesiredHeight);
if (current.toFloat() >= target.toFloat()) {
// We are too short. Must increase height.
scaleY = current.toFloat() / target.toFloat();
} else {
// We must increase width.
scaleX = target.toFloat() / current.toFloat();
}
getView().setScaleX(scaleX);
getView().setScaleY(scaleY);
LOG.i("crop:", "applied scaleX=", scaleX);
LOG.i("crop:", "applied scaleY=", scaleY);
}
});
}

Loading…
Cancel
Save