Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android camera 學習

android camera 學習

編輯:關於Android編程

總體介紹

Android Camera框架從整體上看是一個client/service架構。有兩個進程,一個是client進程,可以看成AP端

,主要包括Java代碼和一些native層的c/c++代碼;另一個是service進程,屬於服務端,是native c/c++代碼,

主要負責和linux kernel中的camera driver交互,搜集linux kernel中driver層傳上來的數據,並交給顯示系統(surface)顯示。client 和 service 進程通過Binder機制進行通信,client端通過調用service端的接口實現各個具體的功能。

對於preview數據不會通過Binder機制從service端copy 到client端,但會通過回調函數與消息機制將preview數據的buffer地址傳到client端,最終可在Java ap中操作處理preview數據。

2.調用層次劃分

Android中Camera的調用流程可分為以下幾個層次:

Package->Framework->JNI->Camera(cpp)--(binder)-->CameraService->Camera HAL->Camera Driver

client端:

Package 中的 camera.java 調用Framework中的 camera.java(framework/base/core/java/android/hardware).Framework中的 camera.java 調用 JNI層的native 函數。JNI層的調用實現在android_hardware_camera.cpp(framework/base/core/jni文件下的文件都被 編譯進libandroid_runtime.so)文件中,android_hardware_camera.cpp文件中的 register_android_hardware_camera(JNIEnv *env)函數會將native函數注冊到虛擬機中,以供framework層的JAVA代碼調用,這些native函數通過調用 libcamera_client.so中的camera類實現具體功能。

核心的libcamera_client.so動態庫源代碼位於:framework/base/libs/camera中,其中 Icamera,IcameraClient,IcameraService三個類按照Binder IPC通信要求的框架實現的,用來與service端通信。

service端:

service端的實現在動態庫libcameraservice.so中,源代碼位於:frameworks/base/services/camera。CameraService相關類通過調用Camera HAL層來實現具體的功能,從HAL層向下就不是Android的標准代碼了,各個廠商有自己不 同的實現。但思路應該都是相同的:Camera遵循V4L2架構,利用ioctl發送VIDIOC_DQBUF命令得到有效的圖像數據,接著回調HAL層 的data callback接口以通知CameraService,CameraService會通過binder通知Camera.cpp。

ps查看進程,類似 com.android.camera是為客戶端Camera進程,/system/bin/mediaserver是為服務端守護進程,由系統啟動時開啟。


麥庫截圖20141420140552825.jpg

n1, camera打開線程與預覽線程n

2,參數設置n

3,自動對焦與觸摸對焦n

4,位置管理n

5,旋轉管理n

6,拍照nA,對焦nB,拍照nC,接受圖片nD,保存圖片


1.打開camera與預覽線程

onCreate()裡會先後開啟CameraOpenThread和CameraPreviewThread。

打開camera還需要線程?CameraOpenThread名為打開camera,實為C/S connect連接服務端,binder進程間通信,開銷較大。預覽線程必須在打開線程完成以後執行,它貫穿始終直到進程消亡為止,整個預覽過程相對復 雜,在抽象層和底層驅動實現.


2.設置參數

—預覽拍照錄像之前,用戶需要設置很多參數,比如閃光,白平衡,場景,對比度等。—程序裡這些參數保存在SharedPreferences共享優選項和Parameters兩個地方,Preferences包含Parameters,打開程序讀取優選項參數,關閉程序保存優選項參數,考慮到用戶經常會調整參數,引入Parameters來保存從打開以後到關閉以前這個中間過程的參數變量,Parameters的鍵值由抽象層根據硬件sensor的能力決定。

3.自動對焦與觸摸對焦

