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

来源:互联网 发布:软件安全测试 编辑:程序博客网 时间:2024/05/16 17:14

在第二个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、要编写横竖屏镜头自动调整的代码,否则预览的图像将是左右颠倒的。

该文件详细代码如下:

[java] view plaincopy
  1. package zyb.org.camera;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import android.app.Activity;  
  6. import android.content.Intent;  
  7. import android.content.res.Configuration;  
  8. import android.hardware.Camera;  
  9. import android.os.Bundle;  
  10. import android.util.DisplayMetrics;  
  11. import android.view.SurfaceHolder;  
  12. import android.view.SurfaceHolder.Callback;  
  13. import android.view.SurfaceView;  
  14.   
  15. public class CameraActivity extends Activity {  
  16.   
  17.     private SurfaceView sView = null;  
  18.     private String ipName = null;  
  19.     private SurfaceHolder sHolder = null;  
  20.     private int screenWidth;  
  21.     private int screenHeight;  
  22.     private Camera camera = null;  
  23.     private boolean isPreview = false;   
  24.       
  25.     public Camera getCamera() {  
  26.         return camera;  
  27.     }  
  28.       
  29.     @Override  
  30.     protected void onCreate(Bundle savedInstanceState) {  
  31.         super.onCreate(savedInstanceState);  
  32.         setContentView(R.layout.activity_camera);  
  33.           
  34.         //从上个Activity中获取传递过来的数据  
  35.         Intent intent = getIntent();  
  36.         ipName = intent.getStringExtra("ipname");  
  37.               
  38.         //获取屏幕的宽和高  
  39.         DisplayMetrics dm = new DisplayMetrics();  
  40.         getWindowManager().getDefaultDisplay().getMetrics(dm);  
  41.         screenWidth = dm.widthPixels;  
  42.         screenHeight = dm.heightPixels;  
  43.           
  44.         sView = (SurfaceView)findViewById(R.id.sView);    
  45.         sHolder = sView.getHolder();  
  46.         sHolder.addCallback(new Callback() {  
  47.               
  48.             //释放camera时,回调该方法  
  49.             @Override  
  50.             public void surfaceDestroyed(SurfaceHolder holder) {  
  51.                 if(camera != null){  
  52.                     camera.setPreviewCallback(null);  
  53.                     if(isPreview)  
  54.                         camera.stopPreview();  
  55.                     camera.release();  
  56.                     camera = null;  
  57.                 }  
  58.             }  
  59.               
  60.             //打开摄像头时,回调该方法  
  61.             @Override  
  62.             public void surfaceCreated(SurfaceHolder holder) {  
  63.                 initCamera();  
  64.             }  
  65.               
  66.             @Override  
  67.             public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  68.                     int height) {  
  69.                 // TODO Auto-generated method stub  
  70.                   
  71.             }  
  72.         });  
  73.     }     
  74.       
  75.     /** 
  76.      * 初始化摄像头各参数 
  77.      * */  
  78.     private void initCamera(){  
  79.         if(!isPreview)  
  80.             camera = Camera.open();  
  81.         if(camera!=null && !isPreview){  
  82.             try {  
  83.                 Camera.Parameters parameters = camera.getParameters();  
  84.                 //每台手机的摄像头所支持的图像预览或拍摄尺寸不尽相同,  
  85.                 //如果设置的图像尺寸,摄像头不支持,则会出错,  
  86.                 //因此在真机上测试前,先要确定摄像头支持哪些尺寸  
  87.                 parameters.setPreviewSize(screenWidth, screenHeight);  //设置预览图像的尺寸大小  
  88.                 parameters.setPreviewFpsRange(1020);                 //设置每秒显示10-20帧  
  89.                 // 横竖屏镜头自动调整  
  90.                 if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE){  
  91.                       parameters.set("orientation""portrait");   
  92.                       parameters.set("rotation"90); // 镜头角度转90度(默认摄像头是横拍)   
  93.                       camera.setDisplayOrientation(90); // 在2.2以上可以使用  
  94.                  } else{  
  95.                   // 如果是横屏  
  96.                       parameters.set("orientation""landscape");   
  97.                       camera.setDisplayOrientation(0); // 在2.2以上可以使用  
  98.                  }   
  99.                 camera.setPreviewDisplay(sHolder);                     //通过SurfaceView显示取景画面  
  100.                 //回调处理预览视频流类中的onPreviewFrame方法  
  101.                 //在onPreviewFrame方法中,启动发送视频流的线程  
  102.                 camera.setPreviewCallback(new ViedoStream(ipName,CameraActivity.this));      
  103.                 camera.startPreview();           //开始预览  
  104.                 camera.autoFocus(null);         //自动对焦  
  105.             } catch (IOException e) {  
  106.                 e.printStackTrace();  
  107.             }  
  108.             isPreview = true;  
  109.         }  
  110.     }  
  111. }  

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

0 0
原创粉丝点击