Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android 多媒體和相機詳解十

android 多媒體和相機詳解十

編輯:關於Android編程

檢測可用的特性

[java]
// get Camera parameters  
Camera.Parameters params = mCamera.getParameters(); 
 
List<String> focusModes = params.getSupportedFocusModes(); 
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) { 
  // Autofocus mode is supported  

// get Camera parameters
Camera.Parameters params = mCamera.getParameters();

List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
  // Autofocus mode is supported
}

 

  你可以對大多數相機特性使用以上所示方法.Camera.Parameters對象提供了一個getSupported...(),is...Supported() or getMax...()方法來確定一個特性是否被支持.

  如果你的應用需要特定的相機特性,你可以通過在你的應用的manifest文件中添加請求.當你聲明要使用特定相機特性,比如閃光燈和自動對焦,Google Play就會阻止你的應用被安裝到不支持這些特性的設備上.

使用相機特性
  當設置要使用的相機特性時,首先要理解的是不是所有的設備都支持所有的特性.另外,一個特性可能被在不同的級別上支持或帶有不同的選項.因此,當你開發一個相機應用時,需要決定支持哪些特性以及支持到什麼級別.當決定之後,你應在代碼中包含檢測設備是否支持所需特性,然後在不支持時要有優雅的錯誤處理.

  你可以通過獲取一個相機參數對象的實例來檢測,並且檢測相關的方法們.下面的代碼向你展示了如何得到一個Camera.Parameters對象並檢測是否支持自動對焦特性:


  大多數相機特性都可以通過Camera.Parameters進行管理.你要獲取此對象,首先獲取一個相機對象的實例,然後調用getParameters()方法.改變所獲取的parameter對象,然後把它設置回相機對象,就像下面所演示的:

 

[java]
// 獲取Camera parameters  
Camera.Parameters params = mCamera.getParameters(); 
// 設置聚焦模式  
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); 
// 設置Camera parameters  
mCamera.setParameters(params); 

// 獲取Camera parameters
Camera.Parameters params = mCamera.getParameters();
// 設置聚焦模式
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// 設置Camera parameters
mCamera.setParameters(params);

 

此方法對於絕大多數相機特性都有效,並且大多數參數可以在任何時刻進行改變.對於參數的改變通常都是馬上在應用的相機預覽中表現出來.在軟件解度看,參數的改變可能經過多幀後才能生效,因為硬件要處理新的指令然後發送更新的圖像數據.

重要: 一些相機特性不能被任務改變.特別的,改變相機預覽的大小或方向需要你首先停止預覽,改變預覽大小或方向,然後重啟預覽.從Android 4.0 (API Level 14),預覽方向可以不用重啟而改變.

其它的相機特性需要更多的代碼,包括:

l Metering and focus areas

l Face detection

l ime lapse video

 


測光與聚焦區域

  在一些情況下攝像,自動對焦和測光不能產生期望的結果.從Android 4.0 (API Level 14)開始,你的相機應用可以提供額外的控制, 允許你的應用或用戶指定圖像中的某塊區域進行聚焦或曝光級別設置,然後把這些值傳給相機,以應用於抓取像片或錄制視頻.


  測光和聚焦區域的工作方式與其它相機特性十分相似,你通過Camera.Parameters 對象控制它們.下面的代碼演示了為一個相機實例設置兩個測光區域:

// 創建一個相機實例


[java]
mCamera = getCameraInstance(); 
 
// 設置相機參數們  
Camera.Parameters params = mCamera.getParameters(); 
 
