雖然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(終端自然角度偏角)有關,二者的換算結果就是圖像寫入偏角,該偏角意味著圖像被順時針旋轉該角度就能夠回正展示。
適配安卓10方式:
返回URI即可
手機上加載webview,網頁上上傳圖片調用原生相機和相冊上傳圖片
先設置好webview的加載以及websetting,這里就不多說了。
主要是setWebChromeClient方法的實現
這個方法分幾個版本的適配3.0以下的設備,3.0到4.1的設備,4.1到5.0的設備,以及5.0以上的設備,每個方法參數不一樣適配時請注意。5.0以下的參數都是 ValueCallbackUri ,以上的設備需要 ValueCallbackUri[] ,回傳數據的時候也是對應的不要弄錯了。
最后的效果如下:
[img]剪映。
為大家整理了一份個人知識提升的學習資源,包括這兩年很火的短視頻直播帶貨運營,各大渠道引流,視頻剪輯和有聲書等資源,每個分表格都是不同的類目,需要什么切換即可。后面會不斷匯聚更多優秀學習資源,供大家交流分享學習,需要的可以先收藏轉存,有時間慢慢看~
手機剪輯學習實時更新
鏈接:
?pwd=2D72
提取碼:2D72