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

android 多媒體和相機詳解八

編輯:關於Android編程

獲取圖像
  一旦你建立了預覽類和顯示預覽類的viewlayout,你就已准備好開始使用你的應用獲取圖像了.在你的應用代碼中,你還必須要建立起那些用於控制的控件們的偵聽器,來響應用戶的動作.

 


  要取得圖像,使用Camera.takePicture()方法.此方法有三個參數.要獲得JPEG圖像,你必須實現一個Camera.PictureCallback接口來接收圖像數據然後寫入文件中.下面的代碼演示了最基本的Camera.PictureCallback接口的實現.


[java]
private PictureCallback mPicture = new PictureCallback() { 
    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 
 
        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE); 
        if (pictureFile == null){ 
            Log.d(TAG, "Error creating media file, check storage permissions: " + 
                e.getMessage()); 
            return; 
        } 
 
        try { 
            FileOutputStream fos = new FileOutputStream(pictureFile); 
            fos.write(data); 
            fos.close(); 
        } catch (FileNotFoundException e) { 
            Log.d(TAG, "File not found: " + e.getMessage()); 
        } catch (IOException e) { 
            Log.d(TAG, "Error accessing file: " + e.getMessage()); 
        } 
    } 
}; 

private PictureCallback mPicture = new PictureCallback() {
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {

        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
        if (pictureFile == null){
            Log.d(TAG, "Error creating media file, check storage permissions: " +
                e.getMessage());
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }
};


通過調用Camera.takePicture()方法觸發圖像獲取事件.下面的代碼演示了如了在一個按鈕的View.OnClickListener方法中調用此方法.


[java]
// 為獲取按鈕增加一個listener  
Button captureButton = (Button) findViewById(id.button_capture); 
captureButton.setOnClickListener( 
    new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
            // 從相機獲取圖像  
            mCamera.takePicture(null, null, mPicture); 
        } 
    } 
); 

// 為獲取按鈕增加一個listener
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
    new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // 從相機獲取圖像
            mCamera.takePicture(null, null, mPicture);
        }
    }
);

注:mPicture成員引用自"使用相機"一節的同名成員變量.

 


注意:記注在用完時要使用Camera.release()來釋放相機對象!關於如何釋放相機,見"釋放相機"一節.

 


獲取視頻


下面這些配置給MediaRecorder的視頻錄制參數被置為默認值.然而,你可以自己設置這些配置項的值:

setVideoEncodingBitRate()

setVideoSize()

setVideoFrameRate()

setAudioEncodingBitRate()

setAudioChannels()

setAudioSamplingRate()


  使用android框架獲取視頻需要小心管理相機對象並且與MediaRecorder類做好協調.當使用相機進行錄像時,你必須管理好Camera.lock()和Camera.unlock()兩個調用以允許MediaRecorder操作相機.


  注:從Android4.0 (API level 14)開始,Camera.lock()和Camera.unlock()調用會自動管理.

 

  與從像機獲取圖像不一樣,獲取視頻需要一個十挑剔的調用順序.你必須按照特殊的順序才能成功的准備並獲取視頻,如下所示:

打開相機 –使用Camera.open()來獲取一個相機對象的實例.

連接預覽 -通過Camera.setPreviewDisplay()連接一個SurfaceView到相機來准備一個實時預覽.

開始預覽 –調用Camera.startPreview()來顯示實時圖像.

開始錄制視頻 –下面的步驟必須完整的執行才能成功的錄制視頻:

Unlock相機– 調用Camera.unlock()來Unlock相機以供MediaRecorder使用.

配置MediaRecorder– 按以下順序調用MediaRecorder的方法.更多知識請參考MediaRecorder參考文檔.

setCamera()- 設置視頻獲取所使用的相機,使用你的應用的當前的相機實例.

setAudioSource()- 設置音頻source,使用MediaRecorder.AudioSource.CAMCORDER.

setVideoSource()- 設置視頻source,使用MediaRecorder.VideoSource.CAMERA.

