Android Camera使用小结 博客分类: Android cameraandroid
程序员文章站
2024-03-04 13:57:47
...
Android 中的camera的使用是个很普遍的用法,今天小结下其使用步骤,翻译自http://mobile.tutsplus.com/tutorials/android/android-essentials-create-a-mirror/
1) 设计界面,如下
2 开始调用摄象头,在其oncreate事件中,如下代码:
这里mCameraId = findFirstFrontFacingCamera();
首先找出前置摄象头,有个findFirstFrontFacingCamera()的方法,代码如下:
其实就是一个循环找出其前置摄象头
3 接下来startCameraInLayout(mPreviewLayout, mCameraId);
就是打开这个前置摄象头,将捕捉到的图象放到屏幕的界面上来,代码如下:
4 下面重点来看MirrorView类
这个类其实是继承了SurfaceView类,如下,这个其实就是让camera直接写surface了
5 最后还要适当调整下图片的比例:
6 最后要做些清理工作,分别为onresume和onpause事件
完整的代码还包括判断是否有摄象头,以及拍下照片保存到文件中去,详细代码见附件,
1) 设计界面,如下
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <FrameLayout android:id="@+id/camPreview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" > </FrameLayout> <Button android:id="@+id/capture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:text="@string/capture" /> </RelativeLayout>
2 开始调用摄象头,在其oncreate事件中,如下代码:
private Camera mCam; private MirrorView mCamPreview; private int mCameraId = 0; private FrameLayout mPreviewLayout; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mCameraId = findFirstFrontFacingCamera(); mPreviewLayout = (FrameLayout) findViewById(R.id.camPreview); mPreviewLayout.removeAllViews(); startCameraInLayout(mPreviewLayout, mCameraId); }
这里mCameraId = findFirstFrontFacingCamera();
首先找出前置摄象头,有个findFirstFrontFacingCamera()的方法,代码如下:
private int findFirstFrontFacingCamera() { int foundId = -1; // find the first front facing camera int numCams = Camera.getNumberOfCameras(); for (int camId = 0; camId < numCams; camId++) { CameraInfo info = new CameraInfo(); Camera.getCameraInfo(camId, info); if (info.facing == CameraInfo.CAMERA_FACING_FRONT) { Log.d(DEBUG_TAG, "Found front facing camera"); foundId = camId; break; } } return foundId; }
其实就是一个循环找出其前置摄象头
3 接下来startCameraInLayout(mPreviewLayout, mCameraId);
就是打开这个前置摄象头,将捕捉到的图象放到屏幕的界面上来,代码如下:
private void startCameraInLayout(FrameLayout layout, int cameraId) { mCam = Camera.open(cameraId); if (mCam != null) { mCamPreview = new MirrorView(this, mCam); layout.addView(mCamPreview); } }
4 下面重点来看MirrorView类
这个类其实是继承了SurfaceView类,如下,这个其实就是让camera直接写surface了
public class MirrorView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder mHolder; private Camera mCamera; public MirrorView(Context context, Camera camera) { super(context); mCamera = camera; mHolder = getHolder(); mHolder.addCallback(this); mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public void surfaceCreated(SurfaceHolder holder) { try { mCamera.setPreviewDisplay(holder); mCamera.startPreview(); } catch (Exception error) { Log.d(DEBUG_TAG, "Error starting mPreviewLayout: " + error.getMessage()); } } public void surfaceDestroyed(SurfaceHolder holder) { } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { if (mHolder.getSurface() == null) { return; } // can't make changes while mPreviewLayout is active try { mCamera.stopPreview(); } catch (Exception e) { } try { // set rotation to match device orientation setCameraDisplayOrientationAndSize(); // start up the mPreviewLayout mCamera.setPreviewDisplay(mHolder); mCamera.startPreview(); } catch (Exception error) { Log.d(DEBUG_TAG, "Error starting mPreviewLayout: " + error.getMessage()); } }
5 最后还要适当调整下图片的比例:
public void setCameraDisplayOrientationAndSize() { CameraInfo info = new CameraInfo(); Camera.getCameraInfo(mCameraId, info); int rotation = getWindowManager().getDefaultDisplay().getRotation(); int degrees = rotation * 90; /* * // the above is just a shorter way of doing this, but could break * if the values change 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; } */ int result; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; } else { result = (info.orientation - degrees + 360) % 360; } mCamera.setDisplayOrientation(result); Camera.Size previewSize = mCam.getParameters().getPreviewSize(); if (result == 90 || result == 270) { // swap - the physical camera itself doesn't rotate in relation // to the screen ;) mHolder.setFixedSize(previewSize.height, previewSize.width); } else { mHolder.setFixedSize(previewSize.width, previewSize.height); } }
6 最后要做些清理工作,分别为onresume和onpause事件
@Override protected void onResume() { super.onResume(); if (mCam == null && mPreviewLayout != null) { mPreviewLayout.removeAllViews(); startCameraInLayout(mPreviewLayout, mCameraId); } } @Override protected void onPause() { if (mCam != null) { mCam.release(); mCam = null; } super.onPause(); }
完整的代码还包括判断是否有摄象头,以及拍下照片保存到文件中去,详细代码见附件,
上一篇: 限制CheckBoxList控件只能单选实现代码及演示动画
下一篇: Android项目基本结构详解
推荐阅读
-
Android Camera使用小结 博客分类: Android cameraandroid
-
android中Application使用 博客分类: androidandroid开发系列
-
使用百度地图API----定位 博客分类: Android 百度地图android
-
Android Intent 使用整理 博客分类: android AndroidGmailGoogleSchemeXML
-
Android Intent 使用整理 博客分类: android AndroidGmailGoogleSchemeXML
-
ubuntu 10.10使用adb连接g2 博客分类: android UbuntuAndroid
-
ubuntu 10.10使用adb连接g2 博客分类: android UbuntuAndroid
-
使用Dexposed为你的安卓应用加上在线修复的能力。 博客分类: android dexposed
-
gradlew wrapper使用下载到本地的gradle.zip文件安装。 博客分类: java基础android
-
gradlew wrapper使用下载到本地的gradle.zip文件安装。 博客分类: java基础android