Skip to content

Commit

Permalink
Choose preview size optimally
Browse files Browse the repository at this point in the history
Change-Id: I8f6f3f24293fa7c66485bca87479808876a8c33b
  • Loading branch information
yaraki committed Apr 6, 2016
1 parent 129e2d9 commit 738d268
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

import java.io.Closeable;
import java.io.IOException;
import java.util.List;
import java.util.Set;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.registerIdlingResources;
Expand Down Expand Up @@ -120,7 +120,7 @@ public void check(View view, NoMatchingViewException noViewFoundException) {
SizeMap map = cameraView.getSupportedPreviewSizes();
assertThat(map.ratios().size(), is(greaterThanOrEqualTo(1)));
for (AspectRatio ratio : map.ratios()) {
final List<Size> sizes = map.sizes(ratio);
final Set<Size> sizes = map.sizes(ratio);
assertThat(sizes.size(), is(is(greaterThanOrEqualTo(1))));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@

package com.google.android.cameraview;

import android.support.annotation.NonNull;

/**
* Immutable class for describing width and height dimensions in pixels.
*/
public class Size {
public class Size implements Comparable<Size> {

private final int mWidth;
private final int mHeight;
Expand Down Expand Up @@ -69,4 +71,9 @@ public int hashCode() {
return mHeight ^ ((mWidth << (Integer.SIZE / 2)) | (mWidth >>> (Integer.SIZE / 2)));
}

@Override
public int compareTo(@NonNull Size another) {
return mWidth * mHeight - another.mWidth * another.mHeight;
}

}
12 changes: 6 additions & 6 deletions library/src/main/base/com/google/android/cameraview/SizeMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@

import android.support.v4.util.ArrayMap;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

/**
* A collection class that automatically groups {@link Size}s by their {@link AspectRatio}s.
*/
public class SizeMap {

private final ArrayMap<AspectRatio, List<Size>> mRatios = new ArrayMap<>();
private final ArrayMap<AspectRatio, SortedSet<Size>> mRatios = new ArrayMap<>();

/**
* Add a new {@link Size} to this collection.
Expand All @@ -38,7 +38,7 @@ public class SizeMap {
public boolean add(Size size) {
for (AspectRatio ratio : mRatios.keySet()) {
if (ratio.matches(size)) {
final List<Size> sizes = mRatios.get(ratio);
final SortedSet<Size> sizes = mRatios.get(ratio);
if (sizes.contains(size)) {
return false;
} else {
Expand All @@ -48,7 +48,7 @@ public boolean add(Size size) {
}
}
// None of the existing ratio matches the provided size; add a new key
List<Size> sizes = new ArrayList<>();
SortedSet<Size> sizes = new TreeSet<>();
sizes.add(size);
mRatios.put(AspectRatio.of(size.getWidth(), size.getHeight()), sizes);
return true;
Expand All @@ -58,7 +58,7 @@ public Set<AspectRatio> ratios() {
return mRatios.keySet();
}

public List<Size> sizes(AspectRatio ratio) {
public SortedSet<Size> sizes(AspectRatio ratio) {
return mRatios.get(ratio);
}

Expand Down
66 changes: 44 additions & 22 deletions library/src/main/camera1/com/google/android/cameraview/Camera1.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,20 @@
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
import android.view.WindowManager;

import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;

@SuppressWarnings("deprecation")
class Camera1 extends CameraViewImpl {

private static final int INVALID_CAMERA_ID = -1;

private static final AspectRatio DEFAULT_ASPECT_RATIO = AspectRatio.of(4, 3);
private static final String TAG = "Camera1";

private final Context mContext;

Expand Down Expand Up @@ -73,6 +72,7 @@ public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int hei
mPreviewInfo.configure(surface, width, height);
if (mCamera != null) {
setUpPreview();
adjustPreviewSize();
}
}

Expand All @@ -81,6 +81,7 @@ public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int h
mPreviewInfo.configure(surface, width, height);
if (mCamera != null) {
setUpPreview();
adjustPreviewSize();
}
}

Expand Down Expand Up @@ -118,15 +119,15 @@ void onPause() {

@Override
void startPreview() {
setUpPreview();
if (mPreviewInfo.surface != null) {
setUpPreview();
}
mCamera.startPreview();
}

private void setUpPreview() {
try {
if (mPreviewInfo.surface != null) {
mCamera.setPreviewTexture(mPreviewInfo.surface);
}
mCamera.setPreviewTexture(mPreviewInfo.surface);
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand All @@ -153,14 +154,12 @@ void setAspectRatio(AspectRatio ratio) {
// Handle this later when camera is opened
mAspectRatio = ratio;
} else if (!mAspectRatio.equals(ratio)) {
final List<Size> sizes = mPreviewSizes.sizes(ratio);
final Set<Size> sizes = mPreviewSizes.sizes(ratio);
if (sizes == null) {
throw new UnsupportedOperationException(ratio + " is not supported");
} else {
mAspectRatio = ratio;
Size size = chooseOptimalSize(sizes);
mCameraParameters.setPreviewSize(size.getWidth(), size.getHeight());
mCamera.setParameters(mCameraParameters);
adjustPreviewSize();
}
}
}
Expand Down Expand Up @@ -205,14 +204,7 @@ private void openCamera() {
if (mAspectRatio == null) {
mAspectRatio = DEFAULT_ASPECT_RATIO;
}
final List<Size> sizes = mPreviewSizes.sizes(mAspectRatio);
if (sizes == null) { // Not supported
mAspectRatio = chooseAspectRatio();
}
Size size = chooseOptimalSize(sizes);
mCameraParameters.setPreviewSize(size.getWidth(), size.getHeight());
Log.d(TAG, "openCamera: " + size.getWidth() + "x" + size.getHeight());
mCamera.setParameters(mCameraParameters);
adjustPreviewSize();
// Display orientation
mDisplayOrientation = calcDisplayOrientation();
mCamera.setDisplayOrientation(mDisplayOrientation);
Expand All @@ -230,9 +222,39 @@ private AspectRatio chooseAspectRatio() {
return r;
}

private Size chooseOptimalSize(List<Size> sizes) {
Log.d(TAG, "chooseOptimalSize: " + sizes.get(0));
return sizes.get(0); // TODO: Pick optimally
private void adjustPreviewSize() {
final SortedSet<Size> sizes = mPreviewSizes.sizes(mAspectRatio);
if (sizes == null) { // Not supported
mAspectRatio = chooseAspectRatio();
}
Size size = chooseOptimalSize(sizes);
mCameraParameters.setPreviewSize(size.getWidth(), size.getHeight());
mCamera.setParameters(mCameraParameters);
}

@SuppressWarnings("SuspiciousNameCombination")
private Size chooseOptimalSize(SortedSet<Size> sizes) {
if (mPreviewInfo.width == 0 || mPreviewInfo.height == 0) { // Not yet laid out
return sizes.first(); // Return the smallest size
}
int desiredWidth;
int desiredHeight;
if (mDisplayOrientation == 90 || mDisplayOrientation == 270) {
desiredWidth = mPreviewInfo.height;
desiredHeight = mPreviewInfo.width;
} else {
desiredWidth = mPreviewInfo.width;
desiredHeight = mPreviewInfo.height;
}
Size result = null;
for (Size size : sizes) { // Iterate from small to large
if (desiredWidth <= size.getWidth() && desiredHeight <= size.getHeight()) {
return size;

}
result = size;
}
return result;
}

private void releaseCamera() {
Expand Down

0 comments on commit 738d268

Please sign in to comment.