㈠ android如何判斷手機攝像頭是否倒置或旋轉角度
攝像頭沒有裝倒這一說,說明你們開發的程序還是有瑕疵的,都是程序設定的,就好比你拿著手機拍照,不管你怎麼旋轉手機,圖像始終是朝下的,給你個提示:重力感應。
㈡ Android 系統原生相機API角度原理與適配
雖然Camera作為第一代原生android所提供的相機類一直被開發者甚至Google官方開發人員所詬病,但為了兼容和適配Android版本5.0以下的App應用,我們別無選擇。因此,有了本篇文檔詳細闡述1.0版的Camera 是如何使用的。本篇使用的是SurfaceView與Camera類。
文檔下文會在拍照流程中的不同的階段應用到上述四個角度,而「終端自然方向」貫穿整個流程當中。這一個方向、四個角度非常重要,缺一不可,是支撐相機Camera 系列API的關鍵。在設計NXDesign的相機項目中,經過對官方文檔的研讀和各路資料的調研之後發現,我們在網路上查到的博客類相關資料有80%的實現方式是存在問題的,當然,這也可以歸咎於該API其本身確實不好用,如果不對源碼注釋進行仔細研究,很容易對開發者產生誤導。
更加准確的說,相機的生命周期是依託於SurfaceView的創建和銷毀來完成的。SurfaceView的作用是提供相機內容的實時預覽。我們需要在surfaceview創建好之後打開相機使用相機資源,在surfaceview被銷毀後釋放相機資源。
surfaceview 提供了holder機制向調用方通知surfaceview的變化時機,為了在不同的時機對相機資源做不同的事情,需要調用SurfaceHolder.addCallback()方法。
現在的Android手機一般會有多個攝像頭,但根據其方向可以歸為兩類: CAMERA_FACING_BACK 和 CAMERA_FACING_FRONT 。在打開攝像頭之前,首先需要獲取相機資源,判斷相機個數 Camera.getNumberOfCameras() 。每個相機對應一個CameraInfo,它的定義如下:
這里涉及到一個重要概念:相機圖像感測器(camera sensor),想要理解上述注釋的含義,就需要先理解下圖內容。
左圖是通常情況下,我們對view的x y方向的認知,以屏幕的左上角為原點向右為x正方向,向下為y正方向;但是,右圖描述的是絕大多數情況下, 相機圖像感測器 的起始位置和方向判定。與view不同的是,感測器以手機屏幕在自然方向上的右上角為原點,向下為x正方向,向左為y正方向。因此,我們理解上述注釋就不難了。如果相機自帶的感測器頂部與終端自然方向(手機屏幕的硬體方向,一般手機都是豎直方向,也就是文檔中說的naturally tall screen)的右邊緣一致,則這個值就是90度。如果前置攝像頭感測器的頂部與手機自然方向一致,則這個值就是270度。
當我們定義startCamera()方法時,要做5件事情,1.遍歷攝像頭cameraId,找到想要打開的攝像頭(前置還是後置);2.獲取攝像頭信息,主要獲取orientation;3. 設置相機DisplayOrientation 4.設置相機參數,主要是寬高比、對焦模式、圖片格式、setRotation等。5. 向camera設置surfaceview.viewholder,並且startPreview。主要邏輯如下:
拿到cameraInfo.orientation之後,要調用camera.setDisplayOrientation設置進去,保證通過surfaceview預覽到的取景跟當前的手機方向保持一致,但是,setDisplayOrientation設置的其實是經過兩個角度計算之後的復合角度,而並不單純是cameraInfo.orientation。正確的做法是這樣的:先獲取手機屏幕的旋轉方向,然後與cameraInfo.orientation加和得到最終角度。通常情況下,如果我們設置相機為portrait,則不用考慮rotation。這也是為什麼絕大部分網路資料中都會粗暴的寫入一個90度完事兒而並沒有解釋這么做的道理。
調用camera.takePicture(null, null, pictureCallback)
這里需要做的僅僅是將callback中返回的data存儲為File。需要注意的是,data中會包含setRotation()方法中的角度信息,因此如果直接使用Bitmap工具類生成bitmap,再進行存儲或者展示,生成出來的圖像其實是缺失了旋轉角度的原始方向,這十有八九會發生圖像展示角度錯誤的情況。因此,需要直接保存,再通過Exif工具類讀取File中的角度信息(當然Exif工具類就是為了讀取File中的各種信息而生的,比如拍照時間、經緯度等等)。
基於Camera API,
surfaceview的預覽需要setDisplayOrientation(),入參角度與CameraInfo.orientation(感測器偏角)和WindowManager.default.displayOrientation(屏幕旋轉角度)兩個角度有關。
相機拍照前需要setRotation(),入參角度與CameraInfo.orientation(感測器偏角)和OrientationEventListener返回的orientation(終端自然角度偏角)有關,二者的換算結果就是圖像寫入偏角,該偏角意味著圖像被順時針旋轉該角度就能夠回正展示。
㈢ Android 如何切換前後攝像頭
三星手機切換前後攝像頭的方法:請您打開手機照相機,找到一個左右箭頭的小相機圖標,點擊該圖標切換前後攝像頭。