Camera Paramter 深度封装( 第一弹 )

1 篇文章 0 订阅
1 篇文章 0 订阅
这篇博客主要介绍了在实习期间对相机参数进行深度封装的过程,以解决获取参数信息不全面的问题。作者提供了代码仓库链接,并详细说明了如何封装全局相机参数以及构建CameraParamter操作类,特别是如何构建PictureSizes集合。
摘要由CSDN通过智能技术生成

概要

实习期间,需要相机的参数进行调用,通常我们调用的时候就直接通过调用Camera.getParamters( )就可以获得其中参数信息,但是,在开发的过程中就会发现了一个问题,其中的一些参数信息的获取是不全面的,例如:有一些参数信息室友isSupported( )方法去判断是否支持的,有一些是没有的.这就需要对相机参数进行进一步封装.


先附上代码地址:https://github.com/DoggyZhang/CameraParamter

1,封装全局相机参数

首先创建出对相机参数信息的简单枚举封装

public enum Ratio {
    R_4x3(
            0, 4, 3, "4:3"),
    R_16x9(
            1, 16, 9, "16:9");

    private int id;

    public int w;

    public int h;

    private String name;

    Ratio(int id, int w, int h, String name) {
        this.id = id;
        this.w = w;
        this.h = h;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public static Ratio getRatioById(int id) {
        for (Ratio ratio : values()) {
            if (ratio.id == id) {
                return ratio;
            }
        }
        return Ratio.R_16x9;
    }

    public static Ratio getRatioByName(String name) {
        for (Ratio ratio : values()) {
            if (ratio.toString().compareTo(name) == 0) {
                return ratio;
            }
        }
        return Ratio.R_16x9;
    }

    public static Ratio pickRatio(int width, int height) {
        for (Ratio ratio : values()) {
            float orignalRatio = ratio.w * 1.0f / ratio.h;
            float targetRatio = width * 1.0f / height;
            if (Math.abs(orignalRatio - targetRatio) < 0.1f) {
                return ratio;
            }
        }
        return Ratio.R_16x9;
    }

    @Override
    public String toString() {
        return name;
    }

}
这里需要注意一点,使用枚举的原因是因为这些属性都是一些常量值,而且我们在构建相对应的对象的时候,也会十分的方便
列出需要的一些枚举类



2,构建CameraParamter操作类

这个类写的我真是心累,挫了1000多行代码,不说废话了。
该类的主要功能就是
1. 判断相机是否支持该参数
2. 获取相机支持的参数列表
3. 设置相机支持的参数

简单的附上类的属性

这样写的灵感还是来源于前面提起的开源项目,比较巧妙的利用集合封装了相机支持并可以设置的参数信息,这里封装的比也行就不用多说了。

列举其中 PictureSizes 是如何构建出来的

构建相对应的集合

/**
     * PictureSize
     *
     * @param sizes 获取相机支持的 pictureSize , Camera.paramter.getSupportedPictureSizes()方法获得
     * @return
     */
    private Map<Ratio, Map<Quality, Size>> buildPictureSizesRatioMap(List<Size> sizes) {
        Map<Ratio, Map<Quality, Size>> map = new HashMap<>();

        Map<Ratio, List<Size>> ratioListMap = new HashMap<>();
        // 选出Ratio.R_4x3 , Ratio.R_16x9 比例对应的大小集合
        for (Size size : sizes) {
            Ratio ratio = Ratio.pickRatio(size.width, size.height);
            if (ratio != null) {
                List<Size> sizeList = ratioListMap.get(ratio);
                if (sizeList == null) {
                    sizeList = new ArrayList<>();
                    ratioListMap.put(ratio, sizeList);
                }
                sizeList.add(size);
            }
        }
        // 挑出集合中的前三个作为不同 picture 质量
        for (Ratio r : ratioListMap.keySet()) {
            List<Size> list = ratioListMap.get(r);
            ratioListMap.put(r, sortSizes(list));
            Map<Quality, Size> sizeMap = new HashMap<>();
            int i = 0;
            for (Quality q : Quality.values()) {
                Size size = null;
                if (i < list.size()) {
                    size = list.get(i++);
                }
                sizeMap.put(q, size);
            }
            map.put(r, sizeMap);
        }

        return map;
    }



设置对应的相机信息

/**
     * 设置 PictureSize
     * @param ratio Picture 比例
     * @param quality Picture 在该比例下的图片质量 
     */
    public void setPictureSize(@NonNull Ratio ratio, Quality quality) {
        if (mCameraParamter == null) {
            throw new RuntimeException("CameraParamter is null , please inject MyCameraParamter.getInstance() !!!");
        }
        if (!isInit) {
            throw new RuntimeException("CameraParamter is not init , please inject MyCameraParamter.initParams !!!");
        }
        if (!supportPictureSize) {
            return;
        }
        // 默认是 16 : 9 的图片比例
        if (this.pictureRatio != ratio) {
            if (ratio == null) {
                ratio = Ratio.R_16x9;
            }
            this.pictureRatio = ratio;
        }
        
        // 默认高质量图片
        if (this.pictureQuality != quality) {
            if (quality == null) {
                quality = Quality.HIGH;
            }
            this.pictureQuality = quality;
            mParameters.setJpegQuality(quality.getQualityValue());
            // 存入 SharePreferences , 以方便下次初始化的时候使用
            PreferenceUtils.put(mContext, PreferenceConfiguration.PICTURE_QUALITY, this.pictureQuality.toString());
        }

        Size size = pictureSizes.get(ratio).get(quality);
        if (size != null) {
            mParameters.setPictureSize(size.width, size.height);
        }
    }

3. 使用CameraParatmer

初始化相机参数

初始化Camera对象,并获取CameraParamter的对象(单例)

/**
     * 初始化相机
     *
     * @param cameraID CAMERA_ID_BACK , CAMERA_ID_FRONT
     *                 默认是 back
     */
    private void initCamera(int cameraID) {
        mCameraCount = Camera.getNumberOfCameras();
        mSupportedFrontCamera = false;
        if (mCameraCount > 1) {
            mSupportedFrontCamera = true;
        }

        // 默认打开后置摄像头
        switch (cameraID) {
            case CAMERA_ID_BACK:
                mCurrentCameraID = CAMERA_ID_BACK;
                break;
            case CAMERA_ID_FRONT:
                if (mSupportedFrontCamera) {
                    mCurrentCameraID = CAMERA_ID_FRONT;
                } else {
                    Toast.makeText(getContext(), "不支持前置摄像头", Toast.LENGTH_SHORT).show();
                    mCurrentCameraID = CAMERA_ID_BACK;
                }
                break;
            default:
                mCurrentCameraID = CAMERA_ID_BACK;
                break;
        }
        mCamera = Camera.open(mCurrentCameraID);
        if (mCamera == null) {
            Toast.makeText(getContext(), "打开相机失败", Toast.LENGTH_SHORT).show();
            throw new RuntimeException("fail to open camera !!!");
        }

	// 这里是初始化CameraParamter, 一定要记得调用initParams()
        mCameraParamter = CameraParamter.getInstance(getContext(), mCamera.getParameters());
        mCameraParamter.initParams();
        mCamera.setParameters(mCameraParamter.getParameters());

        mCamera.setDisplayOrientation(CAMERA_DISPLAY_ORIENTATION);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            mCamera.enableShutterSound(true);
            isShutterSoundEnable = true;
        }

