【问题标题】:Camera2 api problems firing flash/no flash imagesCamera2 api 问题触发闪光灯/无闪光灯图像
【发布时间】:2017-03-28 12:21:22
【问题描述】:

我会解释我的情况。 我正在尝试做一个应用程序,其中每 5 秒拍摄一张图像,一张没有闪光灯,然后在 5 秒后拍摄一张有闪光灯的图像,并且每次都重复此操作。所以它需要一个不带闪光灯,一个带闪光灯,一个不带闪光灯,一个带闪光灯......无限。

情况是,使用我的代码,我可以在某些设备上执行此操作,但相同的代码在其他设备上无法正常工作。即:

  • BQ Aquaris X5 Plus : 无闪光图像是正确的,但闪光图像将只是白色。
  • BQ Aquaris E5:不会闪光。

这怎么可能,我尝试过的所有设备都是对 Camera2 API 的 LEGACY 硬件支持级别。

这是我代码中的一些重要方法(由于字符限制,我无法发布所有代码)。我从 Google 示例开始:

这个 setAutoFlash 做了上面提到的。

private void setAutoFlash(CaptureRequest.Builder requestBuilder) {
        if (mFlashSupported) {
            if(phototaken) {
                requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
                requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
            }else{
                requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE);
            }
        }
    }

另一个在某些设备和 bq aquaris e5 中有效,但在 bq aquaris x5 plus 中不闪光。

private void setAutoFlash(CaptureRequest.Builder requestBuilder) {
        if (mFlashSupported) {
            if(phototaken) {
                requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
                requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
            }else{
                requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
                requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
            }
        }
    }

还有我的 captureStillPicture

private void captureStillPicture() {
        try {
            final Activity activity = getActivity();
            if (null == activity || null == mCameraDevice) {
                return;
            }
            // This is the CaptureRequest.Builder that we use to take a picture.
            final CaptureRequest.Builder captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            captureBuilder.addTarget(mImageReader.getSurface());

            // Use the same AE and AF modes as the preview.
            captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            setAutoFlash(captureBuilder);

            // Orientation
            int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
            captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));

            CameraCaptureSession.CaptureCallback CaptureCallback
                    = new CameraCaptureSession.CaptureCallback() {
                @Override
                public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                                               @NonNull CaptureRequest request,
                                               @NonNull TotalCaptureResult result) {
                    showToast("Saved: " + mFile);
                    Log.d(TAG, mFile.toString());
                    unlockFocus();
                }
            };

            mCaptureSession.stopRepeating();
            mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);
            phototaken = !phototaken;

        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
}

问题是,我做错了什么,所以它不适用于所有设备?任何帮助都会很棒。

【问题讨论】:

    标签: android camera2 camera-flash


    【解决方案1】:

    闪光灯有两个级别的控制 - 手动和由自动曝光程序控制。您目前正在将它们混合在一起。

    如果要手动触发闪光灯,则需要将 AE_MODE 设置为 AE_MODE_OFF 或 AE_MODE_ON;不是任何 FLASH 模式。然后,FLASH_MODE 将控制闪光灯是否处于手电筒模式、关闭或针对给定请求触发一次。

    由于您总是将 AE_MODE 置于其中一种 FLASH 状态,因此您对 FLASH_MODE 所做的操作应该无关紧要,除非某些特定设备中出现错误。

    如果要保证每隔一张照片都闪光,强制闪光照片需要使用AE_MODE_ON_ALWAYS_FLASH,不闪光照片需要使用AE_MODE_ON;不要触摸 FLASH_MODE。 现在,使用 AUTO_FLASH,是否闪光取决于设备,因此您会看到不同设备和照明条件下的不同行为 - 有些会闪光,有些不会。

    您没有做的另一件事是运行预捕获序列;这对于闪光照片至关重要,因为它允许设备触发预闪以确定正确的闪光功率、焦点和白平衡。

    要运行预捕获,请根据需要设置 AE_MODE,然后针对一个请求将 AE_PRECAPTURE_TRIGGER 设置为 START。这会将 AE_STATE 转换为 PRECAPTURE,并且会在那里停留若干帧;一旦 AE_STATE 不再是 PRECAPTURE,您就可以发出实际的图像捕获请求。确保在整个过程中保持 AE_MODE 一致。

    示例应用Camera2Basic 实现了预捕获序列,所以看看那里;它还有一些优化可以跳过预捕获,以防场景不够暗而需要闪光灯,但由于您想强制闪光,这与您无关。

    【讨论】:

    • 嗨@Eddy,感谢您的回答。但它仍然不起作用。我已将 AE_MODE 设置为 AE_MODE_ON,然后只需更改 FLASH_MODE。我正在使用您提到的示例应用程序 Camera2Basic,据我所知,它在 lockFocus 方法中运行预捕获序列。为了拍照,我像示例一样调用此方法。所以我假设我也在触发预捕获序列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-02
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    相关资源
    最近更新 更多