我正在尝试使用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平板电脑。
答案 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;
}