        mCamera.setFaceDetectionListener(new Camera.FaceDetectionListener() {
            @Override
            public void onFaceDetection(Camera.Face[] faces, Camera camera) {
                Toast.makeText(getContext(), "检测到了 " + faces.length + " 张脸", Toast.LENGTH_SHORT).show();
            }
        });
    }

设置相机参数

这里使用了自定义了接口,通过接口回调的方式来动态的设置相机参数
接口:
public interface OnCameraParamterChangeListener {
    void onFaceDetectChange(CameraParamter cameraParamter, boolean isOpen);

    void onFocusModeChange(CameraParamter cameraParamter, FocusMode focusMode);

    void onPreviewRatioChange(CameraParamter cameraParamter, Ratio ratio);

    void onPictureRatioChange(CameraParamter cameraParamter, Ratio ratio);

    void onPictureQualityChange(CameraParamter cameraParamter, Quality quality);

    void onColorEffectChange(CameraParamter cameraParamter, ColorEffect colorEffect);

    void onSceneModeChange(CameraParamter cameraParamter, SceneMode sceneMode);

    void onWhiteBalance(CameraParamter cameraParamter, WhiteBalance whiteBalance);

    void onAntiBindingChange(CameraParamter cameraParamter, String antiBinding);

    void onVideoQualityChange(CameraParamter cameraParamter, Quality quality);
}
在需要回调的地方实现接口,回调方法

