【问题标题】:Android Camera2 API preview sometimes distortedAndroid Camera2 API 预览有时会失真
【发布时间】:2017-04-10 09:20:21
【问题描述】:

我正在使用 Camera2 API 构建自定义相机。 到目前为止,除了预览有时会失真之外,相机工作得很好。假设我连续打开相机 7 次。所有尝试都成功,并且第 8 次相机预览失真。它看起来像使用宽度作为高度,反之亦然。

我的代码基于可在 here 找到的 camera2 的 Google 示例实现。 有趣的是,即使是 Google 示例实现有时也会出现这种扭曲的预览。我试图修改 AutoFitTextureView 但没有成功。我目前正在再次使用 Google 提供的 AutoFitTextureView.java。

can be found here 类似的帖子。 然而,建议的修复并没有解决问题。

我可以通过在 setUpCameraOutputs 方法中更改以下内容来重现该问题:

mTextureView.setAspectRatio(mPreviewSize.getHeight(), mPreviewSize.getWidth());

到:

mTextureView.setAspectRatio(mPreviewSize.getWidth(), mPreviewSize.getHeight());

另一个奇怪的事情是,每当出现失真的预览时,只要按下主页按钮,应用程序就会进入 onPause() 并再次打开应用程序以便调用 onResume(),每次预览都是完美的。

这里有没有人遇到过这个问题并找到了解决方法?

提前致谢

【问题讨论】:

  • 你找到解决办法了吗?我也面临这个问题。
  • 我也面临同样的问题

标签: android preview android-camera2 distortion camera2


【解决方案1】:

我在 Sony Xperia Z3 Tablet Compact 上遇到了同样的问题。

Alex 指出的拉取请求似乎对我不起作用。这会导致相机预览大于视图区域(预览被裁剪)。

虽然我无法具体跟踪问题,但我找到了解决方法。在打开相机的过程中,当 mTextureView 的大小发生变化时,似乎会发生失真。延迟相机打开过程可以解决此问题。

修改openCamera方法:

/**
 * Opens the camera specified by {@link StepFragmentCamera#mCameraId}.
 */
private void openCamera(int width, int height) {
    startBackgroundThread();

    if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
            != PackageManager.PERMISSION_GRANTED) {
        requestCameraPermission();
        return;
    }
    setUpCameraOutputs(width, height);
    configureTransform(width, height);

    /*
     * Delay the opening of the camera until (hopefully) layout has been fully settled.
     * Otherwise there is a chance the preview will be distorted (tested on Sony Xperia Z3 Tablet Compact).
     */
    mTextureView.post(new Runnable() {
        @Override
        public void run() {
            /*
             * Carry out the camera opening in a background thread so it does not cause lag
             * to any potential running animation.
             */
            mBackgroundHandler.post(new Runnable() {
                @Override
                public void run() {
                    Activity activity = getActivity();
                    CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
                    try {
                        if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
                            throw new RuntimeException("Time out waiting to lock camera opening.");
                        }
                        manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
                    }
                }
            });
        }
    });
}

【讨论】:

  • 我遇到了同样的问题,这解决了它。经过测试,需要调用mTextureView.post,以便在TextureView初始化后打开相机。我不需要mBackgroundHandler.post。我还必须注意mPreviewSize 不是来自 TextureView 本身;我需要通过使用由布局控制的 RelativeLayout 包装我的 TextureView 来修复该大小。
  • @BryanW.Wagner 使用tree observer 不是更好吗?
  • @AlexCohn 是的,可能;对于我的用例,我正在对 TextureView.SurfaceTextureListener 事件 onSurfaceTextureAvailableonSurfaceTextureSizeChanged 做出反应,以动态更改 TextureView 的大小。我的用例是从官方示例中导出的,但是有偏差,所以这个问题可能不在官方示例代码中。
  • @Miroslav 您的解决方案经过 2 天的挣扎后奏效了。谢谢!
【解决方案2】:

Google Camera2Basic 示例was finally fixed。原始代码有一个微小的 vs> 错误。错了 2 年。

【讨论】:

  • 不幸的是,您链接的拉取请求不能解决问题, 实际上是正确的。拉取请求中的代码是错误的,因为它会导致相机预览被裁剪(请参阅链接中的 cmets)。
  • @Miroslav,裁剪预览是该修复的预期结果。
  • 从我记得的测试结果来看,裁剪后的预览与相机要捕捉的实际场景大相径庭(大约一半不可见)。这当然不是故意的。此外,直到今天,拉取请求还没有被合并。
  • 我遇到了这个问题,我没有在示例代码中使用纵横比逻辑(我使用的是我自己的裁剪)。这是关于 TextureView 初始化的时间问题;需要@Miroslav 的回答。
猜你喜欢
  • 1970-01-01
  • 2017-09-09
  • 2020-04-06
  • 1970-01-01
  • 1970-01-01
  • 2018-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多