好久沒寫了,有些東西做過都快忘了,趕緊記一下。
現在來實現一個簡單的相機程序。
原文地址http://www.cnblogs.com/rossoneri/p/4246134.html
當然需要的話可以直接調用系統的camera程序,但自己實現會使用更自由。
吶,既然要用實現相機,那就需要先了解一下調用camera的類android.hardware.camera
另外補充一下,實現android的video也是使用的Camera API,用到相關的類爲Camera,SurfaceView,MediaRecorder,Intent(MediaStore.ACTION_IMAGE_CAPTURE, MediaStore.ACTION_VEDIO_CAPTURE)
好,根據camera的說明,在開始編寫程序之前需要確認manifest中添加關於使用攝像設備的適當的權限聲明,如果使用camera API必須加上下段說明:
<uses-permission android:name="android.permission.CAMERA" />
當然,程序也需要聲明使用camera的特性:
<uses-feature android:name="android.hardware.camera" />
如果需要其他特性,在列表裏選擇性添加就好,比如一會兒我還需要自動對焦就要添加相關代碼到manifest。添加特性代碼就是爲了防止你的程序被安裝到沒有攝像頭或者不支持你要的功能的設備上去(prevent your application from being installed to devices that do not include a camera or do not support the camera features you specify. )
如果你的程序能通過適當的操作使用camera或一些特性,但並不特別需要它,可以增加required屬性爲false:
<uses-feature android:name="android.hardware.camera" android:required="false" />
Ok,前面說的有點多,下面說下使用camera的流程:
- 整體流程
- 檢測camera的存在並訪問camera
- 繼承SurfaceView並添加SurfaceHolder接口以顯示預覽畫面
- 爲預覽畫面添加你需要的佈局和控件
- 增加對拍照事件的監聽
- 使用拍照功能並保存照片
- 最後要釋放camera
- 流程細節
- 通過open(int)方法獲取camera的實例,int爲camera的id
- 使用getParameters()獲取相機當前的設置,包括預覽尺寸,拍照尺寸等等參數
- 如果修改了相關設置,調用setParameters(Camera.Parameters)將更改的信息重新生效
- 有需要的話使用setDisplayOrientation(int)來改變預覽畫面的方向
- 使用setPreviewDisplay(SurfaceHolder)傳遞一個完整初始化的SurfaceHolder,沒有surface,就沒法啓動預覽畫面
- 在拍照之前先調用startPreview()來更新預覽畫面
- 調用takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback)進行拍照,在回調函數中獲得照片對象並做處理
- 預覽畫面會在拍照後關閉,如果還需要拍照,記得先startPreview()
- 用stopPreview()來關閉預覽畫面
- camera使用之後一定要調用release()釋放掉
下面跟着流程,開始編碼
先在主界面添加一個按鈕,用來打開相機,效果如下:
設計拍照界面,一個surfaceview用來顯示預覽畫面,兩個button進行拍照和返回
編寫camera操作的代碼,增加了自動對焦,分辨前後攝像頭等內容,爲了代碼看起來連貫,具體說明放在註釋裏
在MainActivity中添加下面主要代碼
在Manifest加入:
<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />
最後一些資源文件string和color
經過以上步驟,我們的設備就可以用攝像頭進行預覽了,預覽時隨意移動設備還可以自動對焦,效果如下圖:
不過,這個是用DDMS截的圖,如果是拍照,實際畫面尺寸會與看到的稍有差別,原因在代碼裏也有寫。
關於拍照takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback)的使用也很簡單,在回調PictureCallback中重寫public void onPictureTaken(byte[] data, Camera camera) {}方法,data就是圖片數據,用bitmapfactory來decode一下,再處理一下顯示的旋轉方向與尺寸就ok了,這部分代碼有空再補吧。
好了,又複習一遍這個過程發現還是蠻簡單的。多看看官方的文檔就好。ok,收工睡覺。