?背景
在APP開發(fā)中會有很多業(yè)務(wù)使用到Camera,對于一些基礎(chǔ)的功能,調(diào)用系統(tǒng)的拍攝功能就可以滿足要求。但是需要自定義UI界面時,例如將攝像頭捕獲的視圖展示在頁面上的時候就需要使用到Camera這個類了。
本篇會介紹哪些知識點:
- 什么是SurfaceView?有什么作用?何為雙緩沖機制?
- 相機涉及到方向的概念,如何旋轉(zhuǎn)到正確的方向?
- Camera常用的API及相關(guān)屬性。
- Camera的調(diào)用流程。
- 如何設(shè)置參數(shù),適配預(yù)覽區(qū)域大???
- 如何切換前后攝像頭。
SurfaceView
1、為什么需要SurfaceView
Android系統(tǒng)默認設(shè)定的刷新頻率是60FPS(每隔16.6ms底層會發(fā)出VSYNC信號重繪界面)。但是當頁面繪制過于復(fù)雜,就沒有辦法保證60FPS,則會出現(xiàn)卡頓現(xiàn)象。其中View,ViewGroup,Animator刷新UI界面的動作都是在主線程中執(zhí)行的。如果頁面邏輯過于復(fù)雜時,可能出現(xiàn)頁面卡頓,甚至可能出現(xiàn)ANR問題。為了解決這個問題,便引入了SurfaceView(主要用于游戲、視頻等視覺效果復(fù)雜、刷新率較高的場景)。
SurfaceView的改進是引入了雙緩沖機制和多線程繪制。
2、雙緩沖機制
如果不用畫布,直接在窗口上繪制就是無緩沖繪圖。
使用一個畫布,先將所有的內(nèi)容繪制到畫布上面,后一次性繪制到窗口上就是單緩沖繪圖,其中畫布是一個緩沖區(qū)。
使用兩個畫布,先在一個畫布上面繪制所有的圖像,待繪制完以后在將該畫布上面所有的內(nèi)容拷貝到正式繪制的畫布上,這就是雙緩沖繪圖。
雙緩沖繪圖比單緩沖繪圖的優(yōu)勢在于 拷貝比直接繪制的效率要高。
在SurfaceView中,一般會開啟一個新的線程,然后在新線程中通過SurfaceHolder的lockCanvas方法獲取得Canvas(緩沖畫布)進行繪制,繪制完以后在通過SurfaceHolder的unlockCanvasAndPost方法釋放canvas并提交修改,下次刷新顯示新內(nèi)容即可。
3、Surface、SurfaceView、SurfaceHolder三者的關(guān)系
它們?nèi)呤堑湫偷腗VC模型。
Surface:Model層,持有緩沖畫布Canvas和繪圖內(nèi)容相關(guān)的各種信息。
SurfaceView:View層,與用戶進行交互,將Surface的內(nèi)容顯示給用戶。
SurfaceHolder:Controller層,通過SurfaceHolder控制Surface中的數(shù)據(jù)。
相機方向
1、自然方向
人自然站立的方向。
2、設(shè)備方向
設(shè)備方向是設(shè)備與自然方向的順時針夾角,例如手機豎著拿正對屏幕的方向是手機的自然方向,即設(shè)備方向為0°,如果手機橫著拿正對屏幕且頂部在右邊,則設(shè)備方向為90°。以此類推。
獲取方向可以通過
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
或者通過OrientationEventListener 監(jiān)聽旋轉(zhuǎn)。
3、攝像頭方向
手機Camera的圖像數(shù)據(jù)都是來自于攝像頭硬件的圖像傳感器(Image Sensor),攝像頭的方向取決于圖像傳感器的安裝方向。安裝之后,有一個默認的取景方向,且不會被改變。但為什么手機旋轉(zhuǎn)以后預(yù)覽畫面也會跟著旋轉(zhuǎn)到自然方向呢?是因為Android系統(tǒng)底層根據(jù)當前手機屏幕的方向?qū)D像Sensor采集到的數(shù)據(jù)進行了旋轉(zhuǎn)處理,然后才送給顯示系統(tǒng)。
手機后置攝像頭一般都是橫屏安裝的。
CameraInfo.orientation 表示相機圖像的方向。它的值是相機圖像順時針旋轉(zhuǎn)到自然方向的角度。
4、預(yù)覽方向
通過setDisplayOrientation設(shè)置預(yù)覽方向,默認情況是0°,即預(yù)覽方向與攝像頭方向一致,對于橫屏應(yīng)用,不需要設(shè)置預(yù)覽方向。而對于豎屏應(yīng)用則設(shè)置預(yù)覽方向旋轉(zhuǎn)90,與手機屏幕方向保持一致,這樣才能得到正確的預(yù)覽方向。
5、拍攝方向
相機采集圖像后需要進行順時針旋轉(zhuǎn)的角度,即相機屬性的orientation的值。當點擊拍照時,得到的照片方向不一定與預(yù)覽方向一致,因為通過setDisplayOrientation僅僅修改了預(yù)覽圖像的方向,不會影響到實際拍攝圖像的方向,需要修改拍攝圖像方向可以通過camera.setRotation實現(xiàn)。
適配預(yù)覽區(qū)域大小
一般手機會提供多個預(yù)覽和拍照尺寸,通過接口getSupportedPreviewSizes和getSupportedPictureSizes可以獲得這些尺寸列表。如果previewSize比例與預(yù)覽(SurfaceView)比例不一致,則看到的預(yù)覽圖像會變形拉伸。如何適配不同預(yù)覽區(qū)大小解決拉伸問題,一般有2種方案:
一是根據(jù)previewSize比例修改SurfaceView的比例,調(diào)整預(yù)覽區(qū)比例(只調(diào)整寬或高)為預(yù)覽尺寸比例,從而使圖像不發(fā)生變形。
二是根據(jù)SurfaceView大小固定,然后根據(jù)其比例選擇最佳的(比例最接近的)預(yù)覽尺寸。
切換前后攝像頭
通過camera.open(int cameraId)獲取camera實例時便可以通過cameraId指定攝像頭。
Camera.CameraInfo.CAMERA_FACING_FRONT = 1??前置攝像頭
Camera.CameraInfo.CAMERA_FACING_BACK = 0?后者攝像頭
注:切換攝像頭便是重新獲取新的camera實例,所以在切換時需要將前一個實例釋放掉。文章來源:http://www.zghlxwxcb.cn/news/detail-772225.html
Camera常見的API及屬性
camera是Android攝像頭硬件的相機類,位于硬件包"android.hardware.Camera"下,它主要用于攝像頭捕獲照片、啟動/停止預(yù)覽圖片、拍照、獲取視頻幀等。文章來源地址http://www.zghlxwxcb.cn/news/detail-772225.html
camera常見的API
- static Camera open():打開camera,返回一個camera實例。
- static Camera open(int cameraId):根據(jù)cameraId打開camera,返回一個camera實例。
- final void release():釋放掉camera的資源。
- static int getNumberOfCameras():獲取當前設(shè)備支持camera硬件個數(shù)。
- Camera.Parameters getParameters():獲取camera的各項參數(shù)設(shè)置類。
- void setParameters(Camera.Parameters params):通過param將camera的各項參數(shù)寫入到camera中。
- final void setDisplayOrientation(int degrees):設(shè)置預(yù)覽的旋轉(zhuǎn)度。
- final void setPreviewDisplay(SurfaceHolder holder):設(shè)置camera預(yù)覽的surfaceHolder。
- final void startPreview():開始camera的預(yù)覽。
- final void stopPreview():結(jié)束camera的預(yù)覽。
- final void autoFocus(Camera.AutoFocusCallback cb):自動對焦。
- final takePicture(Camera.ShutterCallback shutter,Camera.PictureCallback raw,Camera.PictureCallback jpeg):拍照。
- final void lock():鎖定Camera硬件,使其他應(yīng)用無法訪問
- final void unlock():解鎖Camera硬件,使其他應(yīng)用可以訪問。
到了這里,關(guān)于Android學(xué)習(xí)筆記 - Camera(1)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!