使用Camera2的相机预览很暗

时间:2018-07-31 16:12:23

标签: android android-camera2

我正在尝试使用Camera2允许应用拍摄简单的照片。我设法使用android-Camera2Basic sample code得到了一个有效的样本,问题是相机预览非常暗(与this other question相同),经过一些回答,我确实获得了适当的FPS范围[15,15] ,通过在lockFocus()方法中进行设置,可以使应用以正确的亮度呈现清晰的图片,并修复相机的预览:

private void lockFocus() {
    try {
        // This is how to tell the camera to lock focus.
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, Range.create(15, 15));

        // Tell #mCaptureCallback to wait for the lock.
        mState = STATE_WAITING_LOCK;
        mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

但是拍照之前的预览仍然很暗。我试图在示例的其他部分中设置同一行代码,但无法正常工作。我如何解决此问题,以便在预览中获得相同的结果?我正在使用三星SM-P355M平板电脑。

2 个答案:

答案 0 :(得分:0)

在进行大量研究后,没有简单的解决方案(至少不是在使用相同的硬件的情况下),因此这次我们使用不推荐使用的Camera Api实现了新版本的Camera活动,并且一切正常。并不是一个很干净的解决方案,但到目前为止对我有用。

答案 1 :(得分:0)

使用上下限相等的FPS范围,例如[15,15],[30,30],[etc ...],将限制AE算法的调整范围光线变化,因此可能会产生黑暗的结果。此类范围用于视频录制以保持恒定的FPS。对于照片,您需要找到一个上下限较大的范围,例如[7,30],[15,25],[etc ...]

下一种方法可以帮助您找到最佳的FPS范围。考虑到它只用于照片而不是视频记录,因为它丢弃上下限相等的FPS范围。

(根据您的要求调整 MIN_FPS_RANGE MAX_FPS_RANGE

@Nullable
public static Range<Integer> getOptimalFpsRange(@NonNull final CameraCharacteristics characteristics) {
    final int MIN_FPS_RANGE = 0;
    final int MAX_FPS_RANGE = 30;

    final Range<Integer>[] rangeList = characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);

    if ((rangeList == null) || (rangeList.length == 0)) {
        Log.e(TAG, "Failed to get FPS ranges.");
        return null;
    }

    Range<Integer> result = null;

    for (final Range<Integer> entry : rangeList) {
        int candidateLower = entry.getLower();
        int candidateUpper = entry.getUpper();

        if (candidateUpper > 1000) {
            Log.w(TAG,"Device reports FPS ranges in a 1000 scale. Normalizing.");
            candidateLower /= 1000;
            candidateUpper /= 1000;
        }

        // Discard candidates with equal or out of range bounds
        final boolean discard = (candidateLower == candidateUpper)
                || (candidateLower < MIN_FPS_RANGE)
                || (candidateUpper > MAX_FPS_RANGE);

        if (discard == false) {
            // Update if none resolved yet, or the candidate
            // has a >= upper bound and spread than the current result
            final boolean update = (result == null)
                    || ((candidateUpper >= result.getUpper()) && ((candidateUpper - candidateLower) >= (result.getUpper() - result.getLower())));

            if (update == true) {
                result = Range.create(candidateLower, candidateUpper);
            }
        }
    }

    return result;
}