Android开发中如何调用摄像头的功能

(2011-09-29 19:20:41) 转载
标签:

android

摄像头

surface

callback

picture

拍照

杂谈

分类:3GAndroid学习笔记
我们要调用摄像头的拍照功能,显然 第一步必须加入调用摄像头硬件的权限,拍完照后我们要将图片保存在SD卡中,必须加入SD卡读写权限,所以第一步,我们应该在Android清单文件中加入以下代码 <uses-permission android:name="android.permission.CAMERA"/>//摄像头权限 SD卡读写权限 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 第二步,要将摄像头捕获的图像实时地显示在手机上。 我们是用SurfaceView这个视图组件来实现的,因此在main.xml中加入下列代码 <SurfaceView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/surfaceview" /> 第三步,设置窗口的显示方式 首先获得当前窗口 Window window = getWindow();//得到窗口 接着设置没有标题 requestWindowFeature(Window.FEATURE_NO_TITLE);//没有标题 接着设置全屏 window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏 当然,我们在拍照过程中,屏幕必须一致处于高亮状态,因此接着加入下面代码 window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//设置高亮 至此,我们将窗口的显示方式规定死了,然后才能设置窗口上显示的组件(顺序非常重要) setContentView(R.layout.main); 第四步,设置SurficeView显示控件的属性 找到surficeView surfaceView = (SurfaceView) findViewById(R.id.surfaceview); 设置它的像素为800x600 surfaceView.getHolder().setFixedSize(800, 480); //下面设置surfaceView不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前 surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 第五步,就是为surficeView加入回调方法(callBack) surfaceView.getHolder().addCallback(new SurfaceCallback()); 上面的回调类是我们自己定义的,代码如下 private class SurfaceCallback implements SurfaceHolder.Callback{ @Override public void surfaceCreated(SurfaceHolder holder) { try { camera = Camera.open();//打开硬件摄像头,这里导包得时候一定要注意是android.hardware.Camera WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);//得到窗口管理器 Display display = wm.getDefaultDisplay();//得到当前屏幕 Camera.Parameters parameters = camera.getParameters();//得到摄像头的参数 parameters.setPreviewSize(display.getWidth(), display.getHeight());//设置预览照片的大小 parameters.setPreviewFrameRate(3);//设置每秒3帧 parameters.setPictureFormat(PixelFormat.JPEG);//设置照片的格式 parameters.setJpegQuality(85);//设置照片的质量 parameters.setPictureSize(display.getHeight(), display.getWidth());//设置照片的大小,默认是和 屏幕一样大 camera.setParameters(parameters); camera.setPreviewDisplay(surfaceView.getHolder());//通过SurfaceView显示取景画面 camera.startPreview();//开始预览 isPreview = true;//设置是否预览参数为真 } catch (IOException e) { Log.e(TAG, e.toString()); } }
@Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } @Override public void surfaceDestroyed(SurfaceHolder holder) { if(camera!=null){ if(isPreview){//如果正在预览 camera.stopPreview(); camera.release(); } } } } 第六步,我们必须对按键事件进行监听,如是拍照还是聚焦,代码如下 public boolean onKeyDown(int keyCode, KeyEvent event) {//处理按键事件 if(camera!=null&&event.getRepeatCount()==0)//代表只按了一下 { switch(keyCode){ case KeyEvent.KEYCODE_BACK://如果是搜索键 camera.autoFocus(null);//自动对焦 break; case KeyEvent.KEYCODE_DPAD_CENTER://如果是中间键 camera.takePicture(null, null, new TakePictureCallback());//将拍到的照片给第三个对象中,这里的TakePictureCallback()是自己定义的,在下面的代码中 break; } } return true;//阻止事件往下传递,否则按搜索键会变成系统默认的 } ------------------------------------------------------------------------------------------ private final class TakePictureCallback implements PictureCallback{ public void onPictureTaken(byte[] data, Camera camera) { try { Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); File file = new File(Environment.getExternalStorageDirect ory(),System.currentTimeMillis()+".jpg"); FileOutputStream outputStream = new FileOutputStream(file); bitmap.compress(CompressFormat.JPEG, 100, outputStream); outputStream.close(); camera.stopPreview(); camera.startPreview();//处理完数据之后可以预览 } catch (Exception e) { Log.e(TAG, e.toString()); } } } 注意,代码中有两个回调类,一个是SurfaceCallback(),另外一个是TakePictureCallback(),初学者可能一时难以理解,通俗地讲,前者是用来监视surficeView这个暂时存放图片数据的显示控件的,根据它的显示情况调用不同的方法,包括surfaceCreated(),surfaceChanged(),surfaceDestroyed(),也就不难理解为什么会有这三个回调方法了(注意,在surfaceDestroyed()方法中必须释放摄像头,详细代码参见上方)。TakePictureCallback()是为了监视是否拍照而设计的接口,期中也仅有一个方法,camera将拍照得到的数据传入方法,我们便可以对拍照得到的数据进行进一步处理了。 至此,简单的拍照功能介绍完毕!
源码已经托管在 geakit上面
https://geakit.com/yuchao/android_camera欢迎下载

更多相关文章

  1. 用Fiddler抓取Android、Iphone网络数据包
  2. Android之TextView属性列表
  3. Android动画效果-更新中
  4. Android(安卓)onDraw
  5. 【Android】GridView添加网格线
  6. (原创)EditText软键盘弹出关闭等使用总结
  7. gravity和android:layout_gravity区别
  8. Android各种访问权限Permission详解
  9. Android之TextView------属性大全

随机推荐

  1. 招聘android架构师(北京)
  2. 竞争对手短期内不足以威胁Android地位
  3. Android(安卓)、BlackBerry 文本对齐方式
  4. Android(安卓)TextView 添加下划线的几种
  5. android 中 Message详解
  6. JAVA效率真的很低吗?Android为什么要采用
  7. android 配置ADB环境
  8. android:sharedUserId问题
  9. Android学习(18)Canvas_画布(绘图)
  10. [记录点滴]在Ionic和Android中上传Blob图