設置視頻輸出的格式和編碼.對於Android2.2 (API Level8)及更高版本,使用MediaRecorder.setProfile方法,使用CamcorderProfile.get()來獲得一個profile.對於之前的版本,你必須用參數來設置視頻輸出格式和編碼:

setOutputFormat()- 設置輸出格式,指定為默認的或MediaRecorder.OutputFormat.MPEG_4.

setAudioEncoder()- 設置音頻編碼類型,指定為默認的或MediaRecorder.AudioEncoder.AMR_NB.

setVideoEncoder()- 設置視頻編碼類型,指定為默認的或MediaRecorder.VideoEncoder.MPEG_4_SP.

setOutputFile()-指定輸出文件,使用getOutputMediaFile(MEDIA_TYPE_VIDEO).toString(),這個方法是"保存媒體文件"一節(在後面)中的例子代碼.

setPreviewDisplay()- 為你的應用指定SurfaceView預覽layout元素,使用在連接預覽時指定的相同對象.

  注意:你必須按上面的順序調用MediaRecorder的配置方法們,否則你的應用將遇到悲劇從而失敗.

准備MediaRecorder- 准備MediaRecorder,主要是通過調用配置方法MediaRecorder.prepare().

開始MediaRecorder- 調用MediaRecorder.start()開始錄制視頻.

停止錄制視頻 –依次調用下面的方法,才能成功結束一個視頻錄制過程:

停止MediaRecorder– 調用MediaRecorder.stop()停止錄制視頻.

重置MediaRecorder– 可選的,調用MediaRecorder.reset()可以將以前的配置取消.

釋放MediaRecorder– 調用MediaRecorder.release()來釋放MediaRecorder.

鎖住相機 -調用Camera.lock()鎖住相機以使後面的MediaRecorder會話也可以使用相機.從Android4.0 (API level 14)開始,此調用僅在MediaRecorder.prepare()調用失敗時才需要.

停止預覽 –當你的activity完成了對相機的使用,使用Camera.stopPreview()停止預覽.

釋放相機- 調用Camera.release()釋放相機,以使其它應用也可使用它.

 

  注:不創建相機預覽並且略過前幾步也是可以使用MediaRecorder.然而,用戶一般還是想看預覽的,所以此處不討論這種情況.


  技巧:如果你的應用是專為錄像寫的,那麼在啟動你的預覽之前調用setRecordingHint(boolean)並傳入true,這樣可以幫你減少啟動錄制的時間.

配置MediaRecorder

 


  當使用MediaRecorder類來錄制視頻,你必須按特定步驟執行配置過程,然後調用MediaRecorder.prepare()方法來檢查並實現所給予的配置.下面的例子代碼演示了如何為視頻錄制正確的配置並准備MediaRecorder類.


[java] 
private boolean prepareVideoRecorder(){ 
    mCamera = getCameraInstance(); 
    mMediaRecorder = new MediaRecorder(); 
 
    // Step 1: 解鎖相機並設置給MediaRecorder  
    mCamera.unlock(); 
    mMediaRecorder.setCamera(mCamera); 
 
    // Step 2: 設置sources  
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); 
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 
 
    // Step 3: 設置一個CamcorderProfile (在API Level 8或更高版本中)  
    mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); 
 
    // Step 4: 設置輸出文件  
    mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()); 
 
    // Step 5: 設置預覽輸出  
    mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface()); 
 
    // Step 6: 准備配置MediaRecorder  
    try { 
        mMediaRecorder.prepare(); 
    } catch (IllegalStateException e) { 
        Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage()); 
        releaseMediaRecorder(); 
        return false; 
    } catch (IOException e) { 
        Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage()); 
        releaseMediaRecorder(); 
        return false; 
    } 
    return true; 

