在Android上使用Camera API尽快拍照

Ali*_*lin 13 android surfaceview android-camera

场景:

我需要尽快拍照并将其保存到SD卡.如果我能在0.2秒左右拍摄照片并保存它,那将是非常棒的.

到目前为止我做了什么:

像往常一样,我创建了一个SurfaceView来处理Camera预览并初始化相机对象.图像的质量不需要非常高,这就是为什么我没有使用尽可能大的分辨率而且也不需要自动对焦的原因.我设置这样的参数:

 Parameters parameters = camera.getParameters();
 parameters.set("jpeg-quality", 70);

 parameters.setPictureFormat(ImageFormat.JPEG);
 List<Camera.Size> sizes = parameters.getSupportedPictureSizes();
 Size size = sizes.get(Integer.valueOf((sizes.size()-1)/2)); //choose a medium resolution
 parameters.setPictureSize(size.width, size.height);
 camera.setParameters(parameters);
 camera.setDisplayOrientation(90);

 List<Size> sizes2 = parameters.getSupportedPreviewSizes();
 Size size2 = sizes.get(0);

 parameters.setPreviewSize(size2.width, size2.height);
 camera.setPreviewDisplay(holder);
 camera.startPreview();
Run Code Online (Sandbox Code Playgroud)

我将图像保存到SD卡非常简单:

PictureCallback handlePictureStorage = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            FileOutputStream outStream = null;

            try {
                outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
                outStream.write(data);
                outStream.close();       
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
        }
    };
Run Code Online (Sandbox Code Playgroud)

在我的Galaxy Nexus上进行一些测试后,结果如下:

  • 将图片大小设置为:wigth = 1600 height = 1200
  • Jpeg质量:70,图片格式JPEG
  • 消防拍照:00:13:23.603
  • 开始在SD卡上保存图片:00:13:23.956
  • 在SD卡上完成保存图片:00:13:23.990

这几乎是0.4秒.有没有办法更加调整相机参数以获得更快的速度?分辨率还可以,图片质量也一样.我知道市场上有应用程序每秒有30张图片,但我认为他们使用缓冲来达到这个速度.但是,正如您可能会看到拍摄照片而不是将其保存到卡片时丢失的最长时间.如果我能再调整一下这将是很好的.

Ali*_*lin 7

在我用多个参数进行了一些测试后,结论是没有多少工作要做.以下是我设置的一些参数:

  //set color efects to none
 cameraParameters.setColorEffect(Camera.Parameters.EFFECT_NONE);

  //set antibanding to none
 if (cameraParameters.getAntibanding() != null) {
 cameraParameters.setAntibanding(Camera.Parameters.ANTIBANDING_OFF);
 }

 // set white ballance
 if (cameraParameters.getWhiteBalance() != null) {
 cameraParameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT);
 }

  //set flash
 if (cameraParameters.getFlashMode() != null) {
 cameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
 }

  //set zoom
 if (cameraParameters.isZoomSupported()) {
 cameraParameters.setZoom(0);
 }

 //set focus mode
 cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
Run Code Online (Sandbox Code Playgroud)

但是,最好的想法是获取相机支持的完整字符串参数列表,并尝试调整它们.要获取字符串,请使用Camera.Parameters的flatten方法 - http://developer.android.com/reference/android/hardware/Camera.Parameters.html#flatten()

但是为了快速获得图像,我不得不使用带缓冲区的预览,并且对于每个拍摄的帧,尝试将其保存在线程中的SD卡上.图像质量不是很好,但它是一个开始.

  • 在带有android 2.3的Galaxy S上,将图片保存到SD卡需要大约1秒钟.保存预览帧速度更快,我相信大约200ms左右.在Galaxy Nexus拍摄和保存图片大约300毫秒 (2认同)
  • 对于任何试图使用上述代码的人,不要忘记添加对"ColorEffect"和"FocusMode"支持的检查,以防止在不支持的设备上崩溃. (2认同)