`
473687880
  • 浏览: 485729 次
文章分类
社区版块
存档分类
最新评论

Android实时监控项目第三篇:通过摄像头实时预览帧视频

 
阅读更多

在第二个Activity中,我们要显示摄像头预览的视频,布局文件很简单,就一个SurfaceView组件,设置为占满整个父组件(这里不再给出),用来显示预览的视频。

在对应的Activity文件中,要获取SurfaceView的SurfaceHolder,并为其添加一个回调监听器,该监听器传入一个Callback实例,这里需要覆写Callback实例中的三个方法,分别是:

public void surfaceCreated(SurfaceHolder holder)方法,当打开摄像头时,该方法被回调;

public void surfaceChanged(SurfaceHolder holder)方法,当SurfaceView预览界面的格式或大小发生改变时,该方法被回调;

public void surfaceDestroyed(SurfaceHolder holder)方法,当SurfaceView被销毁时,该方法被回调;

surfaceCreated方法中通过私有方法initCreama()对摄像头各项参数进行初始化,主要是设置预览视频的尺寸,每秒显示的帧数等,设置完参数后,通过setParameters(Camera.Parameters parameters)方法显示取景画面,即预览视频。在开始预览前,调用setPreviewCallback(PreviewCallback cb)方法来获取采集到的预览视频流数据,从而可以对其进行处理,这一点将在下篇中详细讲解。在开始预览之后,还要设置自动对焦,不然摄像头采集到的图像不清晰。


另外,这里有两点需要注意:

1、每台手机的摄像头所支持的图像预览或拍摄尺寸不尽相同,如果设置的图像尺寸,摄像头不支持,则会出错,因此在真机上测试前,先要确定摄像头支持哪些尺寸,具体的方法很简单,这里不再给出,需要了解的可以参考这篇文章:http://blog.csdn.net/yanzi1225627/article/details/7738736;

2、要编写横竖屏镜头自动调整的代码,否则预览的图像将是左右颠倒的。

该文件详细代码如下:

package zyb.org.camera;

import java.io.IOException;

import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

public class CameraActivity extends Activity {

	private SurfaceView sView = null;
	private String ipName = null;
	private SurfaceHolder sHolder = null;
	private int screenWidth;
	private int screenHeight;
	private Camera camera = null;
	private boolean isPreview = false; 
	
	public Camera getCamera() {
		return camera;
	}
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_camera);
		
		//从上个Activity中获取传递过来的数据
		Intent intent = getIntent();
		ipName = intent.getStringExtra("ipname");
			
		//获取屏幕的宽和高
		DisplayMetrics dm = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(dm);
		screenWidth = dm.widthPixels;
		screenHeight = dm.heightPixels;
		
		sView = (SurfaceView)findViewById(R.id.sView);	
		sHolder = sView.getHolder();
		sHolder.addCallback(new Callback() {
			
			//释放camera时,回调该方法
			@Override
			public void surfaceDestroyed(SurfaceHolder holder) {
				if(camera != null){
					camera.setPreviewCallback(null);
					if(isPreview)
						camera.stopPreview();
					camera.release();
					camera = null;
				}
			}
			
			//打开摄像头时,回调该方法
			@Override
			public void surfaceCreated(SurfaceHolder holder) {
				initCamera();
			}
			
			@Override
			public void surfaceChanged(SurfaceHolder holder, int format, int width,
					int height) {
				// TODO Auto-generated method stub
				
			}
		});
	}	
	
	/**
	 * 初始化摄像头各参数
	 * */
	private void initCamera(){
		if(!isPreview)
			camera = Camera.open();
		if(camera!=null && !isPreview){
			try {
				Camera.Parameters parameters = camera.getParameters();
				//每台手机的摄像头所支持的图像预览或拍摄尺寸不尽相同,
				//如果设置的图像尺寸,摄像头不支持,则会出错,
				//因此在真机上测试前,先要确定摄像头支持哪些尺寸
				parameters.setPreviewSize(screenWidth, screenHeight);  //设置预览图像的尺寸大小
				parameters.setPreviewFpsRange(10, 20);                 //设置每秒显示10-20帧
				// 横竖屏镜头自动调整
			    if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE){
				      parameters.set("orientation", "portrait"); 
				      parameters.set("rotation", 90); // 镜头角度转90度(默认摄像头是横拍) 
				      camera.setDisplayOrientation(90); // 在2.2以上可以使用
			     } else{
			      // 如果是横屏
				      parameters.set("orientation", "landscape"); 
				      camera.setDisplayOrientation(0); // 在2.2以上可以使用
			     } 
				camera.setPreviewDisplay(sHolder);                     //通过SurfaceView显示取景画面
				//回调处理预览视频流类中的onPreviewFrame方法
				//在onPreviewFrame方法中,启动发送视频流的线程
				camera.setPreviewCallback(new ViedoStream(ipName,CameraActivity.this));    
				camera.startPreview();           //开始预览
				camera.autoFocus(null);         //自动对焦
			} catch (IOException e) {
				e.printStackTrace();
			}
			isPreview = true;
		}
	}
}

下篇将讲述后台线程发送预览帧视频的操作

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics