PreviewActivity improvements

pull/1/head
Dylan McIntyre 8 years ago
parent ac6814d061
commit 8154e129f4
  1. 23
      camerakit/src/main/java/com/flurgle/camerakit/Camera1.java
  2. 5
      camerakit/src/main/java/com/flurgle/camerakit/CameraImpl.java
  3. 9
      camerakit/src/main/java/com/flurgle/camerakit/CameraView.java
  4. 37
      demo/src/main/java/com/flurgle/camerakit/demo/MainActivity.java
  5. 37
      demo/src/main/java/com/flurgle/camerakit/demo/MediaHolder.java
  6. 53
      demo/src/main/java/com/flurgle/camerakit/demo/PreviewActivity.java
  7. 49
      demo/src/main/java/com/flurgle/camerakit/demo/ResultHolder.java
  8. 178
      demo/src/main/res/layout/activity_preview.xml

@ -41,6 +41,8 @@ public class Camera1 extends CameraImpl {
private Camera mCamera; private Camera mCamera;
private Camera.Parameters mCameraParameters; private Camera.Parameters mCameraParameters;
private final Camera.CameraInfo mCameraInfo = new Camera.CameraInfo(); private final Camera.CameraInfo mCameraInfo = new Camera.CameraInfo();
private Size mPreviewSize;
private Size mCaptureSize;
private boolean mShowingPreview; private boolean mShowingPreview;
private boolean mAutoFocus; private boolean mAutoFocus;
@ -395,13 +397,13 @@ public class Camera1 extends CameraImpl {
private void adjustCameraParameters() { private void adjustCameraParameters() {
SortedSet<Size> sizes = mPreviewSizes; SortedSet<Size> sizes = mPreviewSizes;
Size previewSize = chooseOptimalSize(sizes); mPreviewSize = chooseOptimalSize(sizes);
final Camera.Size currentSize = mCameraParameters.getPictureSize(); final Camera.Size currentSize = mCameraParameters.getPictureSize();
if (currentSize.width != previewSize.getWidth() || currentSize.height != previewSize.getHeight()) { if (currentSize.width != mPreviewSize.getWidth() || currentSize.height != mPreviewSize.getHeight()) {
Iterator<Size> iterator = mCaptureSizes.descendingIterator(); Iterator<Size> iterator = mCaptureSizes.descendingIterator();
Size pictureSize; Size pictureSize;
while ((pictureSize = iterator.next()) != null) { while ((pictureSize = iterator.next()) != null) {
if (AspectRatio.of(previewSize.getWidth(), previewSize.getHeight()).matches(pictureSize)) { if (AspectRatio.of(mPreviewSize.getWidth(), mPreviewSize.getHeight()).matches(pictureSize)) {
break; break;
} }
} }
@ -410,12 +412,14 @@ public class Camera1 extends CameraImpl {
pictureSize = mCaptureSizes.last(); pictureSize = mCaptureSizes.last();
} }
mCaptureSize = pictureSize;
if (mShowingPreview) { if (mShowingPreview) {
mCamera.stopPreview(); mCamera.stopPreview();
} }
mCameraParameters.setPreviewSize(previewSize.getWidth(), previewSize.getHeight()); mCameraParameters.setPreviewSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
mPreview.setTruePreviewSize(previewSize.getWidth(), previewSize.getHeight()); mPreview.setTruePreviewSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
mCameraParameters.setPictureSize(pictureSize.getWidth(), pictureSize.getHeight()); mCameraParameters.setPictureSize(pictureSize.getWidth(), pictureSize.getHeight());
mCameraParameters.setRotation(calcCameraRotation(mDisplayOrientation) + (mFacing == CameraKit.Constants.FACING_FRONT ? 180 : 0)); mCameraParameters.setRotation(calcCameraRotation(mDisplayOrientation) + (mFacing == CameraKit.Constants.FACING_FRONT ? 180 : 0));
@ -488,4 +492,13 @@ public class Camera1 extends CameraImpl {
} }
} }
@Override
Size getCaptureSize() {
return mCaptureSize;
}
@Override
Size getPreviewSize() {
return mPreviewSize;
}
} }

@ -4,6 +4,7 @@ import android.view.View;
import com.flurgle.camerakit.types.Facing; import com.flurgle.camerakit.types.Facing;
import com.flurgle.camerakit.types.Flash; import com.flurgle.camerakit.types.Flash;
import com.flurgle.camerakit.utils.Size;
public abstract class CameraImpl { public abstract class CameraImpl {
@ -45,4 +46,8 @@ public abstract class CameraImpl {
abstract void setDisplayOrientation(int displayOrientation); abstract void setDisplayOrientation(int displayOrientation);
abstract Size getCaptureSize();
abstract Size getPreviewSize();
} }

@ -31,6 +31,7 @@ import com.flurgle.camerakit.types.TapToFocus;
import com.flurgle.camerakit.utils.AspectRatio; import com.flurgle.camerakit.utils.AspectRatio;
import com.flurgle.camerakit.utils.CenterCrop; import com.flurgle.camerakit.utils.CenterCrop;
import com.flurgle.camerakit.utils.DisplayOrientationDetector; import com.flurgle.camerakit.utils.DisplayOrientationDetector;
import com.flurgle.camerakit.utils.Size;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
@ -295,6 +296,14 @@ public class CameraView extends FrameLayout {
mCameraImpl.endVideo(); mCameraImpl.endVideo();
} }
public Size getPreviewSize() {
return mCameraImpl != null ? mCameraImpl.getPreviewSize() : null;
}
public Size getCaptureSize() {
return mCameraImpl != null ? mCameraImpl.getCaptureSize() : null;
}
private void requestCameraPermission() { private void requestCameraPermission() {
Activity activity = null; Activity activity = null;
Context context = getContext(); Context context = getContext();

@ -23,7 +23,6 @@ import java.io.File;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
import butterknife.OnTextChanged;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
@ -119,13 +118,20 @@ public class MainActivity extends AppCompatActivity {
@OnClick(R.id.capturePhoto) @OnClick(R.id.capturePhoto)
void capturePhoto() { void capturePhoto() {
final long startTime = System.currentTimeMillis();
camera.setCameraListener(new CameraListener() { camera.setCameraListener(new CameraListener() {
@Override @Override
public void onPictureTaken(byte[] jpeg) { public void onPictureTaken(byte[] jpeg) {
super.onPictureTaken(jpeg); super.onPictureTaken(jpeg);
long callbackTime = System.currentTimeMillis();
Bitmap bitmap = BitmapFactory.decodeByteArray(jpeg, 0, jpeg.length); Bitmap bitmap = BitmapFactory.decodeByteArray(jpeg, 0, jpeg.length);
MediaHolder.dispose(); ResultHolder.dispose();
MediaHolder.setImage(bitmap); ResultHolder.setImage(bitmap);
ResultHolder.setNativeCaptureSize(
captureModeRadioGroup.getCheckedRadioButtonId() == R.id.modeCaptureQuality ?
camera.getCaptureSize() : camera.getPreviewSize()
);
ResultHolder.setTimeToCallback(callbackTime - startTime);
Intent intent = new Intent(MainActivity.this, PreviewActivity.class); Intent intent = new Intent(MainActivity.this, PreviewActivity.class);
startActivity(intent); startActivity(intent);
} }
@ -139,10 +145,7 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
public void onVideoTaken(File video) { public void onVideoTaken(File video) {
super.onVideoTaken(video); super.onVideoTaken(video);
MediaHolder.dispose();
MediaHolder.setVideo(video);
Intent intent = new Intent(MainActivity.this, PreviewActivity.class);
startActivity(intent);
} }
}); });
@ -224,11 +227,6 @@ public class MainActivity extends AppCompatActivity {
} }
}; };
@OnTextChanged(value = R.id.width, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
void widthChanged() {
}
@OnClick(R.id.widthUpdate) @OnClick(R.id.widthUpdate)
void widthUpdateClicked() { void widthUpdateClicked() {
if (widthUpdate.getAlpha() >= 1) { if (widthUpdate.getAlpha() >= 1) {
@ -249,11 +247,6 @@ public class MainActivity extends AppCompatActivity {
} }
}; };
@OnTextChanged(value = R.id.height)
void heightChanged() {
}
@OnClick(R.id.heightUpdate) @OnClick(R.id.heightUpdate)
void heightUpdateClicked() { void heightUpdateClicked() {
if (heightUpdate.getAlpha() >= 1) { if (heightUpdate.getAlpha() >= 1) {
@ -329,16 +322,6 @@ public class MainActivity extends AppCompatActivity {
cameraLayoutParams.width = width; cameraLayoutParams.width = width;
cameraLayoutParams.height = height; cameraLayoutParams.height = height;
camera.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
mCameraWidth = right - left;
mCameraHeight = bottom - top;
camera.removeOnLayoutChangeListener(this);
widthChanged();
heightChanged();
}
});
camera.setLayoutParams(cameraLayoutParams); camera.setLayoutParams(cameraLayoutParams);
Toast.makeText(this, (updateWidth && updateHeight ? "Width and height" : updateWidth ? "Width" : "Height") + " updated!", Toast.LENGTH_SHORT).show(); Toast.makeText(this, (updateWidth && updateHeight ? "Width and height" : updateWidth ? "Width" : "Height") + " updated!", Toast.LENGTH_SHORT).show();

@ -1,37 +0,0 @@
package com.flurgle.camerakit.demo;
import android.graphics.Bitmap;
import android.support.annotation.Nullable;
import java.io.File;
import java.lang.ref.WeakReference;
public class MediaHolder {
private static WeakReference<File> video;
private static WeakReference<Bitmap> image;
public static void setVideo(@Nullable File video) {
MediaHolder.video = video != null ? new WeakReference<>(video) : null;
}
@Nullable
public static File getVideo() {
return video != null ? video.get() : null;
}
public static void setImage(@Nullable Bitmap image) {
MediaHolder.image = image != null ? new WeakReference<>(image) : null;
}
@Nullable
public static Bitmap getImage() {
return image != null ? image.get() : null;
}
public static void dispose() {
setVideo(null);
setImage(null);
}
}

@ -2,27 +2,33 @@ package com.flurgle.camerakit.demo;
import android.app.Activity; import android.app.Activity;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.media.MediaPlayer;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.VideoView; import android.widget.TextView;
import java.io.File; import com.flurgle.camerakit.utils.AspectRatio;
import com.flurgle.camerakit.utils.Size;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import static com.flurgle.camerakit.demo.R.id.video;
public class PreviewActivity extends Activity { public class PreviewActivity extends Activity {
@BindView(R.id.image) @BindView(R.id.image)
ImageView imageView; ImageView imageView;
@BindView(video) @BindView(R.id.nativeCaptureResolution)
VideoView videoView; TextView nativeCaptureResolution;
@BindView(R.id.actualResolution)
TextView actualResolution;
@BindView(R.id.approxUncompressedSize)
TextView approxUncompressedSize;
@BindView(R.id.captureLatency)
TextView captureLatency;
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
@ -30,23 +36,28 @@ public class PreviewActivity extends Activity {
setContentView(R.layout.activity_preview); setContentView(R.layout.activity_preview);
ButterKnife.bind(this); ButterKnife.bind(this);
Bitmap bitmap = MediaHolder.getImage(); Bitmap bitmap = ResultHolder.getImage();
File video = MediaHolder.getVideo(); if (bitmap == null) {
finish();
return;
}
if (bitmap != null) {
imageView.setImageBitmap(bitmap); imageView.setImageBitmap(bitmap);
} else if (video != null) {
imageView.setVisibility(View.GONE); Size captureSize = ResultHolder.getNativeCaptureSize();
videoView.setVideoPath(video.getAbsolutePath()); if (captureSize != null) {
videoView.setMediaController(null); // Native sizes are landscape, hardcode flip because demo app forced to portrait.
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { AspectRatio aspectRatio = AspectRatio.of(captureSize.getHeight(), captureSize.getWidth());
@Override nativeCaptureResolution.setText(captureSize.getHeight() + " x " + captureSize.getWidth() + " (" + aspectRatio.toString() + ")");
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.setLooping(true);
} }
});
videoView.start(); actualResolution.setText(bitmap.getWidth() + " x " + bitmap.getHeight());
approxUncompressedSize.setText(getApproximateFileMegabytes(bitmap) + "MB");
captureLatency.setText(ResultHolder.getTimeToCallback() + " milliseconds");
} }
private static float getApproximateFileMegabytes(Bitmap bitmap) {
return (bitmap.getRowBytes() * bitmap.getHeight()) / 1024 / 1024;
} }
} }

@ -0,0 +1,49 @@
package com.flurgle.camerakit.demo;
import android.graphics.Bitmap;
import android.support.annotation.Nullable;
import com.flurgle.camerakit.utils.Size;
import java.lang.ref.WeakReference;
public class ResultHolder {
private static WeakReference<Bitmap> image;
private static Size nativeCaptureSize;
private static long timeToCallback;
public static void setImage(@Nullable Bitmap image) {
ResultHolder.image = image != null ? new WeakReference<>(image) : null;
}
@Nullable
public static Bitmap getImage() {
return image != null ? image.get() : null;
}
public static void setNativeCaptureSize(@Nullable Size nativeCaptureSize) {
ResultHolder.nativeCaptureSize = nativeCaptureSize;
}
@Nullable
public static Size getNativeCaptureSize() {
return nativeCaptureSize;
}
public static void setTimeToCallback(long timeToCallback) {
ResultHolder.timeToCallback = timeToCallback;
}
public static long getTimeToCallback() {
return timeToCallback;
}
public static void dispose() {
setImage(null);
setNativeCaptureSize(null);
setTimeToCallback(0);
}
}

@ -1,17 +1,183 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:background="@android:color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<VideoView <FrameLayout
android:id="@+id/video"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="wrap_content">
<ImageView <ImageView
android:id="@+id/image" android:id="@+id/image"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:adjustViewBounds="true" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<View
android:layout_width="2.5dp"
android:layout_height="match_parent"
android:background="@color/colorPrimary" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:text="NATIVE CAPTURE RESOLUTION"
android:textColor="@android:color/black"
android:textSize="18dp"
android:textStyle="bold" />
<TextView
android:id="@+id/nativeCaptureResolution"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:textColor="@android:color/black"
android:textSize="14.5dp" />
</LinearLayout>
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp">
<View
android:layout_width="2.5dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scaleType="centerInside" /> android:background="@color/colorPrimary" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:text="ACTUAL RESOLUTION"
android:textColor="@android:color/black"
android:textSize="18dp"
android:textStyle="bold" />
<TextView
android:id="@+id/actualResolution"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:textColor="@android:color/black"
android:textSize="14.5dp" />
</LinearLayout>
</FrameLayout> </FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp">
<View
android:layout_width="2.5dp"
android:layout_height="match_parent"
android:background="@color/colorPrimary" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:text="APPROX. UNCOMPRESSED SIZE"
android:textColor="@android:color/black"
android:textSize="18dp"
android:textStyle="bold" />
<TextView
android:id="@+id/approxUncompressedSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:textColor="@android:color/black"
android:textSize="14.5dp" />
</LinearLayout>
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp">
<View
android:layout_width="2.5dp"
android:layout_height="match_parent"
android:background="@color/colorPrimary" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:text="CAPTURE LATENCY"
android:textColor="@android:color/black"
android:textSize="18dp"
android:textStyle="bold" />
<TextView
android:id="@+id/captureLatency"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:textColor="@android:color/black"
android:textSize="14.5dp" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
Loading…
Cancel
Save