美文网首页
Android自定义相机填坑随笔

Android自定义相机填坑随笔

作者: Nikozxh | 来源:发表于2020-01-08 10:13 被阅读0次

Android自定义相机填坑随笔


笔者一个小小的Android开发,于某厂辛勤的拧螺丝。日常面对如洪水猛兽般的需求大潮,坚守自己一方微不足道的人权小岛!@#¥%……

牢骚差不多了,开始进入正式吐槽……尊敬的观众姥爷没听错,奏是继续吐槽。

随着笔者公司的战略重心迁移,我们开展了新的业务线。因业务需求中,我需要集成自定义相机,于是开始了旷日持久的自定义相机趟坑之旅。作为模块集成在第三方app中,沿用了第三方app配置,由于第三方适配机型版本较低,兼容性问题也是相当的多。回归到自定义相机的开发,简单叙述下开发相机过程踩过的大大小小的坑。

1.照片转置问题

在项目伊始,需求尚不明确,我们调用自定义相机获取照片。在某些机型上照片出现了旋转,由于测试设备匮乏(直至笔者今日都没解决),几经周折,找到了问题机型最多三星测试机,根据图片MetaData的旋转角将图片做相应的还原。

**
     * 读取图片的旋转的角度
     *
     * @param path 图片绝对路径
     * @return 图片的旋转角度
     */
    public static int getBitmapDegree(String path) {
        int degree = 0;
        try {
            // 从指定路径下读取图片,并获取其EXIF信息
            ExifInterface exifInterface = new ExifInterface(path);
            // 获取图片的旋转信息
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

MetaData仅仅在相机返回图片字节流生成的文件信息中能获取,一经压缩转换成bitmap之后就会丢失。笔者取到的旋转角始终为0,让笔者的胃很是翻江倒海。最后经过排查找到图片确实经过了转换。于是乎只要照片重置生成旋转角0的照片不就问题即将迎刃而解了?青年你的九九八十一难怎可如此简简单单就给你来个痛快,只有更多细腻的阻绊使你的开发之路多姿多彩。

2.相机重力问题

看到在三星测试机上转置处理完成,笔者喜形于色忍不住笑出猪叫来。可笔者拿起测试机拍摄了一张横拍照片,纳尼扩类,这就给转成一张竖屏照片了哈?!歪斜的图片笔者不自然的随着皂片歪起了脖子,久病之下的颈椎又刺激了中枢神经。所以说是笔者too young too navi,没有看出bug小妖背后隐藏的诸路仙君。由于是竖屏有拍摄问题,而横屏拍摄本身就是将照片做了旋转处理,如果仅仅按照皂片metadata做重置还原,只会将横屏照片还原为竖屏照片。

根据重力判断一下拍摄时是否是横屏,再做还原应该就可以了。于是乎笔者根据按下快门时重力做了相应处理。可为了适配横竖屏的情况,笔者在加入了横屏布局。也不得不因此委屈求全通过宽高判断屏幕朝向。

 DisplayMetrics dm = new DisplayMetrics();
            CameraActivity.this.getWindowManager().getDefaultDisplay().getMetrics(dm);
            int width = dm.widthPixels;
            int height = dm.heightPixels;
            if (height > width){
                // 竖屏
                isVertiPhoto = true;
            }else{
                // 横屏
                isVertiPhoto = false;
            }

终于旷日持久的相机大战中,笔者获得阶段性胜利。胜利的成果是喜悦的,胜利的路程是曲折的,曲折绝不是一时的。没错,在机型适配上,自定义相机继续绊了笔者一脚。

3.API判断错误


    @SuppressWarnings("WrongConstant")
    public CameraView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        if (isInEditMode()) {
            mCallbacks = null;
            mDisplayOrientationDetector = null;
            return;
        }
        // Internal setup
        final PreviewImpl preview = createPreviewImpl(context);
        mCallbacks = new CallbackBridge();
        if (Build.VERSION.SDK_INT < 21) {
            mImpl = new Camera1(mCallbacks, preview);
        } else if (Build.VERSION.SDK_INT < 23) {
            mImpl = new Camera2(mCallbacks, preview, context);
        } else {
            mImpl = new Camera2Api23(mCallbacks, preview, context);
        }
        // Attributes
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CameraView, defStyleAttr,
                R.style.Widget_CameraView);
        mAdjustViewBounds = a.getBoolean(R.styleable.CameraView_android_adjustViewBounds, false);
        setFacing(a.getInt(R.styleable.CameraView_facing, FACING_BACK));
        String aspectRatio = a.getString(R.styleable.CameraView_aspectRatio);
        if (aspectRatio != null) {
            setAspectRatio(AspectRatio.parse(aspectRatio));
        } else {
            setAspectRatio(Constants.DEFAULT_ASPECT_RATIO);
        }
        setAutoFocus(a.getBoolean(R.styleable.CameraView_autoFocus, true));
        setFlash(a.getInt(R.styleable.CameraView_flash, Constants.FLASH_AUTO));
        a.recycle();
        // Display orientation detector
        mDisplayOrientationDetector = new DisplayOrientationDetector(context) {
            @Override
            public void onDisplayOrientationChanged(int displayOrientation) {
                mImpl.setDisplayOrientation(displayOrientation);
            }
        };
    }

