【问题标题】:Android (Camera) - How to synchronize stopPreview() with onPictureTaken()?Android(相机)- 如何将 stopPreview() 与 onPictureTaken() 同步?
【发布时间】:2014-06-13 20:28:12
【问题描述】:

我有一个应用程序,客户端使用相机拍照。在人们点击我的“点击”按钮之前,图像的预览正在使用 SurfaceView 显示在平板电脑中。当用户点击点击按钮时,会调用 onPictureTaken 方法,在该方法中,我会保存图像并调用 camera.stopPreview() 方法(这样用户就可以看到拍摄的照片)。

但是有一个问题...如果用户在拍摄图片的那一刻在平板电脑上移动,在调用 stopPreview 方法后实际显示的静止图片不对应于我进入了 onPictureTaken 方法的字节数组。那里有几毫秒的延迟,当用户在拍摄照片之前在平板电脑周围移动时,差异会很明显(我知道 99% 的人在拍照时不会移动平板电脑,但我的客户实际上注意到了这个问题并希望修复它......)。我已经尝试将保存操作移动到一个单独的线程,如下所示,这样 onPictureTaken 方法可以尽可能快地执行。然而,它根本没有任何效果......

private PictureCallback pictureCallback = new PictureCallback() {

    public void onPictureTaken(byte[] data, Camera camera) {

        camera.stopPreview();
        reference = data;

        new PictureCallbackHeavy().execute();
    }
};

我也尝试在调用 takePicture 方法之前调用 camera.stopPreview()(而不是在 onPictureTaken() 方法内)。但结果是一样的。

我可以做些什么来同步 stopPreview 方法,这样我就可以准确地显示拍摄的图像并且在 onPictureTaken() 回调的字节数组中?

提前谢谢你!! =)

【问题讨论】:

  • 你在new PictureCallbackHeavy().execute()做什么操作?

标签: android camera sync surfaceview preview


【解决方案1】:

不幸的是,您无法仅通过调用 stopPreview() 来获得合理的良好预览图像,因为在拍摄照片和调用 onPictureTaken() 之间可能会经过相当长的时间,因为它的工作原理如下:

  • 相机实际拍摄照片(这就是您要预览的内容)
  • onShutter() 被调用
  • 为原始图像数据调用 onPictureTaken()(在某些设备上)
  • 为缩放的预览图像调用 onPictureTaken()(在某些设备上)
  • onPictureTaken() 用于最终压缩的图像数据被调用(我们这里说的那个)

因此,您必须将 onPictureTaken() 回调中的 byte[] data 转换为位图,并将该位图映射到您应该放置在 SurfaceView 上方以显示静止预览图像的 ImageView 上。 代码可能看起来像这样:

public void onPictureTaken(byte[] data, Camera camera) {
    camera.stopPreview();
    final Bitmap image = BitmapFactory.decodeByteArray(data, 0, data.length);
    surfaceView.setVisibility(SurfaceView.GONE);
    imageView.setVisibility(ImageView.VISIBLE);
    imageView.setImageBitmap(image);
    reference = data;
    new PictureCallbackHeavy().execute();
}

【讨论】:

  • 谢谢丹尼尔的回答。事实上,我所做的正是您所描述的(将 byte[] 放入 ImageView,然后将其显示在 Surface 上)。但是,我不得不停止这样做,因为 ImageView 中显示的图像有点“颗粒状”(就像上面有噪音一样)。我已经尝试将质量设置为 100% 和所有内容,但它仍然看起来有点颗粒感。!你知道我可能做错了什么吗?是的,我确保显示的图像与平板电脑拍摄的图像比例完全相同。再次感谢您。
  • 感谢您接受 Tiago!不幸的是,我不知道为什么您的图像出现颗粒感。当您以全尺寸检查输出 JPEG 时,它是否也看起来有颗粒感?也许是相机本身拍得不好——毕竟它是一部手机。或者可能是因为 ImageView 用来缩小位图的缩小方法是一种快速但质量较差的算法?也许您必须使用更好的算法(例如 Lanczos 采样)在将图像分配给 ImageView 之前将其缩小到适当的大小。但这只是猜测。
  • 你好丹尼尔。我懂了。我相信问题出在 Android API 使用的算法上。并且图像在 JPEG 中看起来也有些颗粒感。差异真的很短,但足以让人眼(和我的客户)检测到它......无论如何,如果有人找到解决方案,请与我们分享! =)
  • 如果捕获的图片看起来比预览帧差,那么很可能图片尺寸太小。请注意,当您捕获一张巨大的图片(5 兆像素或更高)时,您应该使用 inSmapleScale 选项为 BitmapFactory 明智地使用堆。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多