@Override
    public void onFaceDetectChange(CameraParamter cameraParamter, boolean isOpen) {
        if (isOpen) {
            mCamera.startFaceDetection();
        } else {
            mCamera.stopFaceDetection();
        }
        mCameraParamter = cameraParamter;
        mCamera.setParameters(mCameraParamter.getParameters());
    }

    @Override
    public void onFocusModeChange(CameraParamter cameraParamter, FocusMode focusMode) {
        mCameraParamter = cameraParamter;
        mCamera.setParameters(mCameraParamter.getParameters());
    }

    @Override
    public void onPreviewRatioChange(CameraParamter cameraParamter, Ratio ratio) {
        mCameraParamter = cameraParamter;
        mCamera.setParameters(mCameraParamter.getParameters());
        matchSurfaceView(ratio);
    }

    public void matchSurfaceView(Ratio ratio) {
        int screenWidth = App.getApp().getScreenWidth();
        int screenHeight = App.getApp().getScreenHeight();
        int viewHeight = 0;
        switch (ratio) {
            case R_4x3:
                viewHeight = (int) ((screenWidth * 1.0f) / 3 * 4);
                break;
            case R_16x9:
                viewHeight = (int) ((screenWidth * 1.0f) / 9 * 16);
                break;
        }
        int marginTop = (screenHeight - viewHeight) / 2;
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(screenWidth, viewHeight);
        layoutParams.topMargin = marginTop;
        surfaceView.setLayoutParams(layoutParams);
    }

    @Override
    public void onPictureRatioChange(CameraParamter cameraParamter, Ratio ratio) {
        mCameraParamter = cameraParamter;
        mCamera.setParameters(mCameraParamter.getParameters());
    }

    @Override
    public void onPictureQualityChange(CameraParamter cameraParamter, Quality quality) {
        mCameraParamter = cameraParamter;
        mCamera.setParameters(mCameraParamter.getParameters());
    }

    @Override
    public void onColorEffectChange(CameraParamter cameraParamter, ColorEffect colorEffect) {
        mCameraParamter = cameraParamter;
        mCamera.setParameters(mCameraParamter.getParameters());
    }

    @Override
    public void onSceneModeChange(CameraParamter cameraParamter, SceneMode sceneMode) {
        mCameraParamter = cameraParamter;
        mCamera.setParameters(mCameraParamter.getParameters());
    }

    @Override
    public void onWhiteBalance(CameraParamter cameraParamter, WhiteBalance whiteBalance) {
        mCameraParamter = cameraParamter;
        mCamera.setParameters(mCameraParamter.getParameters());
    }

    @Override
    public void onAntiBindingChange(CameraParamter cameraParamter, String antiBinding) {
        mCameraParamter = cameraParamter;
        mCamera.setParameters(mCameraParamter.getParameters());
    }

    @Override
    public void onVideoQualityChange(CameraParamter cameraParamter, Quality quality) {
        mCameraParamter = cameraParamter;
        mCamera.setParameters(mCameraParamter.getParameters());
    }

最后

如果觉得好的话,请给该项目start,谢谢!!

这个只是第一弹,Android 的 Camera参数还有好多,通过调用paramter.fattern( ),方法可以获得相机支持的参数设置,结果为一个超长字符串

拼接格式为 key=value;key=value=key=value,

当value有多个的时候中间用 , 分割

附上调用处理之后的结果, 部分参数注明了意思,方便查阅



zoom=0
zoom-supported=true
zoom-ratios=100,114,132,151,174,200,229,263,303,348,400
smooth-zoom-supported=true
max-zoom=10


------------------------------------------------------------------------------------


磨皮等级设置,最高为4级
fb-smooth-level=0
fb-smooth-level-min=-4
fb-smooth-level-max=4


------------------------------------------------------------------------------------


硬件支持的最多可以检测人脸张数 15张
max-num-detected-faces-hw=15
软件检测到的人脸张数,0表示未检测到
max-num-detected-faces-sw=0


------------------------------------------------------------------------------------


拍照模式
cap-mode=normal
cap-mode-values=normal,face_beauty,continuousshot,smileshot,bestshot,evbracketshot,autorama


------------------------------------------------------------------------------------


AF辅助灯(AFAssistLamp)功能:自动对焦辅助灯,负责在光线不足的环境下,为照相机的对焦系统照明被摄物体,使对焦系统能准确对焦AF辅助灯
aflamp-mode=off
aflamp-mode-values=off,on,auto


------------------------------------------------------------------------------------


白平衡参数
auto-whitebalance-lock-supported=true
whitebalance-values=auto,incandescent,fluorescent,warm-fluorescent,daylight,cloudy-daylight,twilight,shade
whitebalance=auto


------------------------------------------------------------------------------------


afeng-max-focus-step=0
afeng-min-focus-step=0


------------------------------------------------------------------------------------


preview-format=yuv420sp
preview-format-values=yuv420sp,yuv420p,yuv420i-yyuvyy-3plane


------------------------------------------------------------------------------------


preview-fps-range=5000,60000
preview-fps-range-values=(5000,60000)


------------------------------------------------------------------------------------


preview-size=640x480
preferred-preview-size-for-video=1920x1080
preview-size-values=176x144,320x240,352x288,480x320,480x368,640x480,720x480,800x480,800x600,864x480,960x540,1280x720,1920x1080


------------------------------------------------------------------------------------


