1.CameraInfo
用於描述camera的內部類,主要包括以下參數:
- facing:代表相機的朝向,只能取CameraInfo中的兩個靜態值,源碼說明如下:
/**
* The facing of the camera is opposite to that of the screen.
*/
public static final int CAMERA_FACING_BACK = 0;//背對屏幕方向,後置相機
/**
* The facing of the camera is the same as that of the screen.
*/
public static final int CAMERA_FACING_FRONT = 1;//和屏幕一個方向,前置相機
一般我們在使用相機初始化時,需要確定是開啓前置還是後置相機。如果沒有增加其他外置相機的條件下,後置和前置相機的ID分別爲0和1,如果包含其他的外置相機,則相應的爲2或其他值。爲便於編程理解,一般直接使用以上兩個值作爲開啓相機的ID。
mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);//開啓後置相機
- orientation :表示相機採集圖片的角度,該值是相機採集圖片時需要順時針旋轉的角度,且旋轉值固定爲0、90、180、270中的一個。可以從源碼說明中看出:
/**
* <p>The orientation of the camera image. The value is the angle that the
* camera image needs to be rotated clockwise so it shows correctly on
* the display in its natural orientation. It should be 0, 90, 180, or 270.</p>
*
* <p>For example, suppose a device has a naturally tall screen. The
* back-facing camera sensor is mounted in landscape. You are looking at
* the screen. If the top side of the camera sensor is aligned with the
* right edge of the screen in natural orientation, the value should be
* 90. If the top side of a front-facing camera sensor is aligned with
* the right of the screen, the value should be 270.</p>
上一部分的翻譯在上面的定義中已經說明,下面一段是針對該定義舉例,翻譯如下:
舉例,假設設備處於自然豎直狀態,後置相機的傳感器是水平方向,你面對手機,如果傳感器的頂部在手機屏幕的右邊,那麼這個值爲90;如果前置攝像頭的傳感器頂部在手機右邊,那麼該值就是270。
- setDisplayOrientation:該方法是用於設置相機的預覽的方向,是對上文提及的Orientation的參數設置。在使用手機相機採用豎直預覽時,該方法的就起到了很重要的作用,因爲後置(前置)相機默認的預覽方向是水平的,需要將其順時針旋轉90度,由下面的源碼解釋也可以看出。
Set the clockwise rotation of preview display in degrees. This affects
* the preview frames and the picture displayed after snapshot. This method
* is useful for portrait mode applications. Note that preview display of
* front-facing cameras is flipped horizontally before the rotation, that
* is, the image is reflected along the central vertical axis of the camera
* sensor. So the users can see themselves as looking into a mirror.
<p>This does not affect the order of byte array passed in {@link
* PreviewCallback#onPreviewFrame}, JPEG pictures, or recorded videos. This
* method is not allowed to be called during preview.
在相機預覽時,通過設置該參數的順時針的角度,來影響預覽和拍照的圖片效果,尤其在豎直使用相機時。但需要注意前置相機使用時,顯示的效果會水平翻轉,預覽的效果如圖照鏡子。
注意,該參數的設置僅僅是影響預覽的界面效果,不影響真實的相機採集的數據,因此在PreviewCallback和onPreviewFrame中獲取的數據轉爲圖像後,仍然呈現圖像傳感器方向的圖片效果。在預覽時,不可調用該參數。
提到上面的方向問題,需要結合安卓的座標特點分析:
-
屏幕座標:安卓中的屏幕座標是指左上角爲圓點(0,0),以原點向屏幕的右延伸爲X軸正方向,向下延伸爲Y軸正方向。
-
自然方向:自然方向是指安卓設備正常使用時的方向,比如手機是豎直的方向,平板是水平的方向。
-
圖像傳感器方向:該方向是由手機的攝像機硬件傳感器決定,該方向用於拍攝時的取景方向,上文提及的方向就是指圖像的傳感器方向。
-
相機採集的方向:通過setDisplayOrientation()該方法僅僅是修改相機的預覽方向,實際上並未改變獲取的相機圖像,在onPreviewFrame()中獲取的數據轉爲圖像後,顯示的圖像方向仍然與相機的圖像傳感器方向一致,可通過對獲取的圖片旋轉,獲取需要的圖片,一般情況下,後置相機需順時針旋轉90度,前置相機順時針旋轉270度。
小結:
1.默認情況下手機的傳感器方向是橫向的,且是由傳感器硬件決定,軟件無法修改;
2.通過setDisplayOrientation()可設置相機的預覽方向,一般該值爲順時針90,修改後前置相機會出現水平鏡像翻轉;
3.調用setDisplayOrientation()僅是改變預覽方向,在onPreviewFrame()回調中獲取的圖像,一般後置相機需順時針旋轉90度,前置相機順時針旋轉270度。
2 .Parameters
該參數是用於對相機的參數的設置,使相機捕獲的效果符合我們的要求,但是源碼中的註解我們可以看出,對於該參的設置我們不能隨意設置,因爲不同的相機具體的性能,例如圖片大小和閃光模式等。因此在設置該參數前,需要先查詢一下相機支持參數,例如在設置setColorEffect(String)參數前,先調用getSupportedColorEffects(),查看支持參數,如果不支持該參數的設置,則反回爲空。
默認情況下對於尺寸的獲取和設置,其單位均是像素。一般在調用尺寸或格式的getXX時,默認會返回包含至少一組的有效元素集合。
Different devices may have different camera capabilities, such as
* picture size or flash modes. The application should query the camera
* capabilities before setting parameters. For example, the application
* should call {@link Camera.Parameters#getSupportedColorEffects()} before
* calling {@link Camera.Parameters#setColorEffect(String)}. If the
* camera does not support color effects,
* {@link Camera.Parameters#getSupportedColorEffects()} will return null.
一般在調用setXX前建議先調用對應的getXX方法,否則會顯示如下異常:
java.lang.RuntimeException: setParameters failed
at android.hardware.Camera.native_setParameters(Native Method)
-
預覽尺寸
A: getSupportedPreviewSizes():返回相機支持的預覽尺寸的集合。
B:setPreviewSize(int width, int height): 設置相機的預覽尺寸,注意該尺寸不是最終獲取的圖片尺寸。 -
預覽格式
A: getSupportedPreviewFormats():獲取相機支持的預覽格式,包括ImageFormat.NV21、ImageFormat.NV16和ImageFormat.YV21等,默認情況下,所有相機均支持NV21格式。
B: setPreviewFormat(int pixel_format):設置預覽的數據格式 -
採集圖片尺寸
A: getSupportedPictureSizes():獲取相機支持的採集圖像的尺寸。
B: setPictureSize(int width, int height):設置採集圖片的尺寸,該尺寸是指圖片保存後的真實尺寸大小。 -
採集圖片格式
A: getSupportedPictureFormats():設置相機支持的輸出圖片格式。
B: setPictureFormat(int pixel_format):設置相機保存的圖片格式。 -
對焦模式
A: getSupportedFocusModes():獲取相機支持的對焦模式。
setFocusMode(String value):設置相機的對焦模式。
B: getMaxZoom():獲取相機支持的最大焦距。
C: setZoom(int zoom):設置焦距,該值的設置需要參照獲取到的最大焦距值。 -
最大檢測人臉數
A:getMaxNumDetectedFaces():返回當前相機支持的最大的人臉檢測數,如果調用B:FaceDetectionListener後,該返回值始終爲0,說明不支持該種檢測類型。
小結:
在調用相機前需要根據需要對相機的參數進行設置,但是在設置時爲避免設置的參數,該相機不支持,因此在設置前,建議調用對應的get方法,查看相機支持的對應參數。
3. Face
其實安卓系統從SDK 1.0開始就支持簡單的人臉識別接口,在調用相機前,添加檢測的監聽(setFaceDetectionListener)在回調的onFaceDetection(Camera.Face[] faces, Camera camera)就可以獲取Face信息,包括以下。
-
rect:檢測到的人臉矩形的座標參數(該座標與相機座標不同,需要轉換後纔可以使用)。
-
score:檢測到人臉的可信度(範圍1-100),取決於設備的不同,即使可信度值很低,也會將其回調出來,因此需要我們根據需求,過濾一下。
-
leftEye:左眼的座標參數
-
rightEye:右眼的座標參數
-
mouth:嘴的座標參數
**注意:**並不是所有的相機都支持左眼、右眼和嘴的座標參數回調,如果不支持則返回爲null,並且該參數的座標系與rect相同,因此需要我們手動轉換爲相機參數座標系。
- FaceDetectionListener:相機檢測人臉的回到接口,並重寫onFaceDetection(Face[] faces, Camera camera)方法,獲取相機檢測的人臉回調。
4. Camera類中的方法
-
設備相機個數
getNumberOfCameras():返回設備中支持的相機個數,默認爲2(前後置相機),如果不支持或沒有相機則返回0。 -
開啓相機
A:open():使用後置相機創建相機對象,如果沒有後置相機,則返回null。
B: open(int cameraId):使用相機ID來創建相機對象,在同一時間,只能調用一個相機ID來創建相機對象,否則會報異常。獲取的參數值爲0至相機個數(getNumberOfCameras())減一。默認後置相機ID爲0,前置爲1。 -
獲取指定相機參數信息
getCameraInfo(int cameraId, CameraInfo cameraInfo):返回指定相機的參數信息。
-
預覽
A:方向 setDisplayOrientation(int degrees):設置相機的預覽方向,前文已多次提及。
B : 載體: setPreviewDisplay(SurfaceHolder holder):設置相機的預覽載體,通過一個SurfaceHolder 實現實時預覽的效果。
C: 回調 setPreviewCallback(PreviewCallback cb):設置相機預覽的回調監聽,重寫
onPreviewFrame(byte[] data, Camera camera)方法,獲取每一幀的相機預覽數據。
-
開始
startPreview():開始預覽,在調用該方法前,必須先調用setPreviewDisplay()設置預覽載體,否則沒有效果。 -
結束
stopPreview():結束預覽,在調用該參數前,建議先將setPreviewCallback和setPreviewDisplay設置爲null。
-
相機參數
A:getParameters():獲取當前相機的Parameters參數對象。
B:setParameters(Parameters params):設置當前相機的參數對象。 -
人臉檢測
A: startFaceDetection():開始人臉監聽,在添加FaceDetectionListener前,需要先調用該參數。
B stopFaceDetection():停止人臉檢測監聽。 -
關閉相機
release():釋放相機資源。
小結:
以上方法中介紹了相機使用的關鍵方法,分類總結如下:
1.開啓/關閉 :通過open()開啓後置相機,或通過open(int cameraId)開啓指定相機,在結束相機使用時,需要調用release()釋放相機資源。
2.預覽的設置:需要根據需要設置預覽的方向,設置預覽的載體,在開始預覽前需要先設置載體,否則預覽並未真正開始,結束預覽後需要先將回調置爲null然後調用release方法。
3.人臉檢測:在添加FaceDetectionListener前,需要先調用startFaceDetection()方法,在檢測結束時,調用stopFaceDetection()。
5.錄像
相機錄像的操作,主要通過MediaRecorder實現,通過對該類中參數的設置,實現相機錄像的效果,下面主要講解常用的接口,具體的實現在下面系列文章中會講解,並附有github的Demo路徑。
-
設置相機
setCamera(mCamera):設置指定的相機用於錄製視頻。 -
音頻源格式
setAudioSource():定義的音頻的物理資源和錄製配置,該參數可查看AudioSource類,主要是包括各種對於麥克風優化後的各種參數設置。 -
視頻資源
setVideoSource():設置視頻資源,包括camera、surface兩種,默認是採用來自camera。 -
視頻編碼格式
setVideoEncoder():設置視頻的編碼格式,包括默認、AAC(有損壓縮)和AMR(壓縮較大,質量較差)等 -
視頻幀率
setVideoEncodingBitRate(): 在調用該參數前,先調用prepare()檢測,以確保設置的幀率適用。 -
分辨率
setVideoSize():設置錄製的分辨率,該參數的設置,必須放在設置編碼和格式後面,否則報錯。 -
輸出路徑
setOutputFile():設置存儲錄像的文件路徑。 -
最大錄製時長
setMaxDuration():設置最大的錄製時間,單位爲ms,也可不指定該參數。 -
預覽載體
setPreviewDisplay():該參數的設置與相機預覽類似,需要通過surface展示實時錄像內容。 -
準備預覽
prepare():調用該方法前,必須要設置音頻、視頻源、編碼格式和幀率等參數,但必須在start()方法前。 -
開始預覽
start():調用該方法時,必須擁有相機資源(鎖定),如果調用該方法失敗,需要重新獲取相機資源。 -
重置
reset():調用該方法後,需要重置MediaRecorder的資源。 -
結束
stop():如果在start()後立即調用該方法,則會拋出Runtimeexception異常,原因時結束時未收到有效的音視頻資源,導致清除導出目錄下的文件資源。 -
釋放
release():釋放除了必要的MediaRecorder資源。
小結:
本部分主要講解了關於視頻錄製(MediaRecorder)相關的接口,在錄製視頻前需要必須設置相機、音頻格式、視頻格式、幀率、分辨率和輸出路徑等,在調用prepare()前必須要設置好該參數。
6.總結
本文介紹了相機相關的接口參數,包括以下內容:
1.CameraInfo相關的角度、角度設置以及安卓的座標;
2.Parameters相關的預覽尺寸、格式、對焦模式和燈光等;
3.Face:相關的矩形框、人臉中眼睛和嘴的座標等;
4.Camera類中相關的方法,包括相機參數、回調和人臉檢測等;
5.錄像中MediaRecorder類的主要參數的講解等。