请问如何使用camera2设置全屏preview,要求适配所有屏幕尺寸?

新手上路,请多包涵

本人学习camera2中,希望实现等比例的全屏预览。但是过程中参考网上资料包括官方demo,都是预览画面做出妥协改变自身的长宽比,在本人长宽比近2:1的三星note8手机上预览画面只能是全屏幕的一部分。但是本人又发现微信的拍照画面是等比例的全屏预览,包括note8。
希望有前辈能够解答我这个问题,简单的指引一下方向也可。

阅读 8.8k
3 个回答
新手上路,请多包涵

官方demo中的TextureView中重写了onMeasure方法,如下:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);
    if (0 == mRatioWidth || 0 == mRatioHeight) {
        setMeasuredDimension(width, height);
    } else {
        if (width < height * mRatioWidth / mRatioHeight) {
            setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
        } else {
            setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
        }
    }
}

这段代码使得TextureView在宽高都不超过手机屏幕的情况下最大化显示。
解决方案是,让TextureView总是达到最大边界,超出部分不进行预览(实际上还是能拍到的)。代码如下:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);
    if (0 == mRatioWidth || 0 == mRatioHeight) {
        setMeasuredDimension(width, height);
    } else {
        if (width > height * mRatioWidth / mRatioHeight) {    //注意这里骚操作,替换"小于号"为"大于号"
            setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
        } else {
            setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
        }
    }
}

实际上就是把判断条件中的 "<" 替换成 ">" 即可,天知道这一小段代码害惨多少程序员。。

新手上路,请多包涵

@mo_chan 这位大佬的答案我为什么没有早点看到...
我的需求不太一样:全屏预览的同时将预览图像传到物体检测算法中,得到检测结果(含有识别出的物体的矩阵信息,可以在传入的图像上将其框出来)并实时在预览图像上画出检测框。
当使用类似 @mo_chan 的方法时,需要将图像进行缩放才能保证框能够准确的画在物体上,但缩放会导致预览拉伸,所以最终使用了折中的方案:根据相机所能提供的分辨率和屏幕分辨率之间做“适配”,在做到预览不拉伸的前提下尽可能让预览尺寸接近全屏。
这里写了一篇博客:传送门

新手上路,请多包涵

解决我的问题了,真强。我自己分析不出来。您是如何分析出来的?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