4

我有一个应用程序,客户端使用相机拍照。在人们点击我的“点击”按钮之前,图像的预览正在使用 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() 回调的字节数组中?

先感谢您!!=)

4

1 回答 1

2

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

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

因此,您必须将byte[] dataonPictureTaken() 回调中的转换为位图,并将该位图映射到您应该放置在 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();
}
于 2012-06-19T11:32:24.573 回答