在 Android 上使用 Camera API 尽可能快地拍照
Posted
技术标签:
【中文标题】在 Android 上使用 Camera API 尽可能快地拍照【英文标题】:Taking a picture as fast as possible with Camera API on Android 【发布时间】:2012-08-10 23:38:56 【问题描述】:场景:
我需要尽快拍照并将其保存到 SD 卡中。如果我能在大约 0.2 秒内完成拍照和保存,那就太棒了。
到目前为止我做了什么:
像往常一样,我创建了一个 SurfaceView 来处理相机预览并初始化相机对象。图像的质量不需要非常高,这就是为什么我没有使用尽可能大的分辨率,也不需要自动对焦。 我这样设置参数:
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();
我将图像保存到 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
;
在我的 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 张图片的应用程序,但我认为他们使用缓冲来达到这个速度。但是,您可能会看到,拍照而不是将其保存到卡中浪费了最大的时间。如果我能再调整一下就好了。
【问题讨论】:
这与您正在解决的问题相切,但 API makes no guarantee of the ordering ofgetSupportedPictureSizes()
,因此选择中间值不会在所有设备上都能满足您的需求。
为时已晚,但您的 size2
仍在使用 sizes
而不是 sizes2
进行预览。而且,setParameters()
在此之前已经被调用过。
【参考方案1】:
在我对多个参数进行了一些测试后,我得出的结论是没有太多工作要做。以下是我设置的一些参数:
//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);
但是,最好的办法是获取相机支持的参数的完整字符串列表,并尝试调整它们。获取字符串,使用Camera.Parameters的flatten方法-http://developer.android.com/reference/android/hardware/Camera.Parameters.html#flatten()
但是为了真正快速地获取图像,我不得不使用带缓冲区的预览,并且对于拍摄的每一帧,尝试将其保存在线程中的 sd 卡上。图片质量不是很好,但它是一个开始。
【讨论】:
你得到的最短时间是多少? 在装有 android 2.3 的 Galaxy S 上,拍照并将照片保存到 sd 卡大约需要 1 秒。保存预览帧要快得多,我相信大约 200 毫秒。在 Galaxy Nexus 上拍摄和保存照片大约需要 300 毫秒 谢谢@Alin 我在上面使用了你的代码,它对我来说真的很棒。谢谢... 对于任何尝试使用上述代码的人,不要忘记添加对ColorEffect
和 FocusMode
的支持性检查,以防止在不受支持的设备上崩溃。
您好!你最终如何解决这个问题?因为现在我想拿你的样本,但我没有取得好的结果。我在帧之间获得 600 毫秒的最佳时间......你能帮我吗)【参考方案2】:
如果质量无关紧要,也许您可以考虑使用 JPEG 以外的其他内容并比较执行时间: http://developer.android.com/reference/android/graphics/ImageFormat.html
【讨论】:
在我玩过的一些设备上,除了 JPEG 之外,没有一个可以使用其他设置。以上是关于在 Android 上使用 Camera API 尽可能快地拍照的主要内容,如果未能解决你的问题,请参考以下文章
Android:Camera2 API 仅在 Google Pixel 2 和 2 XL 设备上崩溃
Android Camera API/Camera2 API 相机预览及滤镜贴纸等处理
Android Camera API/Camera2 API 相机预览及滤镜贴纸等处理
使用 Android Camera2 API 进行人脸检测和画圆