① android Camera2 教程 · 第一章 · 概覽
從 Android 5.0 開始,Google 引入了一套全新的相機框架 Camera2(android.hardware.camera2)並且廢棄了舊的相機框架 Camera1(android.hardware.Camera)。作為一個專門從事相機應用開發的開發者來說,這一刻我等了太久了,Camera1 那寥寥無幾的 API 和極差的靈活性早已不能滿足日益復雜的相機功能開發。Camera2 的出現給相機應用程序帶來了巨大的變革,因為它的目的是為了給應用層提供更多的相機控制許可權,從而構建出更高質量的相機應用程序。本文是 Camera2 教程的開篇作,本章將介紹以下幾個內容:
Camera2 的 API 模型被設計成一個 Pipeline(管道),它按順序處理每一幀的請求並返回請求結果給客戶端。下面這張來自官方的圖展示了 Pipeline 的工作流程,我們會通過一個簡單的例子詳細解釋這張圖。
為了解釋上面的示意圖,假設我們想要同時拍攝兩張不同尺寸的圖片,並且在拍攝的過程中閃光燈必須亮起來。整個拍攝流程如下:
一個新的 CaptureRequest 會被放入一個被稱作 Pending Request Queue 的隊列中等待被執行,當 In-Flight Capture Queue 隊列空閑的時候就會從 Pending Request Queue 獲取若干個待處理的 CaptureRequest,並且根據每一個 CaptureRequest 的配置進行 Capture 操作。最後我們從不同尺寸的 Surface 中獲取圖片數據並且還會得到一個包含了很多與本次拍照相關的信息的 CaptureResult,流程結束。
相機功能的強大與否和硬體息息相關,不同廠商對 Camera2 的支持程度也不同,所以 Camera2 定義了一個叫做 Supported Hardware Level 的重要概念,其作用是將不同設備上的 Camera2 根據功能的支持情況劃分成多個不同級別以便開發者能夠大概了解當前設備上 Camera2 的支持情況。截止到 Android P 為止,從低到高一共有 LEGACY、LIMITED、FULL 和 LEVEL_3 四個級別:
相機的所有操作和參數配置最終都是服務於圖像捕獲,例如對焦是為了讓某一個區域的圖像更加清晰,調節曝光補償是為了調節圖像的亮度。因此,在 Camera2 裡面所有的相機操作和參數配置都被抽象成 Capture(捕獲),所以不要簡單的把 Capture 直接理解成是拍照,因為 Capture 操作可能僅僅是為了讓預覽畫面更清晰而進行對焦而已。如果你熟悉 Camera1,那你可能會問 setFlashMode() 在哪? setFocusMode() 在哪? takePicture() 在哪?告訴你,它們都是通過 Capture 來實現的。
Capture 從執行方式上又被細分為【單次模式】、【多次模式】和【重復模式】三種,我們來一一解釋下:
CameraManager 是一個負責查詢和建立相機連接的系統服務,它的功能不多,這里列出幾個 CameraManager 的關鍵功能:
CameraCharacteristics 是一個只讀的相機信息提供者,其內部攜帶大量的相機信息,包括代表相機朝向的 LENS_FACING ;判斷閃光燈是否可用的 FLASH_INFO_AVAILABLE ;獲取所有可用 AE 模式的 CONTROL_AE_AVAILABLE_MODES 等等。如果你對 Camera1 比較熟悉,那麼 CameraCharacteristics 有點像 Camera1 的 Camera.CameraInfo 或者 Camera.Parameters 。
CameraDevice 代表當前連接的相機設備,它的職責有以下四個:
熟悉 Camera1 的人可能會說 CameraDevice 就是 Camera1 的 Camera 類,實則不是,Camera 類幾乎負責了所有相機的操作,而 CameraDevice 的功能則十分的單一,就是只負責建立相機連接的事務,而更加細化的相機操作則交給了稍後會介紹的 CameraCaptureSession。
Surface 是一塊用於填充圖像數據的內存空間,例如你可以使用 SurfaceView 的 Surface 接收每一幀預覽數據用於顯示預覽畫面,也可以使用 ImageReader 的 Surface 接收 JPEG 或 YUV 數據。每一個 Surface 都可以有自己的尺寸和數據格式,你可以從 CameraCharacteristics 獲取某一個數據格式支持的尺寸列表。
CameraCaptureSession 實際上就是配置了目標 Surface 的 Pipeline 實例,我們在使用相機功能之前必須先創建 CameraCaptureSession 實例。一個 CameraDevice 一次只能開啟一個 CameraCaptureSession,絕大部分的相機操作都是通過向 CameraCaptureSession 提交一個 Capture 請求實現的,例如拍照、連拍、設置閃光燈模式、觸摸對焦、顯示預覽畫面等等。
CaptureRequest 是向 CameraCaptureSession 提交 Capture 請求時的信息載體,其內部包括了本次 Capture 的參數配置和接收圖像數據的 Surface。CaptureRequest 可以配置的信息非常多,包括圖像格式、圖像解析度、感測器控制、閃光燈控制、3A 控制等等,可以說絕大部分的相機參數都是通過 CaptureRequest 配置的。值得注意的是每一個 CaptureRequest 表示一幀畫面的操作,這意味著你可以精確控制每一幀的 Capture 操作。
CaptureResult 是每一次 Capture 操作的結果,裡麵包括了很多狀態信息,包括閃光燈狀態、對焦狀態、時間戳等等。例如你可以在拍照完成的時候,通過 CaptureResult 獲取本次拍照時的對焦狀態和時間戳。需要注意的是,CaptureResult 並不包含任何圖像數據,前面我們在介紹 Surface 的時候說了,圖像數據都是從 Surface 獲取的。
如果要我給出強有力的理由解釋為什麼要使用 Camera2,那麼通過 Camera2 提供的高級特性可以構建出更加高質量的相機應用程序應該是最佳理由了。
如果你熟悉 Camera1,並且打算從 Camera1 遷移到 Camera2 的話,希望以下幾個建議可以對你起到幫助:
本章到此結束,主要是介紹了 Camera2 的一些基礎概念,讓大家能夠基本了解 Camera2 的工作流程和基礎概念,並且知道使用 Camera2 能夠做些什麼。如果你對 Camera2 還是感到很陌生,不要緊,後續的教程會帶領大家逐步深入了解 Camera2。
② Android Camera(二)
CameraManager、CameraDevice、CameraCharacteristics、CameraRequest與CameraRequest.Builder、CameraCaptureSession以及CaptureResult。
1. 開發相機必須的的許可權就是 Manifest.permission.CAMERA 了,所以第一步要在Manifest中添加Camera permission:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" /></pre>
如果是6.0以上的手機還要動態申請許可權,關於許可權這塊大家可以使用PermissionUtil全局管理。
2.獲取CameraManager實例 開啟相機
3.當相機成功打開後會回調onOpened方法,這里可以拿到CameraDevice對象,也就是具體的攝像頭設備
4.設置相機一些參數 包括方向
5.開啟預覽
6.開啟預覽後獲取實時流數據,onImageAvailable回調中的ImageRender獲取實時流數據,這個數據是YUV_420_888的數據 ,我們可以存儲數據也可以對數據流進行美顏濾鏡操作,也可以推送給服務端。
7.當關閉界面或者停止預覽時 :
③ 安卓相機軟體哪個最好
UCam全能相機最好,用了一兩年沒有有出過任何問題
UCam,取自You(U) Camera,是UCam開發團隊開發出來一款應用於Android手機的強大拍照軟體。主要包括拍照、錄像、圖像後期處理、GIF動畫錄制和文件快速分享等功能。因為功能極其齊全,在國內市場上、UCam被廣大用戶親切地稱為「全能相機」。UCam開發團隊也響應廣大用戶的支持,將其在國內的名稱定義為「UCam全能相機」。
與世面上其他拍照軟體不同的是,UCam對智能手機/平板電腦搭載的攝像頭硬體參數支持幾乎完美,同時還提供了獨特的畫中畫、防抖、時間戳等技術,幫助用戶輕松地拍照。再加上數十種特效濾鏡、全景拍照、輕松拼圖、完美的文字標簽等功能,可以讓用戶輕松地拍攝/處理出與眾不同的照片。
另外,該軟體還深度整合了各大社交網站,包括新浪微博,QQ空間、人人網、開心網、Facebook、twitter等多達十多家。通過該軟體,可以輕松地將拍攝、製作的圖片統一發布到一個人擁有的多個社交站點。
除此之外,UCam還包括不少特別的功能,比如間諜相機、放大鏡等等,其獨特的快速分享功能、可以通過簡單地拍照將圖片、音樂等文件快速地在手機和個人電腦之間傳遞。
④ Android進階——你所知道的Camera2和你所不知道的Camera2完全解析
一切源於在項目過程中的一個Bug:我的需求是在MainActivity 實現自動預覽,也可以點擊跳到簽到SignedActivity去實現拍照簽到,第一次進入界面的時候都是正常的,但是有時候返回來的時候預覽失敗,即從MainActivity跳轉到SignedActivity偶爾預覽失敗和從SignedActivity返回MainActivity偶爾失敗,都是報(CAMERA_IN_USE)ERRO=1的錯誤,奇怪的是的的確確做了完全釋放操作,加上以前用的更多的是Camera api 對於Camer2 的機制沒有完整去研究過,一下子懵了,於是乎先去找了Stack Overflow,查到一個解決方案是:"我棄用了新API,換回舊API",ORZ,找了其他的也沒有答案,可是我不服呀,我就把官方的文檔全部啃了一遍,於是乎便有了以下的理解,我想如果你不懂得怎麼使用Camera2的話,這篇絕對值得你去閱讀,你會發現Camera2 並非像大多數說得那樣使用起來很復雜。
全新的android.hardware.Camera2 。Android 5.0對拍照API進行了全新的設計,新增了全新設計的Camera 2 API,這些API不僅大幅提高了Android系統拍照的功能,還能支持RAW照片輸出,甚至允許程序調整相機的對焦模式、曝光模式、快門等。
在Camera2 架構在核心參與類角色有: CameraManager 、 CameraDevice 、 CameraCharacteristics 、 CameraRequest與CameraRequest.Builder 、 CameraCaptureSession 以及 CaptureResult 。
位於android.hardware.camera2.CameraManager下,也是Android 21(5.0)添加的,和其他系統服務一樣通過 Context.getSystemService(CameraManager.class ) 或者 Context.getSystemService(Context.CAMERA_SERVICE) 來完成初始化,主要用於管理系統攝像頭:
CameraDevice是Camera2中抽象出來的一個對象,直接與系統硬體攝像頭相聯系。因為不可能所有的攝像頭都會支持高級功能(即攝像頭功能可被分為limit 和full 兩個級別),當攝像頭處於limited 級別時候,此時Camera2和早期的Camera功能差不多,除此之外在Camera2架構中,CameraDevice還承擔其他兩項重要任務:
正如前面所說, 系統向攝像頭發送 Capture 請求,而攝像頭會返回 CameraMetadata,這一切都是在由對應的CameraDevice創建的CameraCaptureSession 會話完成 ,當程序需要預覽、拍照、再次預覽時,都需要先通過會話。(A configured capture session for a CameraDevice , used for capturing images from the camera or reprocessing images captured from the camera in the same session previously.A CameraCaptureSession is created by providing a set of target output surfaces to createCaptureSession , or by providing an InputConfiguration and a set of target output surfaces to for a reprocessable capture session . Once created, the session is active until a new session is created by the camera device, or the camera device is closed.)CameraCaptureSession一旦被創建,直到對應的CameraDevice關閉才會死掉。雖然CameraCaptureSession會話用於從攝像頭中捕獲圖像,但是只有同一個會話才能再次從同一攝像頭中捕獲圖像。另外, 創建會話是一項耗時的非同步操作,可能需要幾百毫秒 ,因為它需要配置相機設備的內部管道並分配內存緩沖區以將圖像發送到所需的目標,因而createCaptureSession和會將隨時可用的CameraCaptureSession發送到提供的監聽器的onConfigured回調中。如果 無法完成配置,則觸發onConfigureFailed回調 ,並且會話將不會變為活動狀態。最後需要注意的是,如果 攝像頭設備創建了一個新的會話,那麼上一個會話是被關閉的,並且會回調與其關聯的onClosed ,如果不處理好,當會話關閉之後再次調用會話的對應方法那麼所有方法將會跑出IllegalStateException異常。關閉的會話清除任何重復的請求(和調用了stopRepeating()方法類似),但是在新創建的會話接管並重新配置攝像機設備之前,關閉的會話仍然會正常完成所有正在進行的捕獲請求。簡而言之,在Camera2中CameraCaptureSession承擔很重要的角色:
描述Cameradevice屬性的對象,可以使用CameraManager通過getCameraCharacteristics(String cameraId)進行查詢。
CameraRequest代表了一次捕獲請求, 而CameraRequest.Builder用於描述捕獲圖片的各種參數設置,包含捕獲硬體(感測器,鏡頭,快閃記憶體),對焦模式、曝光模式,處理流水線,控制演算法和輸出緩沖區的配置。 ,然後傳遞到對應的會話中進行設置, CameraRequest.Builder則負責生成CameraRequest對象 。當程序調用setRepeatingRequest()方法進行預覽時,或調用capture()方法進行拍照時,都需要傳入CameraRequest參數。CameraRequest可以通過CameraRequest.Builder來進行初始化,通過調用createCaptureRequest來獲得。
CaptureRequest描述是從圖像感測器捕獲單個圖像的結果的子集的對象。(CaptureResults are proced by a CameraDevice after processing a CaptureRequest)當CaptureRequest被處理之後由CameraDevice生成。
CameraManager 處於頂層管理位置負責 檢測獲取所有攝像頭及其特性 和 傳入指定的CameraDevice.StateCallback回調打開指定攝像頭 , CameraDevice 是負責管理抽象對象,包括 監聽Camera 的狀態回調CameraDevice.StateCallback 、 創建CameraCaptureSession和CameraRequest , CameraCaptureSession 用於描述一次圖像捕獲操作,主要負責 監聽自己會話的狀態回調CameraCaptureSession.StateCallback 和 CameraCaptureSession.CaptureCallback捕獲回調 ,還有 發送處理CameraRequest ; CameraRequest 則可以看成是一個"JavaBean"的作用用於描述希望什麼樣的配置來處理這次請求;最後三個回調用於監聽對應的狀態。
CameraManager 處於頂層管理位置負責檢測 檢測獲取所有攝像頭並設置輸出參數,傳入指定的CameraDevice.StateCallback回調,然後打開指定攝像頭,並觸發CameraDevice.StateCallback中的onOpened方法,並在onOpened方法里開始通過調用創建預覽會話, ,CameraDevice負責創建請求 CameraCharacteristics 、 CameraRequest與CameraRequest.Builder 、 CameraCaptureSession 以及 CaptureResult 則可以看成是一個JavaBean的作用用於描述以什麼樣的配置來處理這次請求。
Camera2Helper類只是簡單的封裝了下,為了讓Camera2的初始化和Activity 高度分離,這個類只是Demo 階段部分有待優化,另外結合我具體的業務,對於圖片大小有限制,所以我都是默認採用采樣壓縮率方式對圖片進行壓縮