SurfaceView显示Camera拍摄的画面

一般情况下,可以使用MediaRecorder来录制视频,视频数据也可在SurfaceView上显示,但是那要写数据到存储设备上。而且我们项目是视频聊天,就不能使用Media了。

网上找了找资料,自己给改了下:


public class CameravedioActivity extends Activity{
	
	private static final String TAG = "CameravedioActivity";
	private Camera camera; 
    private boolean preview  = false ;
    private SeekBar mSeekBar;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
       /*
        *设置窗口属性:一定要在 setContentView(R.layout.main) 之前
        */
// 窗口标题,其实可以在manifes文件里面注册
//     requestWindowFeature(Window.FEATURE_NO_TITLE);
// 全屏 
       getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
       setContentView(R.layout.main);
       SurfaceView surfaceView =  (SurfaceView) findViewById(R.id.surfaceView);
       surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
       surfaceView.getHolder().setFixedSize(200, 200);
       surfaceView.getHolder().addCallback(new SurfaceViewCallback());
       
       /**
        * seekbar 用来实现变焦逻辑
        */
       mSeekBar = (SeekBar)findViewById(R.id.seekbar);
       mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

		@Override
		public void onProgressChanged(SeekBar seekBar, int progress,
				boolean fromUser) {
			// TODO Auto-generated method stub
			Log.d(TAG, "progress:"+progress);
		}

		@Override
		public void onStartTrackingTouch(SeekBar seekBar) {
			// TODO Auto-generated method stub
			Log.d(TAG, "onStartTrackingTouch");
		}

		@Override
		public void onStopTrackingTouch(SeekBar seekBar) {
			// TODO Auto-generated method stub
			Log.d(TAG, "onStartTrackingTouch");
		}
    	   
       });
    }
	
	private final class SurfaceViewCallback implements Callback {
		/**
		 * surfaceView 被创建成功后调用此方法
		 */
		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			Log.d(TAG,"surfaceCreated");
			/* 
			 * 在SurfaceView创建好之后 打开摄像头
			 * 注意是 android.hardware.Camera
			 */
			camera = Camera.open();
			/*
			 * This method must be called before startPreview(). otherwise surfaceview没有图像
			 */
			try {
				camera.setPreviewDisplay(holder);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			Camera.Parameters parameters = camera.getParameters();
			/* 设置预览照片的大小,此处设置为全屏 */
//			WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); // 获取当前屏幕管理器对象
//			Display display = wm.getDefaultDisplay();      				     // 获取屏幕信息的描述类
//			parameters.setPreviewSize(display.getWidth(), display.getHeight());          // 设置
			parameters.setPreviewSize(200, 200); 
			/* 每秒从摄像头捕获5帧画面, */
			parameters.setPreviewFrameRate(5);
			/* 设置照片的输出格式:jpg */
			parameters.setPictureFormat(PixelFormat.JPEG);
			/* 照片质量 */
			parameters.set("jpeg-quality", 85);
			/* 设置照片的大小:此处照片大小等于屏幕大小 */
//			parameters.setPictureSize(display.getWidth(), display.getHeight());
			parameters.setPictureSize(200, 200);
			/* 将参数对象赋予到 camera 对象上 */
//			camera.setParameters(parameters);
			mSeekBar.setMax(100);
			camera.startPreview();
			/**
			 * Installs a callback to be invoked for every preview frame in addition to displaying them on the screen. 
			 * The callback will be repeatedly called for as long as preview is active. This method can be called at 
			 * any time, even while preview is live. Any other preview callbacks are overridden.
			 * a callback object that receives a copy of each preview frame, or null to stop receiving 
			 */
			camera.setPreviewCallback(new Camera.PreviewCallback(){

				@Override
				public void onPreviewFrame(byte[] data, Camera camera) {
					// TODO Auto-generated method stub
				    //在视频聊天中,这里传送本地frame数据给remote端
					Log.d(TAG, "camera:"+camera);
					Log.d(TAG, "byte:"+data);
				}
				
			});
			preview = true;
		}
		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
			Log.d(TAG,"surfaceChanged");
		}
		/**
		 * SurfaceView 被销毁时释放掉 摄像头
		 */
		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			if(camera != null) {
				/* 若摄像头正在工作,先停止它 */
				if(preview) {
					camera.stopPreview();
					preview = false;
				}
				//如果注册了此回调,在release之前调用,否则release之后还回调,crash
				camera.setPreviewCallback(null);
				camera.release();
			}
		}
		
	}
	
	
	/**
	 * 处理照片被拍摄之后的事件
	 */
	private final class TakePictureCallback implements PictureCallback {
		@Override
		public void onPictureTaken(byte[] data, Camera camera) {
		}
	}
}


main.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <LinearLayout
    	android:layout_width="fill_parent"
    	android:layout_height="fill_parent"
    	android:orientation="vertical"
    >
		<SurfaceView 
			android:id="@+id/surfaceView"
		    android:layout_width="300dip" 
		    android:layout_height="300dip" 
		    android:visibility="visible"
	    />
	    <LinearLayout
	    	android:layout_width="fill_parent"
	    	android:layout_height="wrap_content"
    	>
    		<SeekBar
    			android:id="@+id/seekbar"
    			android:layout_width="fill_parent"
	    		android:layout_height="wrap_content"
    		/>
    	</LinearLayout>
    </LinearLayout>
</FrameLayout>
我在自己机器上测试surfaceview必须包含在FrameLayout中

manifest文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="cn.edu.wtu"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
    	<!-- android:screenOrientation="landscape" 表示横向界面 -->
        <activity android:name=".CameravedioActivity" android:label="@string/app_name"  android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-sdk android:minSdkVersion="7" />
    <!-- 在SDCard中创建与删除文件权限 -->
	<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
	<!-- 往SDCard写入数据权限 -->
	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!-- 申请使用摄像头的权限 -->
	<uses-permission android:name="android.permission.CAMERA"/>
</manifest>
注意哦,有些手机是不支持变焦的,所以设置Camera的Parameter会crash,所以要实现变焦逻辑首先判断手机是否支持smoothzoom

sdk 2.1还是不支持setZoom的,2.3.3可以,2.2没有测试




  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值