編輯:關於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是為服務端守護進程,由系統啟動時開啟。
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/
一、簡介 TextureMapFragment:用於顯示地圖片段。 二、示例3--Demo03MapFragment.cs 文件名:Demo
Android開發中時常會遇到內存洩漏的問題,而Android系統對單個App又有一定的內存限制,此值可以通過一下方式獲取:ActivityManager am = (A
本文實例講述了Android編程解析XML方法。分享給大家供大家參考,具體如下:XML在各種開發中都廣泛應用,Android也不例外。作為承載數據的一個重要角色,如何讀寫
首先我發現API還提供一個畫多邊形的類。而一個镂空圓分解成兩個多邊形,即橫著一刀切在這個镂空圓上,上下兩部分各為一個多邊形。但實現上述镂空圓時我的思路還是講經緯度看出笛卡