—外界事物由光線經凸透鏡聚焦到sensor上成像,camera模組開啟馬達前後平移鏡頭取得最佳成像效果,這個過程稱之為對焦。—5.1 自動對焦—1)camera模組會因感光強度變化而自動開啟對焦,驅動控制。—2) 用戶長按快門,軟件控制自動對焦。—3) 用戶按下快門拍照,拍攝前自動對焦。—程序裡,Camera對象實現類ShutterButton的接口OnShutterButtonListener裡的方法onShutterButtonFocus(booleanpressed)和onShutterButtonClick(),後者是拍照,下節討論,先看onShutterButtonFocus(booleanpressed),這個pressed判斷是否為一次有效的長按,如果是的話,執行autoFocus(),這個autoFocus()也是Camera對象實現類FocusManager的接口Listener裡的方法,由binder交給cameraservice,最後在底層驅動實現自動對焦。—5.2 觸摸對焦—自動對焦的對焦區域位於屏幕正中,用戶也可觸摸特定區域對焦。—Camera對象實現類View的接口OnTouchListener裡的方法onTouch(),輸入系統上報MotionEvent的xy坐標,保存在Parameters,執行autoFocus(),抽象層讀取Paramters的觸摸點坐標,實現區域對焦。

4.存儲位置管理

—位置管理LocationManager用來記錄拍攝圖片的GPS位置信息(經維度),存入JPEG頭部插入的Exif裡。—用戶在菜單“相機設置”裡的"保存所在位置"選擇打開(前提是GPS已開啟),屏幕左上方會出現一個GPS圖標,表示現在可以記錄GPS信息了。—程序裡,Camera對象實現了位置管理監聽器LocationManager.Listener的接口showGpsOnScreenIndicator()和hideGpsOnScreenIndicator(),顯示或者隱藏GPS圖標。—程序第一次初始化時initializeFirstTime(),通過讀取優選項Preference得到bool值recordLocation,判斷是否需要記錄GPS信息,如果需要,在拍照capture()裡調用LocationManager的方法得到Locationloc,並將其存入Exif。

5.旋轉管理

—假設一台手機,camera正常安裝,豎直方向作為默認方向(orientation== 0)拍攝照片,即拍攝“肖像照”(portrait),得到的照片顯示在屏幕上也是豎直方向。—如果把手機旋轉90度水平過來拍攝“山水照”(landscape),對於camerasensor來說,沒有旋轉的概念,所以軟件上要把圖片旋轉90度回來。————————軟件上,需要借助方向監聽器隨時更新方向信息,並保存在Parameters裡,抽象層實現拍照功能時從Parameters裡讀取方向。—具體的,camera對象內部類MyOrientationEventListener的方法onOrientationChanged()保存方向orientation的值,MyOrientationEventListener繼承OrientationEventListener,OrientationEventListener的onSensorChanged()把從sensorManager拿到的xyz坐標轉換成方向。—程序啟動,注冊sensor監聽器並使能,sensorManager不斷上報底層sensor數據,通過消息機制發送到camera對象,後者計算坐標數據得到方向orientation的值(實際外包給orientationListener完成),最後保存Parameters。

麥庫截圖20141420141056762.jpg



6.拍照

—拍照分四步,對焦,拍照,接收圖片,保存圖片。—mCameraDevice.takePicture(mShutterCallback,mRawPictureCallback,— mPostViewPictureCallback, newJpegPictureCallback(loc));—1)對焦—拍照前如果已經區域對焦,則取消自動對焦,反之,開啟一次自動對焦。對焦完成後,底層發送對焦成功與否的消息給camera對象,FocusManager把狀態mState保存起來,如果正在對焦未完成(mState== STATE_FOCUSING)則不可拍照,直到對焦完畢。—2)拍照—onShutterButtonClick()-> doSnap() -> capture() -> takePicture(),具體實現在抽象層和底層驅動,實質就是拿一張預覽的圖像,抽象層讀取拍照時的Parameters參數配置,包括用戶選擇的照片大小。—3)接收圖片—通過回調,由底層發送圖片給camera對象。—RawPictureCallback,得到原始圖片,需要軟件壓縮Jpeg。(YUV轉Jpeg)—JpegPictureCallback,直接得到Jpeg圖片,需要硬件壓縮Jpeg。—PostViewPictureCallback,拍完後預覽圖片。—4)保存圖片—交由線程ImageSaver保存圖片和生成thumbnails。—默認路徑位於/mnt/sdcard/DCIM/Camera/


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved