安卓相机预览过暗

11

我正在尝试创建一个自定义相机应用程序。我遵循了这里的Android开发者示例,并进行了一些小调整。然而,我的相机预览效果非常暗淡。另一方面,原生相机给出了更明亮的预览。

我尝试了几个设置来使它工作得更好,但似乎没有任何影响。相关代码发布在此处。

CameraActivity(主要)

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_camera);
    if(CameraHelper.checkCameraHardware(this)) {
        mHelper = new CameraHelper(this, getWindowManager().getDefaultDisplay());
    }

    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
    mPreview = new CameraPreview(this, CameraHelper.camera);
    mPreview.setLayoutParams(new LayoutParams(CameraHelper.mSize.width, CameraHelper.mSize.height, Gravity.CENTER));

    preview.addView(mPreview);

}

CameraHelper类(初始化相机并设置默认参数)

    public CameraHelper(CameraListener listener, Display display){
        mListener = listener;
        camera = getCameraInstance();

        mParameters = camera.getParameters();
        initCameraParameters();

        mSize = getPreviewSize(display);
        mParameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
        mParameters.setPictureSize(2560, 1920);

        mParameters.setAutoExposureLock(false);
        mParameters.setAutoWhiteBalanceLock(false);
        mParameters.set("iso", "ISO800"); //Tried with 400, 800, 600 (values obtained from flatten())
        mParameters.setColorEffect("none");
        mParameters.setPictureSize(2560, 1920);
        mParameters.setPreviewFrameRate(20);
        mParameters.set("scene-mode", "auto");
        mParameters.setFocusMode("auto");
        mParameters.setExposureCompensation(4);     
        camera.setParameters(mParameters);
    }
相机从上面开发者页面链接的示例中将帧发送到SurfaceHolder.Surface。 这里有一个区别: 股票相机应用程序 我的相机应用程序 根据此处发布的摄像机数据包参数设置ISO等。它仍然不起作用。 在下方评论的基础上进行进一步测试后,编辑:似乎只是预览比它应该更暗淡。实际捕获的图像光线很好,曝光补偿似乎正常工作。只是预览让我头痛。在运行CM11的i9003和运行原生Android的Nexus 10上进行了测试。

你从 "params.getMinExposureCompensation()" 和 "params.getMaxExposureCompensation()" 中获取了曝光补偿的最大/最小值吗? - Florian Barth
是的,最初我使用params.getMaxExposureCompensation()设置了最大曝光值,但当它没有效果时,我尝试根据从params.unpack()接收到的转储手动设置它(范围从4到-4)。请参见上面的转储转储。 - Puneet
我进一步测试了它。结果发现曝光设置对预览没有影响,但实际图像亮度良好。现在,如何将预览与实际图像同步?有什么建议吗?(编辑:我将使用新信息编辑问题)。 - Puneet
请注意,您的代码尝试将帧速率设置为20,但参数显示仅支持30。这种不一致可能会在某些设备上造成大麻烦。 - Alex Cohn
我也遇到了同样的问题...设置帧率和场景模式对我也没有用,所以这不是你的错觉 :-( - kenyee
显示剩余7条评论
3个回答

14

似乎有一些相机会错误地报告支持的预览FPS范围。您可以通过调用 getPreviewFpsRange(int[] range) 并返回最小值和最大值相同的设备来识别引发问题的设备。

在我的情况下,我发现这个问题出现在报告 (15000, 15000)(30000, 30000) 的设备上,而对于值不同的设备,如 (7000, 30000),则没有此问题。

我能找到的最佳解决方案是确定支持的FPS范围并设置具有不同最小和最大值的范围:

Camera.Parameters params = camera.getParameters();
final int[] previewFpsRange = new int[2];
params.getPreviewFpsRange(previewFpsRange);
if (previewFpsRange[0] == previewFpsRange[1]) {
    final List<int[]> supportedFpsRanges = params.getSupportedPreviewFpsRange();
    for (int[] range : supportedFpsRanges) {
        if (range[0] != range[1]) {
            params.setPreviewFpsRange(range[0], range[1]);
            break;
        }
    }
}
camera.setParameters(params);

这个方法有效是因为所报告的范围似乎只有一个实际范围项。例如:

BLU Vivo XL:

preview-fps-range=30000,30000
preview-fps-range-values=(15000,15000),(20000,20000),(24000,24000),(5000,30000),(30000,30000)

像素:

preview-fps-range=7000,30000
preview-fps-range-values=(15000,15000),(24000,24000),(7000,30000),(30000,30000)

一种更加健壮的方法是通过比较所有可用项来设置最小值和最大值。


这很可能是原始问题的原因:正如我在评论中指出的那样,代码将FPS设置为20,而相机报告支持范围为(15-30)fps。 - Alex Cohn
在我的Nexus 7中,我可以更改场景模式,但无法在预览中显示颜色效果,即使拍摄的照片也有效果。按下快门按钮时,我可以看到颜色效果仅持续几分之一秒。我尝试了所有FPS范围的组合,但没有用。有什么想法吗? - Praveena
让我尝试一下帧数(修正)调整,然后再回复你。我尝试了很多设置,所以我很担心。 - Puneet
@Praveen:不,我不知道为什么颜色效果无法保持。我这里没有 Nexus 7 设备可以检查。 - Alex Cohn
非常感谢,这也为我们解决了许多设备上的问题! - Viish
Kindle Fire HD 2018运行Android 9.0。这对我来说解决了问题。谢谢! - anonymous-one

4
除了之前的回答,如果您正在使用Camera2进行操作,则可能会出现这种情况。
createCaptureRequest(CameraDevice.TEMPLATE_RECORD)

更改为

createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)

