Android Camera的进化史
Part1: ?Camera1(Android的傻瓜機(jī))
- Camera1 的開發(fā)中,打開相機(jī),設(shè)置參數(shù)的過程是同步的,就跟用戶實(shí)際使用camera的操作步驟一樣。但是如果有耗時(shí)情況發(fā)生時(shí),會導(dǎo)致整個(gè)調(diào)用線程等待;
- 開發(fā)者如果想要個(gè)性化設(shè)置camera效果,無法手動(dòng)設(shè)置調(diào)整參數(shù),需要依靠第三方算法對于回調(diào)的數(shù)據(jù)進(jìn)行處理(NV21)。而且不同手機(jī)的回調(diào)數(shù)據(jù)效果都是不一樣的,采用第三方算法調(diào)整,通常效果不好;
- 開發(fā)者所能獲取的Camera狀態(tài)信息有限;
camera1 的開發(fā)過程比較簡單,對于常規(guī)視頻采集,如果只要一般的預(yù)覽功能,是沒問題的,然而如果想要挖掘Camera更多的功能,camera1無法滿足,于是有了camera2.
Part2: Camera2(Android的單反)
- Camera2 的開發(fā)中,camera的生命周期都是異步的,即發(fā)送請求,等待回調(diào)的client-service模式;
- 系統(tǒng): Android L+;
- 這里的關(guān)鍵回調(diào)主要是三個(gè):
(1)CameraDevice.StateCallback ///比如線程A發(fā)送打開相機(jī)請求, 線程B中收到相機(jī)狀態(tài)回調(diào),線程B中與cameraDevice建立會話,設(shè)置參數(shù),數(shù)據(jù)回調(diào)處理;
(2)CameraCaptureSession.StateCallback ///與CameraDevice建立會話后,收到的會話狀態(tài)回調(diào);
(3)ImageReader.OnImageAvailableListener?// 開發(fā)者可以直接獲取并且操作的數(shù)據(jù)回調(diào);
- 通過跟相機(jī)建立的會話,可以更加精細(xì)的調(diào)整Camera參數(shù):比如ISO感光度,曝光時(shí)間,曝光補(bǔ)償……;
- 如果開發(fā)者想要更多自己的定制,也可以直接使用回調(diào)數(shù)據(jù)(YUV488);
- MultiCamera的支持;
Multi-Camera 的支持:?
- 系統(tǒng):Android P+;
- 目前支持的multi-camera的設(shè)備: Pixel 3, mate20 系列;
- Multi-Camera 新功能:
(1)更好的光學(xué)變焦:之前的方式通常使用數(shù)碼變焦或者是單個(gè)攝像頭的光學(xué)變焦來達(dá)到變焦的效果, 通過多攝像頭的變焦方式,無論遠(yuǎn)景還是近景,都可以采到更好質(zhì)量的數(shù)據(jù)。
(2)景深計(jì)算:通過多攝像頭的景深不同,可以得到每一幀圖片中不同物體的景深,從而更好的區(qū)分前景或者后景。應(yīng)用范圍:背景虛化,背景替換,現(xiàn)實(shí)增強(qiáng)。
(3)更廣的視角:更廣的視角帶來魚眼鏡頭的畸變效果,畸變矯正功能。
CaptureRequest.DISTORTION_CORRECTION_MODE
(4)人臉識別功能:跟畸變效果一樣,自帶人臉識別功能。應(yīng)用范圍:人臉裁剪,人臉特效。
CaptureResult.STATISTICS_FACE_DETECT_MODE
(5)多路流同時(shí)采集:場景包括(單攝像頭輸出多流,多攝像頭輸出多流)
normalOutputConfigImageReader.setPhysicalCameraId(normalLensId)
wideOutputConfigImageReader.setPhysicalCameraId(wideAngleId)
params.previewBuilder?.addTarget(normalSurface)
params.previewBuilder?.addTarget(wideSurface)
- 帶來的問題:更耗內(nèi)存,更耗電
- 趨勢:單個(gè)手機(jī)中,支持更多的攝像頭
Camera2 雖然給開發(fā)者帶來了相機(jī)的更多可玩性,然而android的碎片化,導(dǎo)致很多設(shè)備的兼容性問題頻繁發(fā)生。尤其國內(nèi)的手機(jī)廠商,對camera2 的支持程度各不相同,
所以Camera2的開發(fā)難度更多的是在兼容性,于是有了CameraX。
Part3: CameraX(Android的個(gè)性化相機(jī))
- 系統(tǒng):Android L+
- Jetpack 內(nèi)的一套Camera開發(fā)支持庫。
- 特點(diǎn):
- 更簡單易用的API,更少的代碼量,使開發(fā)者更專注業(yè)務(wù)的個(gè)性化實(shí)現(xiàn)。比如:對采集到圖片做分析處理。
- 更好的兼容性,減少不同設(shè)備適配煩惱:包括寬高比、屏幕方向、旋轉(zhuǎn)、預(yù)覽大小和高分辨率圖片大小。
- 數(shù)據(jù)分析: 開發(fā)者依然可以對數(shù)據(jù)進(jìn)行個(gè)性化處理。
- 第三方Camera特效拓展:對于一些手機(jī)廠商特定實(shí)現(xiàn)的camera特效,開發(fā)者也可以使用。
- Code Sample 1(CameraX的常規(guī)使用)?
(1)CameraX 創(chuàng)建UseCaseConfig; //已經(jīng)提前實(shí)現(xiàn)好各種UseCase(preview,ImageCapture,ImageAnalysis...)對應(yīng)不同的UseCaseConfig, 開發(fā)者重要專注自己的業(yè)務(wù)。
(2)創(chuàng)建對應(yīng)UseCase
(3)CameraX bindToLifecycle(LifeCycleOwner, UseCases)?//CameraX 會觀察生命周期以確定何時(shí)打開相機(jī)、何時(shí)創(chuàng)建拍攝會話以及何時(shí)停止和關(guān)閉。
(4)CameraX unbind(UseCase)
6.?Code Sample 2(CameraX的特效拓展)
Part4: 開發(fā)二三事
Rotation:Camera1 和 Camera2 上來的數(shù)據(jù)角度是不一樣;Camera2的某些設(shè)備,前置攝像頭的sensor orientation是不一致的。一般前置270,后置90。
- 相機(jī)角度獲取:
Camera1:CameraInfo.orientation
Camera2:CameraCharacteristics.SENSOR_ORIENTATION - 手機(jī)角度:
通過傳感器獲取:
(SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
- APP角度獲取:
通過WindowManager:
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);?
Coordinate system:Camera1 和 Camera2的坐標(biāo)系不一樣,所以在View坐標(biāo)和相機(jī)坐標(biāo)系轉(zhuǎn)換的時(shí)候是不一樣的。
Camera1的坐標(biāo)系:
Camera2的坐標(biāo)系:
Render:
YUV數(shù)據(jù)的紋理映射:
- glGenTextures(...);///create glTexture id
- glBindTextures(...);?//bind texture into Gl context
- glTexParameterf(...);//filter param set when Texture Maping
- glTexImage2D(...);?// load YUV data
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0)?//unBinde Texture
?
離屏渲染:
- glGenFramebuffers(...);
- glBindFramebuffer(...);
- glFramebufferTexture2D(...); //bind?frame buffer with Texture
- glDrawArrays(...);?//draw texture data into?frame buffer?
- glReadPixels(...);?//get frame buffer data for snapshot.
- glBindFramebuffer(...);// unbind texture
GLSL:
- glCreateShader(...);
- glShaderSource(...);//bind Vertex/Segment program with Vertex/Segment object
- glCompileShader(...);
- glCreateProgram(...);
- glAttachShader(...);///attach?Vertex/Segment object with Shader program
- glLinkProgram(...);
- glUseProgram(...);?//draw
總結(jié):
Camera的數(shù)據(jù)輸出格式:
| ? | ByteBuffer | Texture | FPS | Resolution |
| Camera1 | NV21 | Support | 30 | 1080P |
| Camera2 | I420 | Support | 30 | 1080P |
?
?
?
?
對于Texture的數(shù)據(jù)采集,直接在GPU中創(chuàng)建Texture Object并拿到Texture id,Camera 的采集數(shù)據(jù)直接交給texture object 進(jìn)行離屏渲染。
對于Byte Buffer的數(shù)據(jù)采集,需要將YUV數(shù)據(jù)加載到紋理object,再進(jìn)行離屏渲染。
兩種比較起來,直接用Texture 數(shù)據(jù)進(jìn)行采集,可以省去cpu往GPU的數(shù)據(jù)拷貝過程,更高效。
?
Part5:Camera Next Plane:
?添加自己的CameraX功能
Reference :
https://developer.android.com/training/camerax/architecture;
https://source.android.com/devices/camera/multi-camera;
https://developer.android.com/guide/topics/media/camera
https://github.com/google/basicbokeh
https://github.com/IvenFu/Android-MultiCamera
https://medium.com/androiddevelopers/getting-the-most-from-the-new-multi-camera-api-5155fb3d77d9
?
?
?
總結(jié)
以上是生活随笔為你收集整理的Android Camera的进化史的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网易云信10月大事记
- 下一篇: 技术实践 | Android 设备音视频