Android ApiDemos樣本解析(57):Graphics->CameraPreview

來源:互聯網
上載者:User

本例介紹了如何使用裝置的網路攝影機來預覽將要拍攝的照片,本例需要真實的手機來運行:

 

例子中用到兩個方面的知識:SurfaceView 和android.hardware.Camera。

SurfaceView 為View的子類,它提供一個專門用於繪圖的Surface,目的是允許使用背景工作執行緒中這個Surface上繪圖,這樣對於應費時的繪圖操作無需放在UI線程中,而是可以在單獨的背景工作執行緒中按照自己的節奏來繪圖。

使用SurfaceView時需要從SurfaceView派生一個子類,這個子類需要實現SurfaceHolder.Callback介面,這個介面提供了幾個回呼函數用於通知應用關於Surface的訊息,如什麼時候建立,改變大小,銷毀等。實現這些回呼函數非常重要,應用可以在這些回呼函數來調整Surface的一些說明,知道何時可以在Surface繪製等。通常在這個SurfaceView的衍生類別中會定義一個背景工作執行緒用於繪圖。

在Surface上繪圖時,不是通過直接的函數調用,而是通過擷取Surface控制代碼(SurfaceHolder)的間接方法.因此在Surface初始化時,調用getHolder()來擷取Surface的控制代碼。通常是在擷取SurfaceHolder之後,再調用mHolder.addCallback(this)來響應SurfaceHolder.Callback事件。

如何使用背景工作執行緒中Surface 的Canvas上繪製圖形本例沒有涉及,將在後面的例子說明。

下面代碼定義了SurfaceView子類並實現SurfaceHolder.Callback介面。

[java] 
class Preview extends SurfaceView implements SurfaceHolder.Callback {  
 SurfaceHolder mHolder;  
 Camera mCamera;  
...  
public void surfaceCreated(SurfaceHolder holder) {  
 // The Surface has been created, acquire the   
 // camera and tell it where   
 // to draw.   
 mCamera = Camera.open();  
 try {  
 mCamera.setPreviewDisplay(holder);  
 } catch (IOException exception) {  
 mCamera.release();  
 mCamera = null;  
 // TODO: add more exception handling logic here   
 }  
}  
   
public void surfaceDestroyed(SurfaceHolder holder) {  
 // Surface will be destroyed when we return,   
 //    so stop the preview.   
 // Because the CameraDevice object is not a   
 //shared resource, it's very   
 // important to release it when the activity is paused.   
 mCamera.stopPreview();  
 mCamera.release();  
 mCamera = null;  
}  
   
public void surfaceChanged(SurfaceHolder holder,  
 int format, int w, int h) {  
 // Now that the size is known, set up the   
 //camera parameters and begin   
 // the preview.   
 Camera.Parameters parameters = mCamera.getParameters();  
   
 List<Size> sizes = parameters.getSupportedPreviewSizes();  
 Size optimalSize = getOptimalPreviewSize(sizes, w, h);  
 parameters.setPreviewSize(optimalSize.width, optimalSize.height);  
   
 mCamera.setParameters(parameters);  
 mCamera.startPreview();  

class Preview extends SurfaceView implements SurfaceHolder.Callback {
 SurfaceHolder mHolder;
 Camera mCamera;
...
public void surfaceCreated(SurfaceHolder holder) {
 // The Surface has been created, acquire the
 // camera and tell it where
 // to draw.
 mCamera = Camera.open();
 try {
 mCamera.setPreviewDisplay(holder);
 } catch (IOException exception) {
 mCamera.release();
 mCamera = null;
 // TODO: add more exception handling logic here
 }
}
 
public void surfaceDestroyed(SurfaceHolder holder) {
 // Surface will be destroyed when we return,
 //    so stop the preview.
 // Because the CameraDevice object is not a
 //shared resource, it's very
 // important to release it when the activity is paused.
 mCamera.stopPreview();
 mCamera.release();
 mCamera = null;
}
 
public void surfaceChanged(SurfaceHolder holder,
 int format, int w, int h) {
 // Now that the size is known, set up the
 //camera parameters and begin
 // the preview.
 Camera.Parameters parameters = mCamera.getParameters();
 
 List<Size> sizes = parameters.getSupportedPreviewSizes();
 Size optimalSize = getOptimalPreviewSize(sizes, w, h);
 parameters.setPreviewSize(optimalSize.width, optimalSize.height);
 
 mCamera.setParameters(parameters);
 mCamera.startPreview();
}

 

Camera 這裡使用的Camera類是定義在android.hardware包中代表的是網路攝影機硬體裝置,Camera類可以用來設定裝置網路攝影機的配置,開始/停止預覽,拍照或是視頻。這個類是Camera服務(用來管理實際裝置的服務)的用戶端。


為了能使用裝置的網路攝影機,必須在AndroidManifest.xml中定義對應的許可權permission和uses-feature如下:


<uses-permission android:name=”android.permission.CAMERA” />
<uses-feature android:name=”android.hardware.camera” />
<uses-feature android:name=”android.hardware.camera.autofocus” android:required=”false” />


使用Camera拍照的一般步驟如下:


調用open(int)擷取一個Camera的樣本對象.
使用getParameters()擷取Camera 的預設配置參數.
如果有需要,調用setParameters(Camera.Parameters)修改Camera的參數.
如果有需要,可以調用setDisplayOrientation(int)設定取景為縱向或是橫向。
將一個初始化過的SurfaceHolder通過setPreviewDisplay(SurfaceHolder),如果沒有指定Surface,Camera將無法開始預覽。
調用startPreview()開始畫面預覽,拍照之前必須先開始預覽。
如需拍照可以調用takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback),拍照完成事件將以回呼函數的方式通知應用。
拍照完成時,Camera自動停止預覽狀態,需調用startPreview來拍新的照片。
調用stopPreview()停止預覽。
最後不在使用Camera調用release()釋放資源以便其它應用可以使用Camera。
作者:mapdigit
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.