Android---控制设备照相机
本文译自:http://developer.android.com/training/camera/cameradirect.html
本文中,我们讨论如何使用框架API来直接的控制照相机硬件。
直接控制设备等的照相机,比从既存的照相机应用程序中获取图片或视频需要更多的编码。但是,如果你想要创建一个特殊的照相机应用程序,或者要完全与你的应用程序UI集成,那么本文会告诉你如何来做。
打开Camera对象
直接控制照相机的第一步时获取一个Camera对象实例。跟Android自己的Camera应用程序一样,推荐访问照相机的方法是从Activity的onCreate()回调中启动一个独立的线程来打开Camera对象。这是一种好的做法,因为打开Camera对象时需要一些时间,这可能会阻塞UI线程。打开照相机的一个更基本的实现,可延迟到onResume()回调方法中,这有助于代码重用,并保持了简单的控制流。
如果照相机已经被其他的应用程序使用,那么调用Camera.open()方法时会抛出一个异常,因此我们要代码包在在try…catch块中。
privatebooleansafeCameraOpen(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 Level 9开始,照相机框架支持多个相机。如果你使用传统的API,并调用了没有参数的open()方法,就会获得后置的摄像头。
创建Camera预览
通常在点击快门拍照之前,需要预览图片。因此,你可以使用SurfaceView来描绘照相机所扑获的图像。
创建预览类
要显示预览图像,就需要创建一个预览类,这个类要实现android.view.SurfaceHolder.Callback接口,它用于把照相机硬件的图像数据传递给应用程序。
classPreviewextendsViewGroupimplementsSurfaceHolder.Callback{
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Preview(Context context) {
super(context);
mSurfaceView = new SurfaceView(context);
addView(mSurfaceView);
// Install aSurfaceHolder.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对象。在下面的代码片段中,封装了照相机的初始化过程,这样用户无论何时改变照相机,都可以通过setCamera()方法来调用Camera.startPreviw()方法。这个预览类也必须在预览类的surfaceChanged()回调方法中被重启。
publicvoidsetCamera(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: CallstartPreview() to start updating the preview surface. Preview must
be started before you cantake a picture.
*/
mCamera.startPreview();
}
}
修改照相机设置
照相机设置改变着照相机拍照的方式,从变焦级别到曝光度。这个例子仅改变了预览的尺寸,更多的设置可以看Camera应用程序的源代码。
publicvoidsurfaceChanged(SurfaceHolder holder,int format,int w,int h){
// Now that the size isknown, 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 startupdating the preview surface. Preview must be
started before you can take a picture.
*/
mCamera.startPreview();
}
设置预览方向
大多数照相机应用程序都会把显示锁定到横屏模式,因为这是照相机的自然方向。这种设置不会妨碍你拍摄纵向的照片,因为设备的方向被记录在EXIF头中。使用setCameraDisplayOrientation()方法会改变预览的显示方式,而不会影响到被记录的图像。但是,在API Level 14以前的Android版本,在改变方向之前,必须要先终止预览,然后再重启。
拍照
图像预览被启动之后,就可以使用Camera.takePicture()方法来拍摄照片。你可以创建Camera.PictureCallback和Camera.ShutterCallback对象,并把它们传递给Camera.takePicture()方法。
如果你要连续的抢拍图像,可以创建一个实现onPreviewFrame()方法的Camera.PreviewCallback接口。在这个方法中,你可以只选择预览的帧来拍照,或者建立一个延迟的动作来调用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;
} // switch
shutterBtnConfig();
}
终止预览并释放Camera对象
一旦你的应用程序使用完照相机,就是清理的时机。尤其是你必须释放Camera对象,否则可能会让其他应用程序崩溃,包括你自己的应用程序的新的实例。
在什么时候终止预览并释放Camera对象呢?图像预览类被销毁时是终止图像预览和释放Camera对象的一个相当好的时机,例如:
publicvoidsurfaceDestroyed(SurfaceHolder holder){
// Surface will bedestroyed when we return, so stop the preview.
if (mCamera != null) {
/*
Call stopPreview() to stopupdating the preview surface.
*/
mCamera.stopPreview();
}
}
/**
* When this function returns, mCamera will be null.
*/
private void stopPreviewAndFreeCamera() {
if (mCamera != null) {
/*
Call stopPreview() to stopupdating the preview surface.
*/
mCamera.stopPreview();
/*
Important: Call release() torelease the camera for use by other applications.
Applications should releasethe camera immediately in onPause() (and re-open() it in
onResume()).
*/
mCamera.release();
mCamera = null;
}
}
Android---控制设备照相机的更多相关文章
- Android后门GhostCtrl,完美控制设备任意权限并窃取用户数据
Android系统似乎已经成为世界各地病毒作者的首选目标,每天都有新的恶意软件在感染更多的设备. 这一次,安全公司趋势科技发布警告,他们发现了一个新的Android后门--GhostCtrl Ghos ...
- Android硬件入门-照相机
学习Android不能不学习照相机,现在各种美容相机,微信朋友圈发图,现在升级之后直接下拉就可以照相了,各种艳照的的源头也是照相机,扯远了,有点邪恶了,还是简单学习一下Android中照相机的使用,A ...
- esp8266烧录Html文件,实现内置网页控制设备!
代码地址如下:http://www.demodashi.com/demo/14321.html 一.前言: 这个月也快结束了,时间真快,我服务器知识自学依然在路途中,这几天听到热点网页配置esp826 ...
- iOS / Android 移动设备中的 Touch Icons
上次转载了一篇<将你的网站打造成一个iOS Web App>,但偶然发现这篇文章的内容有些是错误的——准确来说也不是错误,只是不适合自半年前来的情况了(也可以说是iOS7 之后的时间)—— ...
- WebSocket学习笔记IE,IOS,Android等设备的兼容性问
WebSocket学习笔记IE,IOS,Android等设备的兼容性问 一.背景 公司最近准备将一套产品放到Andriod和IOS上面去,为了统一应用的开发方式,决定用各平台APP嵌套一个HTML5浏 ...
- 在android移动设备上登录gmail的时候报password错误解决方法!!!!
今天刚发现的解决的方法:就是登录web端的gmail,查看收件箱应该有no-reply这一帐户给你发过邮件(假设没有,你在移动设备上登录一下gmail).照着邮件里的说明去做,就是生成一个专门应用的p ...
- AllJoyn+Android开发案例-android跨设备调用方法
AllJoyn+Android开发案例-android跨设备调用方法 项目须要涉及AllJoyn开源物联网框架.前面主要了解了一些AllJoyn主要的概念.像总线,总线附件,总线对象,总线接口这种概念 ...
- Android之设备唯一识别
唯一Android的设备ID String androidId = Settings.Secure.getString(getContentResolver(),Settings.Secure.AND ...
- android 控制POS机图文打印(二)
上一篇文章结束了ESC/POS的指令集,没看过的可以去看一下,可以当作工具文档来使用的 android 控制POS机图文打印(一) 这一篇正式介绍如何使用POS机来打印图文信息. 首先介绍一下,ESC ...
随机推荐
- C语言库函数大全及应用实例十二
原文:C语言库函数大全及应用实例十二 [编程资料]C语言库函数大全及应用实例十二 函数名: setrgbpalette ...
- OpenGL+VS2013+WIN7(64)组态
1.下载windows在下面glut安装文件:http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip 2. 拆开发现五个文件 ...
- PHP 2:从一个实例介绍学习方法
原文:PHP 2:从一个实例介绍学习方法 在前面我已经描述了PHP,Apache以及MySQL的安装与配置.下面将介绍一下我如何学习PHP.首先我自己已经有了一些编程经验,就拿我自己而言,已经熟悉C/ ...
- Objective-C和Swift
在项目中同时使用Objective-C和Swift 苹果发布的Swift语言可以和之前的Objective-C语言同时存在于一个项目中. 可能有人会认为是同一个类文件中既可以有Objective-C也 ...
- wsgi-restful-routes具体解释:
感谢朋友支持本博客,欢迎共同探讨交流,因为能力和时间有限,错误之处在所难免,欢迎指正! 如有转载,请保留源作者博客信息. Better Me的博客:blog.csdn.net/tantexian 如需 ...
- 学习PHP时的一些总结(四)
目录的基本操作: 在系统的每个目录下都有两个特殊的目录"."和".." , 分别指示当前目录和当前目录的父目录. dirname() 返回目录的名称 path ...
- JAVA中ClassPath妙用
初学java的人肯定都配置过java三大环境变量 . JAVA_HOME:JDK目录 PATH:jdkbin目录 jre目录 CLASSPATH:一般指向类库lib,也可自定义使用 以下例子是个小例 ...
- iOS基础 - 数据库-SQLite
一.iOS应用数据存取的常用方式 XML属性列表 —— PList NSKeyedArchiver 归档 Preference(偏好设置) SQLite3 Core Data(以面向对象的方式操作数据 ...
- JqGrid帮助文档
JQGrid是一个在jquery基础上做的一个表格控件,以ajax的方式和服务器端通信. JQGrid Demo 是一个在线的演示项目.在这里,可以知道jqgrid可以做什么事情. 下面是转自其他人b ...
- [Usaco2008 Feb]Line连线游戏[暴力][水题]
Description Farmer John最近发明了一个游戏,来考验自命不凡的贝茜.游戏开始的时 候,FJ会给贝茜一块画着N (2 <= N <= 200)个不重合的点的木板,其中第i ...