原文地址:http://android.xsoftlab.net/training/camera/cameradirect.html

在这节课,我们会讨论如何使用Android框架API来直接控制相机硬件。

直接控制设备的相机拍照或者摄像的代码远比通过其他相机应用来完成要多得多。然而,如果你想构建一个专业的相机应用或者在APP的UI中完全集成相机的话,这节课展示了如何去做。

开启相机对象

直接控制相机的第一步就是获得Camera对象的实例。和Android自身的相机应用相同,推荐访问相机的方式就是在独立的线程打开Camera,这种方式是应对阻塞UI线程的一个好的解决方法。在更加基础化的实现当中,开启相机这一步操作可以推迟到onResume()方法中执行,这样可以促使代码重用并且保持简单的控制流。

如果相机已经正在被其它应用所使用,那么调用Camera.open()方法会抛出一个异常,所以我们需要使用try控制块包裹住它:

private boolean safeCameraOpen(int id) {boolean qOpened = false;try {releaseCameraAndPreview();mCamera = Camera.open(id);qOpened = (mCamera != null);} catch (Exception e) {Log.e(getString(R.string.app_name), "failed to open Camera");e.printStackTrace();}return qOpened;
}
private void releaseCameraAndPreview() {mPreview.setCamera(null);if (mCamera != null) {mCamera.release();mCamera = null;}
}

从API 9开始,相机框架支持多个相机。如果你使用的是过去的API,然后调用了没有参数的open()方法,那么你会获得后置面板的相机。

创建相机预览

拍照通常需要可以使用户能看到目标的预览图。你可以使用SurfaceView来绘制相机传感器捕获到的图像。

预览类

为了可以显示预览,你需要预览类。预览需要一个android.view.SurfaceHolder.Callback接口的实现,它被用来从相机硬件给应用传递图像数据。

