Android -- Camera2(Android5.0)
Camera2
Camera2是Android5.0中的其中一个新的特性,新的API。与原来的camera API相比,不同之处在于:
- 原生支持RAW照片输出
- 突发拍摄模式
制约拍照速度的不再是软件而是硬件。以Nexus 5为例,分辨率全开下Andorid L的连拍速度可达到30fps。
- 全手动控制
快门、感光度、对焦、测光、硬件视频防抖等多种参数都被整合到了新的API内。新的API中添加的手动控制功能列表:
- 感光度
- 手动对焦/AF开关
- AE/AF/AWB模式
- AE/AWB锁
- 硬件视频防抖
- 连续帧
干货
Camera2 程序逻辑与原Camera有很大不同。
CameraManager,系统服务,通过 CameraManager去获得camera设备对象。CameraDevices提供描述相机硬件设备支持可用的和输出的参数,这些信息通过 CameraCharacteristics获得,CameraCharacteristics又是从 getCameraCharacteristics(cameraId)获得,通过freamwork中的源码发现,其实这里就是直接调用的Camera API接口。
通过camera拍照,应用首先要创建由相机设备的输出surface组成的拍照会话,createCaptureSession(List, CameraCaptureSession.StateCallback, Handler)。每个surface必须预先设置适当的大小和格式去匹配相机设备的可支持的大小和格式。一个目标surface可以从不同的类中获取,包括SurfaceView,SurfaceTexture via Surface(SurfaceTexture), MediaCodec, MediaRecorder, Allocation, and ImageReader.
一旦请求被建立,他可以交给活动的拍照会话:一次拍照(one-shot )或者无止境连续拍照或预览(Repeating)。两种方法都有一个其他的方式:接受一系列的请求作为burst拍照/重复burst。
public void openCamera (String cameraId, CameraDevice.StateCallback callback, Handler handler)
使用getCameraIdList()来获得可用摄像设备的列表。一旦成功打开相机,CameraDevice.StateCallback中的onOpened(CameraDevice)将被调用。相机设备可以通过调用createCaptureSession()和createCaptureRequest()去设置操作。如果打开相机设备失败,那么设备回调的onError方法将被调用,和后续调用相机设备将抛出一个CameraAccessException。
public abstract CaptureRequest.Builder createCaptureRequest (int templateType)
为请求拍照创建一个CaptureRequest.Builder,初始化目标用例的模板。选择最好的设置为特定的相机设备,所以不建议为不同的相机设备重用相同的请求,创建一个builder为具体的设备和模板和根据需要覆盖的设置。