不难看出google提供的Api小于21,会实例化Camera1作为相机视图。但是令人惊奇的是,收到的崩溃日志Android 7.0的机器于Camera1处报错,大为惊诧之后,想想bug不修推锅给谷歌不现实,于是乎开始了调试之旅。

几经调查之后Camera1中会因为调用后stop()方法后,调用cancelAutoFocus()会报出无法在release()后使用api的错误。

笔者只能加上防护代码抵消报错。不过更神奇的是亲测小米8 Android 9.0 的测试机居然也初始化了Camera1的实例,奈何如何走到Camera1实例中又成为这个世纪最大的未解之谜。面对手上楚楚可怜几个测试机,只得双手合十,在2020年的心愿单上加上公司尽早补上主流机型测试机资源,早日助笔者脱离兼容性苦海。


随笔至此已入尾声,望着20后都要出生的新新时代,笔者再次感到万分压力。今年的职级是否能顺利提升,薪资是否能追上cpi的脚步,七大姑八大姨是否能在过年忘记笔者,都成为笔者来年的稀疏头顶的最大敌人。

望来年大事可成,未来可期。

相关文章

  • Android自定义相机填坑随笔

    Android自定义相机填坑随笔 笔者一个小小的Android开发,于某厂辛勤的拧螺丝。日常面对如洪水猛兽般的需求...

  • 自定义viewon之Measure

    自定义view随笔填坑-----onMeasure 子view的大小由父view的measureSpec和子vi...

  • Android Camera旋转角度分析

    开发过Android自定义相机的朋友估计都被相机的各种乱七八糟的旋转角度适配坑过,本文将对Camera的各种角度进...

  • Android自定义相机

    CustomCamera android自定义相机 功能描述: 主要可自定义相机的各类按钮布局 相机拍照缩放功能 ...

  • Android-自定义相机Camera

    前言 由于最近一个项目需要自定义相机这块,踩了很多坑,在这里做个记录,以防忘记。 Android Camera 相...

  • Android CameraX结合LibYUV和GPUImage

    目录 前言 之前使用Camera实现了一个自定义相机滤镜(Android自定义相机滤镜[https://www.j...

  • 填坑随笔

    俗话说自己挖的坑死也要填上。最近和一帮年轻人玩儿社群。看着他们鸡血满满,真心羡慕啊。我也算活跃,但鸡血槽内余额明显...

  • 自定义相机的旋转角度适配

    Android中时常会需要实现自定义的相机。但是应用可以横屏竖屏操作,所以自定义相机需要\设置Orientatio...

  • android 调起相册和相机的问题

    1:调起相册拍照 照片在相机里显示 android 6.0以下适配能在相机里显示时无法给照片自定义命名自定义命名...

  • 13.4 camera

    简介 android中相机使用有两种方式,一是调用系统相机(Intent),二是自定义相机 调用系统相机相册 自定...

网友评论

      本文标题:Android自定义相机填坑随笔

      本文链接:https://www.haomeiwen.com/subject/rzedactx.html