class Preview extends ViewGroup implements SurfaceHolder.Callback {SurfaceView mSurfaceView;SurfaceHolder mHolder;Preview(Context context) {super(context);mSurfaceView = new SurfaceView(context);addView(mSurfaceView);// Install a SurfaceHolder.Callback so we get notified when the// underlying surface is created and destroyed.mHolder = mSurfaceView.getHolder();mHolder.addCallback(this);mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);}
...
}

在开始预览之前,必须将预览对象传递给Camera对象,就像下面部分展示的那样。

设置并开始预览

相机实例的创建于相关预览对象创建必须是以指定顺序进行的,从相机对象开始。在下面的代码中,实例化相机对象的过程被封装起来了,所以Camera.startPreview()是可以通过setCamera()调用的,每当用户做了什么事情使相机发生了改变。预览也必须在预览类的surfaceChanged()回调方法重新启动。

public void setCamera(Camera camera) {if (mCamera == camera) { return; }stopPreviewAndFreeCamera();mCamera = camera;if (mCamera != null) {List<Size> localSizes = mCamera.getParameters().getSupportedPreviewSizes();mSupportedPreviewSizes = localSizes;requestLayout();try {mCamera.setPreviewDisplay(mHolder);} catch (IOException e) {e.printStackTrace();}// Important: Call startPreview() to start updating the preview// surface. Preview must be started before you can take a picture.mCamera.startPreview();}
}

修改相机设置

相机设置可以改变相机拍照的方式,从缩放等级到曝光补偿等等。下面的示例只是更改了预览的大小;请查看相机应用的源代码获取更多可能。

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {// Now that the size is known, set up the camera parameters and begin// the preview.Camera.Parameters parameters = mCamera.getParameters();parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);requestLayout();mCamera.setParameters(parameters);// Important: Call startPreview() to start updating the preview surface.// Preview must be started before you can take a picture.mCamera.startPreview();
}

设置预览方向

大多数的相机应用将展示锁定在了水平方向,因为这是相机传感器的自然方向。这个设置并不能阻止你在垂直方向上拍摄,因为相机的方向会被记录到EXIF的头部。setCameraDisplayOrientation()方法允许你改变如何展示预览,而不受图像记录方向的影响。然而,在API14之前,在改变方向之前必须停止预览,然后在重新启动它。

拍照

一旦预览启动后,可以使用Camera.takePicture()方法来拍一张照片。你可以创建Camera.PictureCallback对象和Camera.ShutterCallback对象然后将它们传递给Camera.takePicture()方法。

重启预览

在拍了一张照片之后,你必须在用户拍另一张照片之前重新启动预览。在这个例子中,通过重写快门按钮来完成重启。

@Override
public void onClick(View v) {switch(mPreviewState) {case K_STATE_FROZEN:mCamera.startPreview();mPreviewState = K_STATE_PREVIEW;break;default:mCamera.takePicture( null, rawCallback, null);mPreviewState = K_STATE_BUSY;} // switchshutterBtnConfig();
}

停止预览并且释放相机

一旦你的程序不再需要使用相机,这时就需要执行清理工作。尤其是你需要释放相机对象,否则会使其它程序面临崩溃的风险,包括你自己程序中新的实例。

何时应该停止预览并释放相机呢?好吧,当预览界面被销毁的时候便是停止预览并释放相机的最佳时机,就像下面Preview类中显示的那样:

public void surfaceDestroyed(SurfaceHolder holder) {// Surface will be destroyed when we return, so stop the preview.if (mCamera != null) {// Call stopPreview() to stop updating the preview surface.mCamera.stopPreview();}
}
/*** When this function returns, mCamera will be null.*/
private void stopPreviewAndFreeCamera() {if (mCamera != null) {// Call stopPreview() to stop updating the preview surface.mCamera.stopPreview();// Important: Call release() to release the camera for use by other// applications. Applications should release the camera immediately// during onPause() and re-open() it during onResume()).mCamera.release();mCamera = null;}
}

在上面的课程中,这段程序也是setCamera()方法的一部分,所以实例化一个相机总是从停止这段预览开始的。

Android官方开发文档Training系列课程中文版:调用相机之控制相机相关推荐

  1. Android官方开发文档Training系列课程中文版:目录

    原文地址 : http://android.xsoftlab.net/training/index.html 引言 在翻译了一篇安卓的官方文档之后,我觉得应该做一件事情,就是把安卓的整篇训练课程全部翻 ...

  2. Android官方开发文档Training系列课程中文版:创建自定义View之View的创建

    原文地址:http://android.xsoftlab.net/training/custom-views/index.html 引言 Android框架含有大量的View类,这些类用来显示各式各样 ...

  3. Android官方开发文档Training系列课程中文版:OpenGL绘图之图形绘制

    原文地址:http://android.xsoftlab.net/training/graphics/opengl/draw.html 如果你还不清楚如何定义图形及坐标系统,请移步:Android官方 ...

  4. Android官方开发文档Training系列课程中文版:使用Fragment构建动态UI之Fragment创建

    原文地址:http://android.xsoftlab.net/training/basics/fragments/index.html 导言 为了在Android中创建动态的多面板用户界面,你需要 ...

  5. Android官方开发文档Training系列课程中文版:OpenGL绘图之应用投影与相机视图

    原文地址:http://android.xsoftlab.net/training/graphics/opengl/projection.html##transform 在OpenGL ES环境中,投 ...

  6. Android官方开发文档Training系列课程中文版:性能优化建议

    原文地址:http://android.xsoftlab.net/training/articles/perf-tips.html 本篇文章主要介绍那些可以提升整体性能的微小优化点.它与那些能突然改观 ...

  7. Android官方开发文档Training系列课程中文版:Android的安全建议 .

    转载:http://blog.csdn.net/sahadev_/article/details/52949855 原文地址:http://android.xsoftlab.net/training/ ...

  8. Android官方开发文档Training系列课程中文版:Android的安全建议

    原文地址:http://android.xsoftlab.net/training/articles/security-tips.html Android系统内置的安全策略可以有效的降低应用程序的安全 ...

  9. Android官方开发文档Training系列课程中文版:调用相机之简单摄像

    原文地址:http://android.xsoftlab.net/training/camera/videobasics.html 这节课解释了如何通过已有的相机应用拍摄视频. 假设你的程序含有摄像功 ...

最新文章

  1. http://bbs.phome.net/showthread-13-45519-0.html
  2. 部署Nagios监控系统(一)
  3. phpstrom xdebug配置
  4. 用D触发器构造RAM存储器
  5. 云炬60s看世界20211116
  6. jQuery选择器介绍:基本选择器、层次选择器、过滤选择器、表单选择器
  7. 简洁商城系统后台管理模板
  8. IOC容器特性注入第六篇:利用MVC注入点,把容器启动
  9. 11、进入保护模式-V
  10. 神奇的发明 —— 百叶窗
  11. Java魔法堂:JVM的运行模式
  12. getopt/getopt_long函数使用说明
  13. 假如时光能够倒流, 我会这么学习Java
  14. Powerdesigner下载安装
  15. ubuntu + gcc-linaro-交叉编译环境搭建
  16. ORVIBO 精灵款升级分析
  17. 单面机51小车程序_4千元牛排机实测!小白也能做出星级牛排,在家吃出法式餐厅感觉...
  18. JAVA:日期时间范围查询0点到23点59分59秒之间
  19. leetcode(力扣) 39. 组合总和(回溯 剪枝)
  20. 使用IDEA如何对Java项目进行打包

热门文章

  1. Redis源码分析之工具类util
  2. ubuntu安装codeblock的方法
  3. 重庆大二学生花了6年写出了操作系统
  4. pythongui界面小程序_python界面小程序
  5. 电源管理 解析_智能电源控制箱
  6. java怎么打增量包_eclipse实现JavaWeb应用增量打包
  7. deepin tim(wine)无法安装_浅析国产操作系统深度deepin
  8. 十二、PHP框架Laravel学习笔记——构造器的查询表达式
  9. 一、服务端开发基础(搭建Web服务器、网络基础概念、请求响应流程、配置Apache、静态网站与动态网站)
  10. LeetCode 1848. 到目标元素的最小距离