问题
前面文章已经实现了基于Camera(相对于Camera2)的拍照功能。但是每次拍照都要有几秒时间的卡顿。可以看下效果:
老的
总感觉卡了好久,打开手机自带相机发现也没等这么久。。。想想办法解决一下。下面是新的解决方案实现效果,参考了Giftedcat的CameraTakeManager
感觉不到一丝卡顿。
新的
原理
老的方式是使用Camera中提供的takePicture
这个API,前面的文章可以看到,不再叙述,新的拍照方式是:直接拿当前预览界面的图像进行保存。具体解释与代码如下:
方式一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| private boolean canTakePhoto = false;
public void doOpenCamera(int cameraIndex){ try { mCamera = Camera.open(cameraIndex); mCamera.setPreviewCallback(new Camera.PreviewCallback() { @Override public void onPreviewFrame(byte[] data, Camera camera) { if(canTakePhoto){ Bitmap bmp = getBmpPicData(data, camera); canTakePhoto = false; saveBitmap(bmp); } } }); doStartPreview(); CameraViewHelp.getInstance().cameraHasOpened(); } catch (Exception e) { } }
private Bitmap getBmpPicData(byte[] data, Camera camera){ Camera.Size size = camera.getParameters().getPreviewSize(); YuvImage image = new YuvImage(data, ImageFormat.NV21,size.width, size.height,null); if(image != null){ Bitmap bmp = null; try { ByteArrayOutputStream stream = new ByteArrayOutputStream(); image.compressToJpeg(new Rect(0,0, size.width, size.height),80, stream); bmp = BitmapFactory.decodeByteArray(stream.toByteArray(),0, stream.size()); stream.close(); } catch (IOException e) { e.printStackTrace(); } return bmp; } return null; }
|
第二次重构时又发现一个新的API, 比上面方式更简单:
方式二:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public void TakePicture(){ if(mCamera!=null){ mCamera.setOneShotPreviewCallback(new Camera.PreviewCallback(){ @Override public void onPreviewFrame(byte[] data, Camera camera) { Bitmap bmp = getBmpPicData(data); saveBitmap(bmp); } }); } }
|
参考