diff --git a/src/ve/ucv/ciens/ccg/nxtcam/camera/CameraPreview.java b/src/ve/ucv/ciens/ccg/nxtcam/camera/CameraPreview.java index 46ba5c2..fbe4da9 100644 --- a/src/ve/ucv/ciens/ccg/nxtcam/camera/CameraPreview.java +++ b/src/ve/ucv/ciens/ccg/nxtcam/camera/CameraPreview.java @@ -30,6 +30,8 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.hardware.Camera; +import android.hardware.Camera.CameraInfo; +import android.hardware.Camera.Parameters; import android.hardware.Camera.Size; import android.os.Build; import android.view.Surface; @@ -39,15 +41,17 @@ import android.view.SurfaceView; /** A basic Camera preview class */ @SuppressLint("ViewConstructor") public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback { - private final String TAG = "SURFVIEW"; - private final String CLASS_NAME = CameraPreview.class.getSimpleName(); + private static final String TAG = "SURFVIEW"; + private static final String CLASS_NAME = CameraPreview.class.getSimpleName(); + private static final int OPTIMAL_WIDTH = 352; + private static final int OPTIMAL_HEIGHT = 288; private CameraImageMonitor imgMonitor; - private Activity parentActivity; - private SurfaceHolder holder; - private Camera camera; - private int previewWidth; - private int previewHeight; + private Activity parentActivity; + private SurfaceHolder holder; + private Camera camera; + private int previewWidth; + private int previewHeight; @SuppressWarnings("deprecation") public CameraPreview(Context context, Camera camera){ @@ -61,41 +65,52 @@ public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } + /** + *

Sets the camera for this surface view.

+ * + * @param camera The camera to set. + */ public void setCamera(Camera camera){ this.camera = camera; if(this.camera != null){ - Logger.log_d(TAG, CLASS_NAME + ".setCamera() :: Setting camera."); + Logger.log_d(TAG, CLASS_NAME + ".setCamera(): Setting camera."); imgMonitor = CameraImageMonitor.getInstance(); requestLayout(); - Logger.log_d(TAG, CLASS_NAME + ".setCamera() :: Camera set."); + Logger.log_d(TAG, CLASS_NAME + ".setCamera(): Camera set."); } } + @Override public void surfaceCreated(SurfaceHolder holder){ // The Surface has been created, now tell the camera where to draw the preview. - Logger.log_d(TAG, CLASS_NAME + ".surfaceCreated() :: Creating surface view."); + Logger.log_d(TAG, CLASS_NAME + ".surfaceCreated(): Creating surface view."); try { if(camera != null) camera.setPreviewDisplay(holder); } catch (IOException e) { - Logger.log_e(TAG, CLASS_NAME + ".surfaceCreated() :: Error creating camera: " + e.getMessage()); + Logger.log_e(TAG, CLASS_NAME + ".surfaceCreated(): Error creating camera: " + e.getMessage()); } } + @Override public void surfaceDestroyed(SurfaceHolder holder){ if(camera != null) camera.stopPreview(); } + @Override public void surfaceChanged(SurfaceHolder tmpHolder, int format, int w, int h){ - int result; - int rotation; - int degrees = 0; - Camera.Parameters camParams; + int result; + int rotation; + int degrees = 0; + Size optimal; + CameraInfo info; + List sizes; + Parameters camParams; - Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged() :: Method started."); + Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged(): Method started."); if(this.holder.getSurface() == null || camera == null){ - Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged() :: Holder and/or camera are null."); + Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged(): Holder and/or camera are null."); return; } @@ -104,35 +119,43 @@ public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback requestLayout(); camParams = camera.getParameters(); - camParams.getSupportedPreviewSizes(); - List sizes = camParams.getSupportedPreviewSizes(); + sizes = camParams.getSupportedPreviewSizes(); for(Size size: sizes){ - Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged() :: Supported preview size (" + size.width + ", " + size.height + ")"); + Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged(): Supported preview size (" + size.width + ", " + size.height + ")"); } - Size optimal = getOptimalPreviewSize(sizes, 352, 288); - Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged() :: Preview size set at (" + optimal.width + ", " + optimal.height + ")"); + optimal = getOptimalPreviewSize(sizes, camera.new Size(OPTIMAL_WIDTH, OPTIMAL_HEIGHT)); + Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged(): Preview size set at (" + optimal.width + ", " + optimal.height + ")"); camParams.setPreviewSize(optimal.width, optimal.height); - // camParams.setPreviewSize(352, 288); camera.setParameters(camParams); previewWidth = optimal.width; previewHeight = optimal.height; - // previewWidth = 352; - // previewHeight = 288; - android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); - android.hardware.Camera.getCameraInfo(0, info); + info = new CameraInfo(); + Camera.getCameraInfo(0, info); rotation = parentActivity.getWindowManager().getDefaultDisplay().getRotation(); switch (rotation) { - case Surface.ROTATION_0: degrees = 0; break; - case Surface.ROTATION_90: degrees = 90; break; - case Surface.ROTATION_180: degrees = 180; break; - case Surface.ROTATION_270: degrees = 270; break; + default: + case Surface.ROTATION_0: + degrees = 0; + break; + + case Surface.ROTATION_90: + degrees = 90; + break; + + case Surface.ROTATION_180: + degrees = 180; + break; + + case Surface.ROTATION_270: + degrees = 270; + break; } - if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { + if (info.facing == CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing @@ -145,7 +168,7 @@ public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback camera.setPreviewDisplay(this.holder); camera.startPreview(); }catch (Exception e){ - Logger.log_e(TAG, CLASS_NAME + ".surfaceChanged() :: Error starting camera preview: " + e.getMessage()); + Logger.log_e(TAG, CLASS_NAME + ".surfaceChanged(): Error starting camera preview: " + e.getMessage()); } } @@ -153,51 +176,47 @@ public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback public void onPreviewFrame(byte[] data, Camera camera){ if(imgMonitor.hasChanged()) imgMonitor.setImageParameters(previewWidth, previewHeight); - Logger.log_d(TAG, CLASS_NAME + ".onPreviewFrame() :: Preview received"); - Logger.log_d(TAG, CLASS_NAME + ".onPreviewFrame() :: Frame has" + (imgMonitor.hasChanged() ? "" : " not") + " been consumed."); imgMonitor.setImageData(data); } + /** + *

If camera is not null then disable the camera preview.

+ */ public void removePreviewCallback(){ if(camera != null) camera.setPreviewCallback(null); } - private Size getOptimalPreviewSize(List sizes, int w, int h) { - final double ASPECT_TOLERANCE = 0.1; - double targetRatio = (double) w / h; + /** + *

Tries to obtain the preview size that better matches the target size pixel dimensions.

+ * + * @param sizes An initialized list of supported preview sizes. + * @param target The ideal preview size. + * @return The size from the list of sizes that better matches the target. Null if sizes is null or empty. + */ + private final Size getOptimalPreviewSize(List sizes, final Size target) { + final int TARGET_HEIGHT = target.height; + Size optimalSize = null; + double minDiff = Double.MAX_VALUE; - Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize() :: Method started."); - 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); - } - } + if (sizes == null || sizes.size() == 0) return null; // Cannot find the one match the aspect ratio, ignore the requirement if (optimalSize == null) { + Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize(): Ignoring aspect ratio."); minDiff = Double.MAX_VALUE; for (Size size : sizes) { - if (Math.abs(size.height - targetHeight) < minDiff) { + if (Math.abs(size.height - TARGET_HEIGHT) < minDiff) { optimalSize = size; - minDiff = Math.abs(size.height - targetHeight); + minDiff = Math.abs(size.height - TARGET_HEIGHT); + Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize(): Size = (" + Integer.toString(size.width) + ", " + Integer.toString(size.width) + ")"); + Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize(): minDiff = " + Double.toString(minDiff)); } } } - Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize() :: Method ended."); - Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize() :: Optimal size is: (" + Integer.toString(optimalSize.width) + - ", " + Integer.toString(optimalSize.height) + ")"); + + Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize(): Optimal size found is (" + Integer.toString(optimalSize.width) + ", " + Integer.toString(optimalSize.height) + ")"); + return optimalSize; } }