Camera 预览拉伸问题处理

欢迎关注我的个人博客:http://www.offday.club/

问题现象

之前负责人脸识别的模块,遇到一个很奇怪的问题。录入时,人脸预览有拉伸的迹象的(之前的项目都是好好的),后面花了一天半的时间,终于将此问题解决,故想写一篇总结,记录自己的解决问题的过程。

PS:公司不同品牌的手机很多,其他手机都没有预览问题,单独有一个项目存在着预览拉伸的问题。

问题背景

使用的自定义surfaceview

当前使用的是camera API2 (因为Android P 版本不支持HAL1.0了,所以camera api1也被我们渐渐舍弃了=-=)

分析过程

第一直觉:

当初自己的第一直觉是,emmm,这应该是跟分辨率有关系。因为其他没有问题的手机,我看了下分辨率,都是7201500;而唯独发生拉伸现象的手机是10802160的。

于是我就在自定义Surfaceview中,看了下Surfaceview的大小,发现:

720*1500 手机width:480 height:640

1080*2160 手机width:720 height:960

Emmm,其实可以理解,不同分辨率,surfaceview的大小会进行对应调整。但不难发现,宽高比是一致的。

所以,我排除了跟分辨率的关系。

以下为自定义view中onMeasure的重写部分:


    @Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        int widthSize = MeasureSpec.getSize(widthMeasureSpec);

        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        Log.e("onMeasure", "widthMeasureSpec = " +widthSize + "  heightMeasureSpec = " + heightSize + "height = " + height);

        setMeasuredDimension(widthSize, heightSize);

    }

了解产生拉伸的原因:

之后,上网查了一些资料,camera previewSize需要跟surfaceview的大小比例不一致就会产生拉伸效果。(我认为的比例一致就是宽高比是一致的,但我解完这个问题后,只想说,不知道camera的预览方向,真心难以理解)。

产生预览拉伸的原因

Camera预览方向跟拍照方向

如果你已经看了上面的两篇文档,那么就不难理解了。因为camera默认的取景方向是横向的,所以上面的话我们应该如下理解:Camera previewSize的宽高比跟surfaceview的高宽最简比一致,就不会拉伸。

举个例子:

可以看下我附件的Demo(利用camera1预览,写的非常简单,仅仅提供了个预览功能,只是为了验证这个例子而已),如果我们不设置setDisplayOrientation来改变预览角度,那么预览就会是横屏的,所以按照横屏的方式来计算,surfaceview的宽度实际对应着高度,从而验证上述的想法。

当然很多情况下,camera previewSize跟surfaceview的最简比乘积不一定一致,那么

这个时候预览就肯定会拉伸,但是为了防止拉伸(压缩)明显,就要找跟previewSize最为相近的比例去设置surfaceview的宽跟高。

拿我下面获取的camera previewSize为例,比如说:

全面屏手机比例是1500720。而surfaceview恰好是全屏的,那么此时camera previewSize其实并没有1500720的比例,你就需要设置最为接近的1600*800的previewSize,这样才可以将拉伸(压缩)的效果降到最低。反之相同。

那知道了这个产生问题,后面的问题就都好说了。

如何获取camera 预览尺寸:

很明显,此问题的两个重要关键点就是camera previewSize以及surfaceview的Size大小,那么,我们首先要做的,就需要优先获取当前手机camera previewSize所支持的那些?

Camera APi2 获取camera预览尺寸的方法:

private void choosePreview() {

    try {

        CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics("1");

        StreamConfigurationMap map = characteristics.get(

                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);

        Size[] preview = map.getOutputSizes(SurfaceHolder.class);

        for (int i = 0 ;i <= preview.length ; i++) {

            Log.d(TAG,"preview width = " + preview[i].getWidth() + ", height = " + preview[i].getHeight());

        }

    } catch (Exception exception) {

    }

}

Camera API1 获取camera previewSize的方法:

List<Camera.Size> allSupportedSize = camPara.getSupportedPreviewSizes();

文章最后见手机支持的尺寸。

如何设置camera previewSize:

虽然知道了手机camera previewSize的大小,但是如果不知道如何设置,其实也算是白搭。

Camera API1 设置camera previewSize:

params.setPreviewSize(cameraWidth, cameraHeight);

Camera API2 设置previewSize:

Surfaceview

mSurfaceHolder.setFixedSize(heightSize, widthSize);// 此方法是设置surface的size的,可以认为surface的size代表camera的PreviewSize

2.TextureView (参考官方Demo)


SurfaceTexture texture = mTextureView.getSurfaceTexture();

// We configure the size of default buffer to be the size of camera preview we want.

texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());

万事具备了,东风都不需要了,后面只需要将上面所提到的方法运用到自己具体的例子中就好了。

拿我的自定义view来说:

为了简单,我将设置surfaceview的大小跟设置camera previewSize的大小写在一起了。也方便后面的同事进行排查。

以下为我的修改方案,仅仅是加了一行代码,就解决了拉伸问题。

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);

    int heightMode = MeasureSpec.getMode(heightMeasureSpec);

    int widthSize = MeasureSpec.getSize(widthMeasureSpec);

    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    ...

    Log.e("onMeasure", "widthMeasureSpec = " +widthSize + "  heightMeasureSpec = " + heightSize + "height = " + height);

    //添加了如下代码

    mSurfaceHolder.setFixedSize(heightSize, widthSize);

    setMeasuredDimension(widthSize, heightSize);

}

PS:以下是 setFixedSize的方法描述,可以看到传参先是宽,之后是高。但是我自己项目中却传入的是setFixedSize(heightSize, widthSize)。

/**

 * Make the surface a fixed size.  It will never change from this size.

 * When working with a {@link SurfaceView}, this must be called from the

 * same thread running the SurfaceView's window.

 *

 * @param width The surface's width.

 * @param height The surface's height.

 */

public void setFixedSize(int width, int height);

其实有一点是需要注意的,那就是camera previewSize的宽一般要大于高的。

详细参考:https://blog.csdn.net/mengzhengjie/article/details/70859396

参考链接:

https://blog.csdn.net/yanzi1225627/article/details/17652643

https://blog.51cto.com/ticktick/1592267

https://blog.csdn.net/mengzhengjie/article/details/70859396

总结:

此种修改仅仅解决的是预览拉伸的问题,拍照拉伸等问题后续会慢慢了解的,但是我相信,万变不离其宗,将本文中的精髓了解到,拍照拉伸的问题依旧迎刃而解了。

小弟初步学习Camera,有什么不对的地方还请各位指正。

Demo下载地址:

大家看下百度云吧。

下载地址

提取码:w5bk

以下是我debug用的手机支持的部分尺寸:

Line 229: 03-04 22:33:28.565 1887 1887 D Camera: preview width = 1600, height = 800

..

Line 234: 03-04 22:33:28.565 1887 1887 D Camera: preview width = 960, height = 720

Line 235: 03-04 22:33:28.565 1887 1887 D Camera: preview width = 960, height = 540
..

Line 241: 03-04 22:33:28.565 1887 1887 D Camera: preview width = 176, height = 144

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355