private boolean prepareVideoRecorder(){
    mCamera = getCameraInstance();
    mMediaRecorder = new MediaRecorder();

    // Step 1: 解鎖相機並設置給MediaRecorder
    mCamera.unlock();
    mMediaRecorder.setCamera(mCamera);

    // Step 2: 設置sources
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    // Step 3: 設置一個CamcorderProfile (在API Level 8或更高版本中)
    mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

    // Step 4: 設置輸出文件
    mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());

    // Step 5: 設置預覽輸出
    mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());

    // Step 6: 准備配置MediaRecorder
    try {
        mMediaRecorder.prepare();
    } catch (IllegalStateException e) {
        Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    } catch (IOException e) {
        Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    }
    return true;
}


在Android2.2 (API Level8)之前,你必須直接設置輸出格式和編碼格式等參數,而不是使用CamcorderProfile.可以像下面這樣做:

 

[java]
// Step 3: 設置輸出格式和編碼(for versions prior to API Level 8)  
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); 
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); 
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT); 

    // Step 3: 設置輸出格式和編碼(for versions prior to API Level 8)
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);


下面這些配置給MediaRecorder 的視頻錄制參數被置為默認值.然而,你可以自己設置這些配置項的值:


· setVideoEncodingBitRate()

· setVideoSize()

· setVideoFrameRate()

· setAudioEncodingBitRate()

· setAudioChannels()

· setAudioSamplingRate()

 


開始和停止MediaRecorder


  當使用MediaRecorder開始和停止錄像時,你必須按特定的順序進行調用,如下所列:

· 使用Camera.unlock()解鎖相機

· 按上面代碼所演示的配置MediaRecorder

· MediaRecorder.start()開始錄像

· 錄制視頻

· 使用MediaRecorder.stop()停止錄像

· 用MediaRecorder.release()釋放MediaRecorder

· 用Camera.lock()鎖住相機 www.2cto.com

 

下面的示例代碼演示如何通過一個按鈕來使用相機和MediaRecorder類正確的開始和停止視頻錄制

注:當完成一個視頻錄制,不要釋放相機,否則你的預覽將被迫停止.

 


[java]
private boolean isRecording = false; 
 
// 向錄像按鈕增加監聽器  
Button captureButton = (Button) findViewById(id.button_capture); 
captureButton.setOnClickListener( 
    new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
            if (isRecording) { 
                // 停止錄像並釋放 MediaRecorder  
                mMediaRecorder.stop();  // stop the recording  
                releaseMediaRecorder(); // release the MediaRecorder object  
                mCamera.lock();         // take camera access back from MediaRecorder  
 
                // inform the user that recording has stopped  
                setCaptureButtonText("Capture"); 
                isRecording = false; 
            } else { 
                // 初始化視頻相機  
                if (prepareVideoRecorder()) { 
                    // 相幾解鎖,MediaRecorder 已准備好.現在可以開始錄像了  
                    mMediaRecorder.start(); 
 
                    // inform the user that recording has started  
                    setCaptureButtonText("Stop"); 
                    isRecording = true; 
                } else { 
                    // 准備過程失敗,釋放相機  
                    releaseMediaRecorder(); 
                    // inform user  
                } 
            } 
        } 
    } 
); 

private boolean isRecording = false;

// 向錄像按鈕增加監聽器
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
    new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (isRecording) {
                // 停止錄像並釋放 MediaRecorder
                mMediaRecorder.stop();  // stop the recording
                releaseMediaRecorder(); // release the MediaRecorder object
                mCamera.lock();         // take camera access back from MediaRecorder

                // inform the user that recording has stopped
                setCaptureButtonText("Capture");
                isRecording = false;
            } else {
                // 初始化視頻相機
                if (prepareVideoRecorder()) {
                    // 相幾解鎖,MediaRecorder 已准備好.現在可以開始錄像了
                    mMediaRecorder.start();

                    // inform the user that recording has started
                    setCaptureButtonText("Stop");
                    isRecording = true;
                } else {
                    // 准備過程失敗,釋放相機
                    releaseMediaRecorder();
                    // inform user
                }
            }
        }
    }
);

 


注:在上例中,prepareVideoRecorder()方法引用自例子"配置MediaRecorder".此方法解鎖相機配置並准備MediaRecorder實例.

作者:nkmnkm

 

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