Android上的相机示例

时间:2011-12-09 17:31:55

标签: android camera android-camera android-camera-intent

我想写一个活动:

  1. 显示相机预览(取景器),并有一个“捕捉”按钮。
  2. 按下“捕获”按钮时,拍摄照片并将其返回到调用活动(setResult()& finish())。
  3. 是否有完整示例适用于每台设备?链接到一个简单的开源应用程序拍照将是理想的答案。


    到目前为止我的研究:

    这是一个常见的场景,有很多问题和教程。

    主要有两种方法:

    1. 使用android.provider.MediaStore.ACTION_IMAGE_CAPTURE事件。请参阅this question
    2. 直接使用Camera API。请参阅this examplethis question (with lots of references)
    3. 方法1本来是完美的,但问题是每个设备上的意图实现方式不同。 在某些设备上运行良好。但是,在某些设备上,您可以拍照,但它永远不会返回到您的应用。在某些设备上,启动意图时没有任何反应。通常它还会将图像保存到SD卡,并且需要存在SD卡。每个设备上的用户交互也不同。

      采用方法2,问题是稳定性。我尝试了一些例子,但我设法阻止相机在某些设备上工作(直到重启)并完全冻结另一台设备。在另一台设备上捕捉工作,但预览保持黑色。

      我会使用ZXing作为示例应用程序(我经常使用它),但它只使用预览(取景器),并且不拍任何照片。我还发现,在某些设备上,当光照条件发生变化时,ZXing并没有自动调整白平衡,而原生相机应用程序正确地进行了调整(不确定是否可以修复)。


      更新

      有一段时间我直接使用了相机API。这提供了更多控制(自定义UI等),但我不建议任何人。我会在90%的设备上工作,但每次都会发布一个新的设备,但会有不同的问题。

      我遇到的一些问题:

      • 处理自动对焦
      • 处理闪光灯
      • 带前置摄像头,后置摄像头或两者的支持设备
      • 每个设备都有不同的屏幕分辨率,预览分辨率(并不总是与屏幕分辨率相匹配)和图像分辨率的组合。

      所以一般情况下,除非没有别的办法,否则我不建议去这条路线。两年后,我通过自定义代码转储并切换回基于Intent的方法。从那时起,我的麻烦就少了很多。我过去在基于意图的方法中遇到的问题可能只是我自己的无能。

      如果真的需要走这条路,我听说如果你只支持Android 4.0 +的设备会更容易。

3 个答案:

答案 0 :(得分:9)

  

采用方法2,问题是稳定性。我尝试了一些例子,但我设法阻止相机在某些设备上工作(直到重启)并完全冻结另一台设备。在另一台设备上捕捉工作,但预览保持黑色。

示例中存在错误或设备存在兼容性问题。

答案 1 :(得分:1)

CommonsWare提供的示例效果很好。该示例在按原样使用时有效,但以下是我在修改用例时遇到的问题:

  1. 在第一张照片完成之前,永远不要拍第二张照片,换句话说,PictureCallback.onPictureTaken()已被调用。 CommonsWare示例为此目的使用inPreview标志。
  2. 确保您的SurfaceView是全屏的。如果您想要更小的预览,则可能需要更改预览大小选择逻辑,否则预览可能不适合某些设备上的SurfaceView。有些设备仅支持全屏预览大小,因此保持全屏是最简单的解决方案。
  3. 要在预览屏幕中添加更多组件,FrameLayout在我的体验中运作良好。我开始使用LinearLayout在预览上方添加文字,但这违反了规则#2。使用FrameLayout在预览顶部添加组件时,预览分辨率没有任何问题。

    我还在GitHub上发布了与Camera.open()相关的小问题。

答案 2 :(得分:0)

"the recommended way to access the camera is to open Camera on a separate thread"。否则,Camera.open()可能需要一段时间,可能会阻碍UI线程。

"Callbacks will be invoked on the event thread open(int) was called from"。这就是为什么要通过相机预览回调来实现最佳性能(例如,将它们编码为低延迟视频以进行实时通信),我建议在新的HandlerThread中打开相机,如图here所示。