android通过camera和surfaceview选择摄像头并即时预览

来源:互联网 发布:基础设施网络建设 编辑:程序博客网 时间:2024/06/05 07:45

在使用android设备的摄像头的时候我们有两种选择:

1.调用intent方法使用摄像头

2.通过camera类使用摄像头


第一种方法非常方便,不过需要跳到新的activity中,这样的用户体验并不是特别好


生气使用camera能有更大的自定义空间!


使用camera就需要用surfaceview显示摄像头的即时画面


我们这样设置layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:gravity="center"    android:orientation="vertical"    tools:context="com.example.video_activity.MainActivity" >    <SurfaceView        android:id="@+id/surfaceview"        android:layout_width="320dp"        android:layout_height="240dp" />    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center_horizontal"        android:orientation="horizontal" >        <Button            android:id="@+id/change"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="change" />    </LinearLayout>    <TextView        android:id="@+id/textview"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="which camera" /></LinearLayout>

一个静态的surfaceview、Button和Textview

button是用于后面切换摄像头的

textview用于显示摄像头id

实例化以上控件再声明一个camera对象。

private Camera mCamera;

实例化控件后还要给surfaceview一个holder用于接收camera的内容。

一个layoutParameters用于改变surfaceview尺寸(否则会产生畸变)

lp = surfaceView.getLayoutParams();sh = surfaceView.getHolder();

选一个摄像头的id(默认可以为0或者1),获取它的信息

private Void OpenCameraAndSetSurfaceviewSize(int cameraId) {mCamera = Camera.open(cameraId);//id用于选中不同的摄像头,有的相机会有很多的Camera.Parameters parameters = mCamera.getParameters();Size pre_size = parameters.getPreviewSize();Size pic_size = parameters.getPictureSize();//和预览的尺寸不同,这是拍照后实际相片的尺寸,会比较大android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();android.hardware.Camera.getCameraInfo(cameraId, info);//获取选中的摄像头信息int camera_number = Camera.getNumberOfCameras();//获取摄像头数量if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {//分辨是否前置摄像头textview.setText("There are " + camera_number + " camera."+ "This is the Front Camera!");} else {textview.setText("There are " + camera_number + " camera."+ "This is the Back Camera!");}lp.height = pre_size.width * 2;lp.width = pre_size.height * 2;return null;}


我们编写SetAndStartPreview方法实例化camera并将预览加载到surfaceview中

private Void SetAndStartPreview(SurfaceHolder holder) {try {mCamera.setPreviewDisplay(holder);mCamera.setDisplayOrientation(90);mCamera.startPreview();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}

切换摄像头的原理就将camera释放掉再重新加载。

为button添加事件监听:

change_Button.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubmCamera.stopPreview();mCamera.release();if (cameraId == 0) {cameraId = 1;} else {cameraId = 0;}OpenCameraAndSetSurfaceviewSize(cameraId);// the surfaceview is ready after the first launchSetAndStartPreview(sh);}});


值得一提的是我们将camera和surface holder关联的时候必须确保surfaceview已经建立好,否则camera获取不到surfaceview的信息

我们需要为surfaceholder添加addCallback(this);并在create中调用方法

public void surfaceCreated(SurfaceHolder holder) {// TODO Auto-generated method stubSetAndStartPreview(holder);}

源码在这里⬇️

http://download.csdn.net/detail/edwardwayne/8491597







0 0