From a2e3dedbe4e09c4299143110bf938956c74ffe6c Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Mon, 9 Sep 2013 12:38:17 +0100 Subject: integrated working example --- src/com/example/rotorm/Preview.java | 160 ++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 src/com/example/rotorm/Preview.java (limited to 'src/com/example/rotorm/Preview.java') diff --git a/src/com/example/rotorm/Preview.java b/src/com/example/rotorm/Preview.java new file mode 100644 index 0000000..5fdea5a --- /dev/null +++ b/src/com/example/rotorm/Preview.java @@ -0,0 +1,160 @@ +package com.example.rotorm; + +import java.io.IOException; +import java.util.List; + +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 android.view.View; +import android.view.ViewGroup; + +class Preview extends ViewGroup implements SurfaceHolder.Callback { + private final String TAG = "Preview"; + + SurfaceView mSurfaceView; + SurfaceHolder mHolder; + Size mPreviewSize; + List mSupportedPreviewSizes; + Camera mCamera; + + Preview(Context context, SurfaceView sv) { + super(context); + + mSurfaceView = sv; +// addView(mSurfaceView); + + mHolder = mSurfaceView.getHolder(); + mHolder.addCallback(this); + mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + } + + public void setCamera(Camera camera) { + mCamera = camera; + if (mCamera != null) { + mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes(); + requestLayout(); + + // get Camera parameters + Camera.Parameters params = mCamera.getParameters(); + + List focusModes = params.getSupportedFocusModes(); + if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) { + // set the focus mode + params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); + // set Camera parameters + mCamera.setParameters(params); + } + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + // We purposely disregard child measurements because act as a + // wrapper to a SurfaceView that centers the camera preview instead + // of stretching it. + final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); + final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); + setMeasuredDimension(width, height); + + if (mSupportedPreviewSizes != null) { + mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height); + } + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + if (changed && getChildCount() > 0) { + final View child = getChildAt(0); + + final int width = r - l; + final int height = b - t; + + int previewWidth = width; + int previewHeight = height; + if (mPreviewSize != null) { + previewWidth = mPreviewSize.width; + previewHeight = mPreviewSize.height; + } + + // Center the child SurfaceView within the parent. + if (width * previewHeight > height * previewWidth) { + final int scaledChildWidth = previewWidth * height / previewHeight; + child.layout((width - scaledChildWidth) / 2, 0, + (width + scaledChildWidth) / 2, height); + } else { + final int scaledChildHeight = previewHeight * width / previewWidth; + child.layout(0, (height - scaledChildHeight) / 2, + width, (height + scaledChildHeight) / 2); + } + } + } + + public void surfaceCreated(SurfaceHolder holder) { + // The Surface has been created, acquire the camera and tell it where + // to draw. + try { + if (mCamera != null) { + mCamera.setPreviewDisplay(holder); + } + } catch (IOException exception) { + Log.e(TAG, "IOException caused by setPreviewDisplay()", exception); + } + } + + public void surfaceDestroyed(SurfaceHolder holder) { + // Surface will be destroyed when we return, so stop the preview. + if (mCamera != null) { + mCamera.stopPreview(); + } + } + + + private Size getOptimalPreviewSize(List sizes, int w, int h) { + final double ASPECT_TOLERANCE = 0.1; + double targetRatio = (double) w / h; + if (sizes == null) return null; + + Size optimalSize = null; + double minDiff = Double.MAX_VALUE; + + int targetHeight = h; + + // Try to find an size match aspect ratio and size + for (Size size : sizes) { + double ratio = (double) size.width / size.height; + if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; + if (Math.abs(size.height - targetHeight) < minDiff) { + optimalSize = size; + minDiff = Math.abs(size.height - targetHeight); + } + } + + // Cannot find the one match the aspect ratio, ignore the requirement + if (optimalSize == null) { + minDiff = Double.MAX_VALUE; + for (Size size : sizes) { + if (Math.abs(size.height - targetHeight) < minDiff) { + optimalSize = size; + minDiff = Math.abs(size.height - targetHeight); + } + } + } + return optimalSize; + } + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + if(mCamera != null) { + Camera.Parameters parameters = mCamera.getParameters(); + parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); + requestLayout(); + + mCamera.setParameters(parameters); + mCamera.startPreview(); + } + } + +} -- cgit v1.2.3