更新:我还开始在一些新的Pixel设备上看到了黑暗预览,如果你没有在捕获请求中设置fps或者将fps设置为设备无法处理的值,则会出现这种情况。但是在Note 10和S10等三星设备上不会出现这种情况。


这对我解决了问题。但我想知道使用这个模板会失去什么(可能是视频质量)。 - Vlad
我也试过了,和@Vlad一样有同样的担忧。 - prex
1
在预览状态下,您应该使用“CameraDevice.TEMPLATE_PREVIEW”。然后,一旦准备好录制,您可以切换到“TEMPLATE_RECORD”以进行捕获请求。 - Machine Tribe

1
从我的实验中,场景模式设置可以改变预览(不像ISO或曝光补偿,它们都适用于拍摄的照片)。不要使用自动。尝试scene-mode-values=nightscene-mode=dusk-dawn
场景的问题在于支持的值在设备之间没有标准化。但是通常会有某种夜间模式。

1
我已在Nexus 7(Android L)上进行了测试,前置摄像头工作正常,但后置摄像头显示暗预览。我尝试设置夜间模式,但没有用。我尝试了其他流行的相机应用程序,发现它们也无法解决这个问题。唯一正常工作的相机是谷歌相机。这是否与颜色效果有关? - Praveena
@Praveen:我并没有在GoogleCamera上进行逆向工程,但根据其要求(4.4及更高版本)和对Nexus设备的额外关注,我可以推测他们已经调整过它,以适应Nexus 7上不太好的后置摄像头。 - Alex Cohn
场景模式,如夜间或派对,将激活相机 - 至少在Nexus 5上是这样的。我的做法是测量光线,然后根据光线逐渐改变曝光值。这导致了一个不错的结果。 - slott
1
@AlexCohn 感谢您的回复。我认为必须使用Camera2 API而不是已弃用的Camera API。刚刚我在我的Nexus 7上使用了Camera2 API,令人惊讶的是一切都正常工作。但我唯一的问题是,我的应用程序有很多自定义内容,而且将其移植到Camera2需要太多的工作量。 - Praveena
@Praveen:感谢您提供这些信息。相机2在Nexus 7(Android L)上的表现比弃旧的API更好,这并不令人惊讶。我想知道,旧的ROM是否会有同样的表现。不幸的是,我遇到了一些4.4+的原生ROM没有支持Camera2(尽管这是强制性的),而且从商业角度来看,旧的API将需要一段时间才能退出市场。 - Alex Cohn
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接