Android5.0_camera2Api

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。

?
1
public void openCamera (String cameraId, CameraDevice.StateCallback callback, Handler handler)

使用getCameraIdList()来获得可用摄像设备的列表。一旦成功打开相机,CameraDevice.StateCallback中的onOpened(CameraDevice)将被调用。相机设备可以通过调用createCaptureSession()和createCaptureRequest()去设置操作。如果打开相机设备失败,那么设备回调的onError方法将被调用,和后续调用相机设备将抛出一个CameraAccessException。

?
1
public abstract CaptureRequest.Builder createCaptureRequest ( int templateType)

为请求拍照创建一个CaptureRequest.Builder,初始化目标用例的模板。选择最好的设置为特定的相机设备,所以不建议为不同的相机设备重用相同的请求,创建一个builder为具体的设备和模板和根据需要覆盖的设置。

11

?
1
public abstract void createCaptureSession (List<surface> outputs, CameraCaptureSession.StateCallback callback, Handler handler)</surface>

活动着的会话决定了相机的output Surfaces 为每个拍照的要求。给定请求可以使用全部或只有部分的output Surfaces。一旦CameraCaptureSession创建,可以提交capture请求、captureBurst请求,setRepeatingRequest请求或setRepeatingBurst请求。

 

权限

?
1
<uses-permission android:name= "android.permission.CAMERA/" ></uses-permission>

布局

 
?
1
2
3
4
5
6
<!--?xml version= 1.0 encoding=utf- 8 ?-->
<linearlayout android:layout_height= "match_parent" android:layout_width= "match_parent" android:orientation= "vertical" xmlns:android= "http://schemas.android.com/apk/res/android" >
 
     <textureview android:id= "@+id/textureview" android:layout_height= "fill_parent/" android:layout_width= "fill_parent" >
 
</textureview></linearlayout>
 

核心代码

 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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);
     }
}

 原文链接

http://www.2cto.com/kf/201501/367226.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值