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

在使用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 block
			e.printStackTrace();
		}
		return null;
	}

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

为button添加事件监听:

change_Button.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				mCamera.stopPreview();
				mCamera.release();
				if (cameraId == 0) {
					cameraId = 1;
				} else {
					cameraId = 0;
				}
				OpenCameraAndSetSurfaceviewSize(cameraId);
				// the surfaceview is ready after the first launch
				SetAndStartPreview(sh);
			}
		});


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

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

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

源码在这里??

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


技术分享

技术分享





郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。