if (params.getMaxNumMeteringAreas() > 0){ // 檢查是否支持測光區域  
    List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>(); 
 
    Rect areaRect1 = new Rect(-100, -100, 100, 100);    // 在圖像的中心指定一個區域  
    meteringAreas.add(new Camera.Area(areaRect1, 600)); // 設置寬度到60%  
    Rect areaRect2 = new Rect(800, -1000, 1000, -800);  // 在圖像的右上角指定一個區域  
    meteringAreas.add(new Camera.Area(areaRect2, 400)); // 收置寬度為40%  
    params.setMeteringAreas(meteringAreas); 

 
mCamera.setParameters(params); 

mCamera = getCameraInstance();

// 設置相機參數們
Camera.Parameters params = mCamera.getParameters();

if (params.getMaxNumMeteringAreas() > 0){ // 檢查是否支持測光區域
    List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();

    Rect areaRect1 = new Rect(-100, -100, 100, 100);    // 在圖像的中心指定一個區域
    meteringAreas.add(new Camera.Area(areaRect1, 600)); // 設置寬度到60%
    Rect areaRect2 = new Rect(800, -1000, 1000, -800);  // 在圖像的右上角指定一個區域
    meteringAreas.add(new Camera.Area(areaRect2, 400)); // 收置寬度為40%
    params.setMeteringAreas(meteringAreas);
}

mCamera.setParameters(params);

 


Camera.Area對象包含兩個數據參數:一個Rect對象指定了相機視口中的一塊區域,還有一個寬度,告訴相機在測光或聚焦計算中此區域的重要程度.

Camera.Area對象的Rect字段描述了一個矩形區域在一個2000 x 2000個單元格組成的區域中的映射位置.坐標-1000, -1000代表了top, left,並且坐標1000, 1000代表了bottom, right,如下面示意圖所示:

 

 

 

 


圖1.紅線表示在相機預覽中指定一個Camera.Area所在的坐標系.藍框表示一個相機區域的位置和形狀,其坐標值為:333,333,667,667.

此坐標系的邊界總是與相機預覽圖像的外邊界一至,並且不會隨著變焦變大或變小.同樣的,使用Camera.setDisplayOrientation()旋轉預覽圖像也不會改變做標系.

人臉檢測


對於包含人的圖像,臉往往是圖像中最重要的部分,並且在拍照時,臉部被用於對焦和白平衡.Android 4.0 (API Level 14)框架提供了識別面部的和跟據其計算圖像設置的API們.


注:當啟用面部檢測特性時,setWhiteBalance(String), setFocusAreas(List) 和setMeteringAreas(List)不再起作用.

 

 

使用面部檢測特性通常需要以下幾步:

l 檢查設備是否支持面部檢測

l 創建一個面部檢測監聽器

l 添加面部檢測監聽器到你的相機對象.

l 預覽開始後開始面部檢測(並且每次重啟預覽後同樣)

  面部檢測特性不是在所有的設備上都支持.你可以調用getMaxNumDetectedFaces()來檢測是否支持.

為了接收到面部檢測的通知並作出響應,你的相機應用中必須為面部檢測事件設置一個監聽器.所以你必須創建一個監聽類,它實現Camera.FaceDetectionListener接口,如下代碼所示:

 

[java]
class MyFaceDetectionListener implements Camera.FaceDetectionListener { 
 
    @Override 
    public void onFaceDetection(Face[] faces, Camera camera) { 
        if (faces.length > 0){ 
            Log.d("FaceDetection", "face detected: "+ faces.length + 
                    " Face 1 Location X: " + faces[0].rect.centerX() + 
                    "Y: " + faces[0].rect.centerY() ); 
        } 
    } 

class MyFaceDetectionListener implements Camera.FaceDetectionListener {

    @Override
    public void onFaceDetection(Face[] faces, Camera camera) {
        if (faces.length > 0){
            Log.d("FaceDetection", "face detected: "+ faces.length +
                    " Face 1 Location X: " + faces[0].rect.centerX() +
                    "Y: " + faces[0].rect.centerY() );
        }
    }
}

 

 

創建此類後,你就可以把它設置給你的應用的相機對象,如下代碼所示:

[java]  mCamera.setFaceDetectionListener(new MyFaceDetectionListener()); 

mCamera.setFaceDetectionListener(new MyFaceDetectionListener());

你的應用必須在每次啟動(或重啟)預覽時啟動面部檢測.創建一個方法專用於開啟面部檢測,你便可以在需要時調用它,如下例如示:

 

[java]
public void startFaceDetection(){ 
    // Try starting Face Detection  
    Camera.Parameters params = mCamera.getParameters(); 
 
    // start face detection only *after* preview has started  
    if (params.getMaxNumDetectedFaces() > 0){ 
        // camera supports face detection, so can start it:  
        mCamera.startFaceDetection(); 
    } 

public void startFaceDetection(){
    // Try starting Face Detection
    Camera.Parameters params = mCamera.getParameters();

    // start face detection only *after* preview has started
    if (params.getMaxNumDetectedFaces() > 0){
        // camera supports face detection, so can start it:
        mCamera.startFaceDetection();
    }
}
你必須在每次開始(或重啟)預覽時開啟臉部檢測.如果你使用"創建一個預覽類"一節中的預覽類,把你的startFaceDetection()方法添加到你的預覽類的surfaceCreated()和surfaceChanged()方法中,如下面代碼所示:

 

[java]  public void surfaceCreated(SurfaceHolder holder) { 
    try { 
        mCamera.setPreviewDisplay(holder); 
        mCamera.startPreview(); 
 
        startFaceDetection(); // start face detection feature  
 
    } catch (IOException e) { 
        Log.d(TAG, "Error setting camera preview: " + e.getMessage()); 
    } 

 
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
 
    if (mHolder.getSurface() == null){ 
        // preview surface does not exist  
        Log.d(TAG, "mHolder.getSurface() == null"); 
        return; 
    } 
 
    try { 
        mCamera.stopPreview(); 
 
    } catch (Exception e){ 
        // ignore: tried to stop a non-existent preview  
        Log.d(TAG, "Error stopping camera preview: " + e.getMessage()); 
    } 
 
    try { 
        mCamera.setPreviewDisplay(mHolder); 
        mCamera.startPreview(); 
 
        startFaceDetection(); // re-start face detection feature  
 
    } catch (Exception e){ 
        // ignore: tried to stop a non-existent preview  
        Log.d(TAG, "Error starting camera preview: " + e.getMessage()); 
    } 

public void surfaceCreated(SurfaceHolder holder) {
    try {
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();

        startFaceDetection(); // start face detection feature

    } catch (IOException e) {
        Log.d(TAG, "Error setting camera preview: " + e.getMessage());
    }
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

    if (mHolder.getSurface() == null){
        // preview surface does not exist
        Log.d(TAG, "mHolder.getSurface() == null");
        return;
    }

    try {
        mCamera.stopPreview();

    } catch (Exception e){
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error stopping camera preview: " + e.getMessage());
    }

    try {
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();  www.2cto.com

        startFaceDetection(); // re-start face detection feature

    } catch (Exception e){
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error starting camera preview: " + e.getMessage());
    }
}


注:記住在調用startPreview()後要調用此函數.不要試圖在你的應用的actvitiy的onCreate()中啟動臉部檢測,因為此時預覽還沒有啟動呢.

 

 作者:nkmnkm
 

 

 

 

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