上一节中,记录了如何使用SurfaceView对摄像头进行预览( http://www.cnblogs.com/fishbone-lsy/p/5240504.html )。这一节,简单记录一下拍照的实现。
为了简单,我将单击预览画面作为拍照的触发动作,拍照之后,将照片存在手机本地的相册中。
拍照的方法如下:
/** * 拍照 */ private void doTakePicture(){ Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback() { @Override public void onShutter() { } }; if (mCamera != null){ // 拍照 mCamera.takePicture(shutterCallback, null, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { if (data != null){ Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0 , data.length); if (bitmap != null){ FileUtil.saveBitmap(bitmap , onSavePictureListener); } } } }); } }
我们不能看出,其实拍照只有一句话mCamera.takePicture。但是这个方法,可以输入4个监听,这还是比较少见的一个方法。幸好,方法定义的注释中写明了,四个监听分别有什么作用
* @param shutter the callback for image capture moment, or null * @param raw the callback for raw (uncompressed) image data, or null * @param postview callback with postview image data, may be null * @param jpeg the callback for JPEG image data, or null
我们暂时只使用了最后一个监听,在拍照完成后,将JPEG的data保存起来。
保存的代码比较简单,如下:
public static void saveBitmap(final Bitmap bm , final OnFinishListener listener){ new Thread(new Runnable() { @Override public void run() { File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM); String pathStr = path.getAbsolutePath() + "/Camera/s.png"; File file = new File(pathStr); try { FileOutputStream fileOutputStream = new FileOutputStream(file); bm.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream); fileOutputStream.flush(); fileOutputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } if (bm != null && !bm.isRecycled()){ bm.recycle(); } if (listener != null){ listener.onFinished(); } } }).start(); } }
FileUtil.OnFinishListener onSavePictureListener = new FileUtil.OnFinishListener() { @Override public void onFinished() { try { // 拍照完成后,相机会自动停止预览,此处重新开启相机的预览 mCamera.startPreview(); } catch (Exception e) { mCamera.release(); mCamera = null; } } };
Done