android camera 學習,androidcamera
總體介紹
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是為服務端守護進程,由系統啟動時開啟。
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。
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/
android使用camera拍照然後對圖片進行編輯的問題
你是想實現不同activity之間傳值 。
可以有以下方法 :
1 sharedpreference 如果資料量大 ,不建議使用它
2 檔案儲存體 , 存進去再讀出來
3 inten 傳值 :
Intent intent = new Intent(this,xxx.class);
Bundle bundle = new Bundler();
Bundle.putString("key","value");
intent.putExtras(bundle);
startActivity(intent);
跳轉到另外activity取值 :
Bundle bundle = this.getIntent().getExtras();
bundle.getString("key");
4 建資料庫吧
android camera 曝光設定
可能底層驅動沒有支援