/**
*
*/
package com.performanceactive.plugins.camera;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
public class CustomCameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = CustomCameraPreview.class.getSimpleName();
private final Camera camera;
public CustomCameraPreview(Context context, Camera camera) {
super(context);
this.camera = camera;
getHolder().addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
// TODO: show activity indicator here, it can take almost 1 second to show the preview
camera.setPreviewDisplay(holder);
camera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// nothing to do here
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (getHolder().getSurface() == null) {
return;
}
try {
camera.stopPreview();
} catch (Exception e){
// tried to stop a non-existent preview
}
try {
Camera.Parameters cameraSettings = camera.getParameters();
Size previewSize = optimimalPreviewSize(width, height);
cameraSettings.setPreviewSize(previewSize.width, previewSize.height);
camera.setParameters(cameraSettings);
camera.setPreviewDisplay(holder);
camera.setDisplayOrientation(90);
camera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
private Size optimimalPreviewSize(int targetWidth, int targetHeight) {
List<Size> sizes = camera.getParameters().getSupportedPreviewSizes();
float targetAspectRatio = (float) targetWidth / targetHeight;
List<Size> sizesWithMatchingAspectRatios = filterByAspectRatio(targetAspectRatio, sizes);
if (sizesWithMatchingAspectRatios.size() > 0) {
return optimalSizeForHeight(sizesWithMatchingAspectRatios, targetHeight);
}
return optimalSizeForHeight(sizes, targetHeight);
}
private List<Size> filterByAspectRatio(float targetAspectRatio, List<Size> sizes) {
List<Size> filteredSizes = new ArrayList<Size>();
for (Size size : sizes) {
// reverse the ratio calculation as we've flipped the orientation
float aspectRatio = (float)size.height / size.width;
if (aspectRatio == targetAspectRatio) {
filteredSizes.add(size);
}
}
return filteredSizes;
}
private Size optimalSizeForHeight(List<Size> sizes, int targetHeight) {
Size optimalSize = null;
float minimumHeightDelta = Float.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minimumHeightDelta) {
optimalSize = size;
minimumHeightDelta = Math.abs(size.height - targetHeight);
}
}
return optimalSize;
}
}