preview-frame-rate=30
preview-frame-rate-values=15,24,30


------------------------------------------------------------------------------------


rotation=0


------------------------------------------------------------------------------------


jpeg-thumbnail-quality=100
jpeg-thumbnail-width=160
jpeg-thumbnail-height=128
jpeg-thumbnail-size-values=0x0,160x128,320x240


------------------------------------------------------------------------------------


感光度,ISO的数值越大,对光的敏感程度越高 , 要说明的是,ISO越高,虽然对微弱光线的敏感程度增加,但同时也要使拍摄的照片的噪声点大大地增加
iso-speed=auto
iso-speed-values=auto,100,200,400,800,1600


------------------------------------------------------------------------------------


flash-mode=off
flash-mode-values=off,on,auto,red-eye,torch


------------------------------------------------------------------------------------


eng-flash-duty-value=-1
eng-flash-duty-min=0
eng-flash-duty-max=1


------------------------------------------------------------------------------------


eng-flash-step-max=0
eng-flash-step-min=0


------------------------------------------------------------------------------------


hue=middle
hue-values=low,middle,high


------------------------------------------------------------------------------------


cshot-indicator=true
cshot-indicator-supported=true


------------------------------------------------------------------------------------


video-stabilization-supported=true
video-stabilization=false


------------------------------------------------------------------------------------


video-snapshot-supported=true
video-size=640x480
video-size-values=176x144,480x320,640x480,864x480,1280x720,1920x1080
video-frame-format=yuv420p


------------------------------------------------------------------------------------


scene-mode=auto
scene-mode-values=auto,portrait,landscape,night,night-portrait,theatre,beach,snow,sunset,steadyphoto,fireworks,sports,party,candlelight,hdr


------------------------------------------------------------------------------------


//当前支持的对比度设置
contrast=middle
contrast-values=low,middle,high


------------------------------------------------------------------------------------


曝光补偿
max-exposure-compensation=3
min-exposure-compensation=-3
曝光补偿步径值
exposure-compensation-step=1.0
exposure-compensation=0
auto-exposure-lock-supported=true


------------------------------------------------------------------------------------


防牛顿环频率设置
antibanding=off
antibanding-values=off,50hz,60hz,auto


------------------------------------------------------------------------------------


eng-focus-fullscan-frame-interval=0
eng-focus-fullscan-frame-interval-max=65535
eng-focus-fullscan-frame-interval-min=0


------------------------------------------------------------------------------------


focus-distances=0.95,1.9,Infinity
max-num-focus-areas=1


------------------------------------------------------------------------------------


focus-mode=auto
focus-mode-values=auto,macro,infinity,continuous-picture,continuous-video,manual,fullscan


------------------------------------------------------------------------------------


vertical-view-angle=49
horizontal-view-angle=61


------------------------------------------------------------------------------------


人脸美化皮肤颜色设置值
fb-skin-color=0
fb-skin-color-max=4
fb-skin-color-min=-4


------------------------------------------------------------------------------------


拍照亮度设置
brightness_value=0
brightness=middle
brightness-values=low,middle,high


------------------------------------------------------------------------------------


饱和度
saturation=middle
saturation-values=low,middle,high


------------------------------------------------------------------------------------


edge=middle
edge-values=low,middle,high


------------------------------------------------------------------------------------


picture-format=jpeg
picture-format-values=jpeg


------------------------------------------------------------------------------------


picture-size=2560x1920
picture-size-values=320x240,640x480,1024x768,1280x720,1280x768,1280x960,1600x1200,2048x1536,2560x1440,2560x1920,3264x2448,3328x1872,2880x1728,3600x2160,4096x3072,4160x3120


------------------------------------------------------------------------------------


eng-shading-table=0
eng-save-shading-table=0


------------------------------------------------------------------------------------


fb-sharp=0
fb-sharp-max=4
fb-sharp-min=-4


------------------------------------------------------------------------------------


滤镜
effect=none
effect-values=none,mono,negative,sepia,aqua,whiteboard,blackboard


------------------------------------------------------------------------------------


零秒快拍模式是否有开启
zsd-mode=off
zsd-mode-values=off,on


------------------------------------------------------------------------------------


jpeg-quality=100


------------------------------------------------------------------------------------


当前拍摄张数
burst-num=1


------------------------------------------------------------------------------------


镜头焦距
focal-length=3.5


------------------------------------------------------------------------------------


当前平台支持的最大测光区域为9块
max-num-metering-areas=9


------------------------------------------------------------------------------------


传感器类型
sensor-type=252


------------------------------------------------------------------------------------


capfname=/sdcard/DCIM/cap00


------------------------------------------------------------------------------------


max-num-ot=1


------------------------------------------------------------------------------------


相机模式设置
mtk-cam-mode=0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值