public abstract void createCaptureSession (List<Surface> outputs, CameraCaptureSession.StateCallback callback, Handler handler)
活动着的会话决定了相机的output Surfaces 为每个拍照的要求。给定请求可以使用全部或只有部分的output Surfaces。一旦CameraCaptureSession创建,可以提交capture请求、captureBurst请求,setRepeatingRequest请求或setRepeatingBurst请求。
权限
<uses-permission android:name="android.permission.CAMERA"/>
布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <TextureView
android:id="@+id/textureview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/> </LinearLayout>
核心代码
public class CameraFragment extends Fragment implements TextureView.SurfaceTextureListener {
private TextureView mPreviewView;
private Handler mHandler;
private HandlerThread mThreadHandler;
private Size mPreviewSize;
private CaptureRequest.Builder mPreviewBuilder;
public static CameraFragment newInstance() {
return new CameraFragment();
}
@SuppressWarnings("ResourceType")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.camera_frag, null);
initLooper();
initUIAndListener(v);
return v;
}
//很多过程都变成了异步的了,所以这里需要一个子线程的looper
private void initLooper() {
mThreadHandler = new HandlerThread("CAMERA2");
mThreadHandler.start();
mHandler = new Handler(mThreadHandler.getLooper());
}
//可以通过TextureView或者SurfaceView
private void initUIAndListener(View v) {
mPreviewView = (TextureView) v.findViewById(R.id.textureview);
mPreviewView.setSurfaceTextureListener(this);
}
@SuppressWarnings("ResourceType")
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
try {
//获得CameraManager
CameraManager cameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
//获得属性
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics("0");
//支持的STREAM CONFIGURATION
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
//显示的size
mPreviewSize = map.getOutputSizes(SurfaceTexture.class)[0];
//打开相机
cameraManager.openCamera("0", mCameraDeviceStateCallback, mHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
//TextureView.SurfaceTextureListener
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
try {
startPreview(camera);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onDisconnected(CameraDevice camera) {
}
@Override
public void onError(CameraDevice camera, int error) {
}
};
//开始预览,主要是camera.createCaptureSession这段代码很重要,创建会话
private void startPreview(CameraDevice camera) throws CameraAccessException {
SurfaceTexture texture = mPreviewView.getSurfaceTexture();
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface surface = new Surface(texture);
try {
mPreviewBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
} catch (CameraAccessException e) {
e.printStackTrace();
}
mPreviewBuilder.addTarget(surface);
camera.createCaptureSession(Arrays.asList(surface), mSessionStateCallback, mHandler);
}
private CameraCaptureSession.StateCallback mSessionStateCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
try {
updatePreview(session);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
}
};
private void updatePreview(CameraCaptureSession session) throws CameraAccessException {
session.setRepeatingRequest(mPreviewBuilder.build(), null, mHandler);
}
}
我是天王盖地虎的分割线
源码:https://github.com/pinguo-yuyidong/Camera2
Android -- Camera2(Android5.0)的更多相关文章
- Android Camera2 Opengles2.0 实时滤镜(冷暖色/放大镜/模糊/美颜)
https://blog.csdn.net/keen_zuxwang/article/details/78363464 demo: http://download.csdn.net/download/ ...
- Android Material Design Ripple Effect在Android5.0(SDK=21)以下Android版本崩溃问题解决
Android Material Design Ripple Effect在Android5.0(SDK=21)以下Android版本崩溃问题解决 附录1的Android Ripple Effect水 ...
- Android自定义组件系列【14】——Android5.0按钮波纹效果实现
今天任老师发表了一篇关于Android5.0中按钮按下的波纹效果实现<Android L中水波纹点击效果的实现>,出于好奇我下载了源代码看了一下效果,正好手边有一个Nexus手机,我结合实 ...
- Android开发之设置应用设置全屏的两种解决方法 兼容android5.0等两种解决方法
在开发中我们经常需要把我们的应用设置为全屏,有两种方法,一中是在代码中设置,另一种方法是在配置文件里改! 一.在代码中设置: 代码如下: package com.android.tutor; imp ...
- android5.0联系人 sort_key改成phonebook_label
项目中用到了联系人根据字母排序,在android4.0手机上是可以的,但是在android4.4以上的手机排序是乱的,一般字母排序都是根据sort_key这个拼音进行排序,而android5.0这个字 ...
- 【Android】Anroid5.0+新控件---酷炫标题栏的简单学习
Android5.0+推出的新控件感觉特别酷,最近想模仿大神做个看图App出来,所以先把这些新控件用熟悉了. 新控件的介绍.使用等等网上相应的文章已经特别多了,题主也没那能力去写篇详解出来,本篇随笔记 ...
- 一个Activity掌握Android5.0新控件 (转)
原文地址:http://blog.csdn.net/lavor_zl/article/details/51279386 谷歌在推出Android5.0的同时推出了一些新控件,Android5.0中最常 ...
- 【转】Android M(6.0) 权限爬坑之旅
原文网址:https://yanlu.me/android-m6-0-permission-chasm/ 有一篇全面介绍Android M 运行时权限文章写的非常全面:Android M 新的运行时权 ...
- Windows8下PhoneGap 4 + Android Studio 1.0 + VS2013配置指南
1.准备工作 安装JDK1.6+,设置环境变量 JAVA_HOME C:\Program Files\Java\jdk1.5.0_07 CLASSPATH .;%JAVA_HOME%\lib Path ...
随机推荐
- Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) E. Tree Folding 拓扑排序
E. Tree Folding 题目连接: http://codeforces.com/contest/765/problem/E Description Vanya wants to minimiz ...
- JS在在线人数和访问人数
var date=new Date();var expiresDays=10;var count=1500+parseInt(date.getTime()/1000)-parseInt(date.ge ...
- mongodb用mongoose查库的对象,不能增加属性
node + koa2 + mongodb 写了一个给前端的接口 如果不是写这个接口,这辈子都发现不了mongodb里这个大坑 mongoose 是个ODM(Object Document Mappe ...
- FireDAC 下的 Sqlite [8] - 自定义函数
Sqlite 本身没有这个功能, FireDAC 通过 TFDSQLiteFunction 增加了该功能; 尽管通过某些 SQL 语句或通过视图也可以达到类似效果, 但函数会更灵活些. 本例先建了一个 ...
- Tomcat无法启动8005端口,提示:java.net.ConnectException: 拒绝连接 (Connection refused)
修改$JAVA_HOME/jre/lib/security/Java.security 文件中 securerandom.source 配置项: 将 securerandom.source=file: ...
- C#——性能计数器
简要Windows性能监视器: 打开Windows性能监视器的步骤如下: 开始→运行→perfmon→确定 在这里我们可以选择添加我们要监控的计数器,比如:cpu使用率.内存使用量等,作为asp.ne ...
- 自定义两行可左右滑动的GridView
效果图: xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:an ...
- .NET轻量级DBHelpers数据访问组件
一.摘要 一说到ADO.NET大家可能立刻想到的就是增.删.改.查(CRUD)操作,然后再接就想到项目中的SQLHelper.没错本课分享课阿笨给大家带来的是来源于github上开源的DAO数据库访问 ...
- NSArray进行汉字排序
由于NSArray并不直接支持对汉字的排序,这就要通过将汉字转换成拼音完毕按A~Z的排序,这看起来是个头疼的问题.由于牵扯到汉字转为拼音,kmyhy给出一个较易实现的方法,获取汉字的首字的首字母,如将 ...
- 委托、Lambda表达式、事件系列07,使用EventHandler委托
谈到事件注册,EventHandler是最常用的. EventHandler是一个委托,接收2个形参.sender是指事件的发起者,e代表事件参数. □ 使用EventHandler实现猜拳游戏 使用 ...