概要
实习期间,需要相机的参数进行调用,通常我们调用的时候就直接通过调用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操作类
这样写的灵感还是来源于前面提起的开源项目,比较巧妙的利用集合封装了相机支持并可以设置的参数信息,这里封装的比也行就不用多说了。
列举其中 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());
}
最后
这个只是第一弹,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