Back to project page geoar-app.
The source code is released under:
Apache License
If you think the Android project geoar-app listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/** * Copyright 2012 52North Initiative for Geospatial Open Source Software GmbH */*ww w .j ava 2 s .co m*/ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.n52.geoar.tracking.camera; import java.util.List; import org.n52.geoar.R; import android.app.AlertDialog; import android.content.Context; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.hardware.Camera.Size; import android.util.AttributeSet; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; import android.view.View; import android.view.WindowManager; /** * A View which encapsulates a camera preview. Takes care of freeing all * resources as needed * * @author Holger Hopmann * */ public class CameraView extends SurfaceView implements Callback { private SurfaceHolder holder; private Camera camera; private int cameraId; private int cameraSizeHintWidth; private int cameraSizeHintHeight; public CameraView(Context context) { super(context); init(); } public CameraView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { holder = getHolder(); holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // kept for // older // versions } /** * Methode ?bernommen aus Android API Demos, siehe * http://developer.android.com * /resources/samples/ApiDemos/src/com/example/android * /apis/graphics/CameraPreview.html * * Copyright (C) 2007 The Android Open Source Project * * @param sizes * @param w * @param h * @return */ private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.05; 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 width, int height) { if (camera == null) return; // ?nderung des Surface f?r Kameravorschau ber?cksichtigen // Bilddrehung // Systemdienstinstanz erhalten WindowManager windowManager = (WindowManager) getContext() .getSystemService(Context.WINDOW_SERVICE); // Rotationskonstante Surface.ROTATION_... int rotation = windowManager.getDefaultDisplay().getRotation(); // According to API Documentation // http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation%28int%29 int degrees = 0; 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; } // // Annahme, dass Kamera 90? verdreht zu Standardausrichtung // platziert // // ist. Tats?chlicher Wert erst ab Android 2.3 abrufbar. TODO // int cameraRotation = (90 - degrees + 360) % 360; CameraInfo info = new CameraInfo(); Camera.getCameraInfo(cameraId, info); int cameraRotation; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { cameraRotation = (info.orientation + degrees) % 360; cameraRotation = (360 - cameraRotation) % 360; // compensate the // mirror } else { // back-facing cameraRotation = (info.orientation - degrees + 360) % 360; } camera.stopPreview(); // Fix for 2.3.3 Bug? camera.setDisplayOrientation(cameraRotation); // Bildgr??e Camera.Parameters parameters = camera.getParameters(); Size bestSize = getOptimalPreviewSize( parameters.getSupportedPreviewSizes(), cameraSizeHintWidth != 0 ? cameraSizeHintWidth : width, cameraSizeHintHeight != 0 ? cameraSizeHintHeight : height); parameters.setPreviewSize(bestSize.width, bestSize.height); // Update static camera settings fields if (cameraRotation == 0 || cameraRotation == 180) { RealityCamera.setViewportSize(bestSize); RealityCamera.setFovY(parameters.getVerticalViewAngle()); // RealityCamera.setAspect(parameters.getHorizontalViewAngle() // / parameters.getVerticalViewAngle()); // TODO merge updates } else { RealityCamera.setViewportSize(bestSize.height, bestSize.width); RealityCamera.setFovY(parameters.getHorizontalViewAngle()); // RealityCamera.setAspect(parameters.getVerticalViewAngle() // / parameters.getHorizontalViewAngle()); // TODO merge updates } camera.setParameters(parameters); // Neustart der Vorschaudarstellung camera.startPreview(); requestLayout(); } // @Override // protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // // if (!RealityCamera.hasViewportSize()) { // super.onMeasure(widthMeasureSpec, heightMeasureSpec); // } else { // int maxWidth = MeasureSpec.getSize(widthMeasureSpec); // // int maxHeight = MeasureSpec.getSize(heightMeasureSpec); // // float ratio = maxWidth / (float) RealityCamera.cameraViewportWidth; // // int widthSpec = MeasureSpec.makeMeasureSpec(maxWidth, // MeasureSpec.EXACTLY); // int heightSpec = MeasureSpec.makeMeasureSpec( // (int) (RealityCamera.cameraViewportHeight * ratio), // MeasureSpec.EXACTLY); // // setMeasuredDimension(widthSpec, heightSpec); // } // } public void surfaceCreated(SurfaceHolder holder) { try { // Kameraobjekt erzeugen int numCameras = Camera.getNumberOfCameras(); CameraInfo cameraInfo = new CameraInfo(); for (int i = 0; i < numCameras; i++) { Camera.getCameraInfo(i, cameraInfo); if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) { camera = Camera.open(i); cameraId = i; break; } } if (camera == null) { throw new RuntimeException(); // jump to exception block } camera.setPreviewDisplay(this.holder); } catch (Exception e) { new AlertDialog.Builder(getContext()).setTitle(R.string.error) .setMessage(R.string.camera_not_available) .setNeutralButton(R.string.ok, null).show(); } } public void surfaceDestroyed(SurfaceHolder holder) { if (camera != null) { /** stop and release the camera */ camera.stopPreview(); camera.release(); camera = null; } } @Override protected void onVisibilityChanged(View changedView, int visibility) { if (camera != null) { if (isShown()) { camera.startPreview(); } else { camera.stopPreview(); } } super.onVisibilityChanged(changedView, visibility); } public void setCameraSizeHint(int width, int height) { cameraSizeHintWidth = width; cameraSizeHintHeight = height; } }