Android開發相機比較簡單,而且幫助文檔中有詳細的說明,但是對於剛剛開始學習android的程序員來說,仍然是一件很有挑戰性的事情,本人由於工作需要,開發了一個很簡單的照相機程序(只能拍照並保存而已,呵呵),下邊將簡述開發相機程序的主要步驟,並在最后給出源碼。
首先給出API文檔中開發相機程序的步驟描述:(比較懶,直接截圖了)
1.獲取系統提供的照相機服務:
Camera.open();//上圖中給出的是open(int)這個方法,這是SDK升級的結果,因為現在很多手機已經不止一個攝像頭了,為了兼容性,我們使用open()方法
2.這一步對應上圖中的2-4步,主要作用是獲取相機的配置參數,並按照自己的需求對參數進行修改,例如預覽區的尺寸,保存圖片的尺寸,相機的角度等等。
Camera.Parameters parameters = camera.getParameters();//獲取相機的配置參數 List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();//不同手機支持的預覽區的大小是不一樣的,而且也不是任意的,該方法的作用是獲取手機支持的預覽區大小,以便按自己的需求進行自定義 Camera.Size previewSize = previewSizes.get(0);//為了演示,選擇第一個 parameters.setPreviewSize(previewSize.width, previewSize.height);//設置預覽區的大小 List<Camera.Size> picSizes = parameters.getSupportedPictureSizes();//和預覽區的設置一樣,相機最后捕獲的照片的大小也是因手機廠商的不同而不同,而且不能隨便定義 Camera.Size picSize = picSizes.get(0);//為了演示,隨便選擇一個 parameters.setPictureSize(picSize.width, picSize.height);//設置保存圖片的大小,還有很多其他的參數,具體看API吧
3.設置好參數之后,就可以開啟預覽了,正如API中說的,必須定義一個SurfaceHolder的實例,傳送給camera,然后調用startPreView就可以實現預覽了。
//下邊給我自己定義個Preview public class Preview extends SurfaceView implements SurfaceHolder.Callback { SurfaceHolder mHolder; public Camera camera; public Preview(Context context, Camera camera) { super(context); this.camera = camera; mHolder = getHolder(); mHolder.addCallback(this); mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public void surfaceCreated(SurfaceHolder holder) { try { camera.setPreviewDisplay(holder); } catch (IOException exception) { camera.release(); camera = null; } } public void surfaceDestroyed(SurfaceHolder holder) { if (camera != null) { camera.stopPreview(); camera.setPreviewCallback(null); camera.release(); camera = null; } }
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {//系統會自動調用這個方法 Camera.Parameters parameters = camera.getParameters(); List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes(); Camera.Size previewSize = previewSizes.get(0); parameters.setPreviewSize(previewSize.width, previewSize.height); List<Camera.Size> picSizes = parameters.getSupportedPictureSizes(); Camera.Size picSize = picSizes.get(0); parameters.setPictureSize(picSize.width, picSize.height); camera.setParameters(parameters); camera.startPreview(); } @Override public void draw(Canvas canvas) { super.draw(canvas); } }
4.最后就是獲取相機捕獲的數據了,這步比較簡單,就是將比特流保存為最后的圖片,需要說明的是保存圖片的操作必須在Camera.PictureCallback這個接口實現,因為保存相機數據的方法是:
camera.takePicture(null, null, m_PicCallback);//前兩個參數不用管,最后一個參數是保存相機數據的地方
我的保存相機數據的接口如下所示:
public class MyPictureCallback implements Camera.PictureCallback { public void onPictureTaken(byte[] data, Camera camera) { Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length); String picDirStr = Environment.getExternalStorageDirectory() + "/pic/"; File picDir = new File(picDirStr); if(!picDir.exists()){ picDir.mkdir(); } String picName = picDirStr + System.currentTimeMillis() + ".jpg"; File myCaptureFile = new File(picName); try { BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(myCaptureFile)); bm.compress(Bitmap.CompressFormat.JPEG, 80, bos); bos.flush(); bos.close(); camera.startPreview(); } catch (Exception e) { e.printStackTrace(); } } }
嗯,大體就是這樣一個步驟,總體來說不是很困難,最后想給出代碼,結果發現不會,呵呵。