Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/212.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Camera2 api问题触发闪存/无闪存图像_Android_Camera2_Camera Flash - Fatal编程技术网

Android Camera2 api问题触发闪存/无闪存图像

Android Camera2 api问题触发闪存/无闪存图像,android,camera2,camera-flash,Android,Camera2,Camera Flash,我会解释我的情况。 我试着做一个应用程序,每5秒拍摄一张图像,一张没有闪光灯,5秒后一张有闪光灯,每次重复这个过程。所以需要一个没有闪光灯,一个有闪光灯,一个没有闪光灯,一个有闪光灯。。。无限 我的代码可以在某些设备上实现这一点,但同样的代码在其他设备上无法正常工作。i、 e: BQ Aquaris X5 Plus:无闪光图像是正确的,但闪光图像仅为白色 BQ Aquaris E5:不会触发闪光灯 这怎么可能呢,我尝试过的所有设备都是Camera2 API的传统硬件支持级别 这是我代码中的一

我会解释我的情况。 我试着做一个应用程序,每5秒拍摄一张图像,一张没有闪光灯,5秒后一张有闪光灯,每次重复这个过程。所以需要一个没有闪光灯,一个有闪光灯,一个没有闪光灯,一个有闪光灯。。。无限

我的代码可以在某些设备上实现这一点,但同样的代码在其他设备上无法正常工作。i、 e:

  • BQ Aquaris X5 Plus:无闪光图像是正确的,但闪光图像仅为白色
  • BQ Aquaris E5:不会触发闪光灯
这怎么可能呢,我尝试过的所有设备都是Camera2 API的传统硬件支持级别

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

此设置AutoFlash执行上述操作

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);
            }
        }
    }
还有我的照片

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();
        }
}

问题是,我做错了什么,所以它不能在所有设备上工作?任何帮助都会很好。

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

如果要手动启动闪光灯,则需要将AE_模式设置为AE_模式关闭或AE_模式打开;没有任何闪光模式。然后,闪光灯模式将控制闪光灯是否处于火炬模式、关闭或针对给定请求触发一次

由于您总是将AE_模式保持在其中一种闪存状态,因此您对FLASH_模式所做的操作应该无关紧要,除非某些特定设备中出现错误

如果你想保证每隔一张照片中都有闪光,你需要对强制闪光照片使用AE_MODE_ON_ALWAYS_flash,对无闪光照片使用AE_MODE_ON;不要触摸闪光灯模式。 现在,使用AUTO_FLASH,是否启动闪光灯取决于设备,因此您将看到不同设备和照明条件下的不同行为-一些会启动,一些不会

你没有做的另一件关键的事情是运行一个预设序列;这对于flash图片至关重要,因为它允许设备启动预闪光以确定正确的闪光功率、焦距和白平衡

要运行预许可,请根据需要设置AE_模式,然后将AE_precapture_触发器设置为启动一个请求。这会将AE_状态转换为预紧状态,并在一定数量的帧内保持该状态;一旦AE_状态不再是PRECAPTURE,您就可以发出实际的图像捕获请求。确保在整个过程中保持AE_模式的一致性


示例应用程序实现了precapture序列,请看这里;它还进行了一些优化,可以在场景不够暗而不需要闪光灯的情况下跳过预拍摄,但由于您想强制使用火焰闪光灯,这与您无关。

Hi@Eddy,谢谢您的回答。但它仍然不起作用。我已经将AE_模式设置为AE_模式,然后只需更改FLASH_模式。正如你提到的,我正在使用示例应用程序Camera2Basic,据我所知,它在lockFocus方法中运行预拍摄序列。为了拍摄照片,我将此方法称为示例。所以我想我也在启动预缝合序列。