2021SC@SDUSC
前言
以手机相机为依托的camera项目不仅需要有基础的拍照功能,并且还需要对拍摄的照⽚进⾏⼀系列处理,包括但不仅限于图⽚抗扭曲,曝光度,聚焦等。具体可以整理为以下功能:1. 相机预览功能
2. 拍照的偏好设置,如闪光灯,聚焦,曝光补偿
3. 相机可随设备旋转,拍摄横屏和竖屏的照⽚
4. 拍照后保存在⼿机的pictures⽂件夹
5. 可以预览拍摄的照⽚
6. 图⽚抗扭曲处理
这篇将继续分析相机的偏好设置。
一、项目环境
android studio版本 4.1.2
sdk版本 Compile SDK version:30
Build Tools Version 30.0.3
gradle版本 6.8.3
二、代码分析
1.动态加载预览分辨率
上次文章已经分析了关于曝光补偿的方法,这里分析动态加载预分辨率的方法。
//动态加载预览分辨率
public static final String KEY_PREF_PREV_SIZE = "preview_size";
private void loadSupportedPreviewSize() {
cameraSizeListToListPreference(mParameters.getSupportedPreviewSizes(), KEY_PREF_PREV_SIZE);
}
private void cameraSizeListToListPreference(List<Camera.Size> list, String key) {
List<String> stringList = new ArrayList<>();
for (Camera.Size size : list) {
String stringSize = size.width + "x" + size.height;
stringList.add(stringSize);
}
stringListToListPreference(stringList, key);
}
KEY_PREF_PREV_SIZE 用于存储预览分辨率的key,在加载预览分辨率中调用了cameraSizeListToListPreference()这个方法,将mParameters.getSupportedPreviewSizes(),和KEY_PREF_PREV_SIZE作为参数传入。在cameraSizeListToListPreference()方法中,实现的是将所给我们提供的相机的参数转变成宽x高的形式,例如1024x512这种形式的字符串再存入到stringList中,此时stringList作为一个字符串型List作为参数传入到stringListToListPreference()里面,在stringListToListPreference()中,stringList转化为字符串类型的数组,并且由getPreferenceScreen.findPreference()获取由key制定的菜单条目,利用setEntries()和setEntryValues()指定了所有用户和代码可见的value,完成了对预览分辨率的加载。
2.动态加载闪光灯和聚焦
public static final String KEY_PREF_FLASH_MODE = "flash_mode";
public static final String KEY_PREF_FOCUS_MODE = "focus_mode";
private void loadSupportedFlashMode() {
stringListToListPreference(mParameters.getSupportedFlashModes(), KEY_PREF_FLASH_MODE);//闪光灯
}
private void loadSupportedFocusMode() {
stringListToListPreference(mParameters.getSupportedFocusModes(), KEY_PREF_FOCUS_MODE);
}
和前面动态加载分辨率和曝光补偿非常相似,在动态加载闪光灯和聚焦的时候,也是利用stringListToListPreference()的方法,在key制定的菜单条目中传入相应的参数的字符串数组。
为了在onCreate()触发时就调用这些load进行动态加载,在onCreate()尾部添加
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
loadSupportedFlashMode();
loadSupportedFocusMode();
loadSupportedExposeCompensation();
// initSummary(getPreferenceScreen());
}
在SettingsFragment类中,开发人员定义了加载动态参数的方法,还添加了加载动态默认值的方法setDefault(),通过调用setDefault()方法可以使相机初始化时拥有默认值,设定的setDefault是在其他参数没有初始默认值时指定默认值,否则不进行操作,所以在该方法中,需要先判断目前有没有默认的值,如果为空则需要指定,否则不进行任何操作直接返回,同时我们本身相机有默认的参数,可以直接把它当作默认值,具体方法如下:
public static void setDefault(SharedPreferences sharedPrefs) {
String valPreviewSize = sharedPrefs.getString(KEY_PREF_PREV_SIZE, null);//读取是否已有默认值
if (valPreviewSize == null) {
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putString(KEY_PREF_PREV_SIZE, getDefaultPreviewSize());
editor.putString(KEY_PREF_PIC_SIZE, getDefaultPictureSize());
editor.putString(KEY_PREF_VIDEO_SIZE, getDefaultVideoSize());
editor.putString(KEY_PREF_FOCUS_MODE, getDefaultFocusMode());
editor.apply();
}
}
其中用到了SharedPreferences类的sharedPredfs实例,这里分析一下SharedPreferences类。
SharedPreferences:一个轻量级的存储类,特别适合用于保存软件配置参数。(是用xml文件存放数据,文件存放在/data/data//shared_prefs目录下)
- SharedPreferences类
- 保存数据的步骤:
1.使用Activity类的getSharedPreferences()获得SharedPreferences对象;
2.使用SharedPreferences接口的edit获得SharedPreferences.Editor对象;
3.通过SharedPreferences.Editor接口的putXXX方法保存key-value对;
4.通过过SharedPreferences.Editor接口的commit方法保存key-value对。 - 读取数据的步骤:
1.使用Activity类的getSharedPreferences方法获得SharedPreferences对象;
2.通过SharedPreferences对象的getXXX方法获取数据;
- 保存数据的步骤:
注意最后需要apply()保存更改。
3.init()方法
用户希望相机APP每次启动时都能自动加载好之前偏好设置
在SettingsFragment中创建init()方法,负责设置相机
public static void init(SharedPreferences sharedPref) {
setFlashMode(sharedPref.getString(KEY_PREF_FLASH_MODE, ""));
setFocusMode(sharedPref.getString(KEY_PREF_FOCUS_MODE, ""));
setExposComp(sharedPref.getString(KEY_PREF_EXPOS_COMP, ""));
mCamera.stopPreview();
mCamera.setParameters(mParameters);
mCamera.startPreview();
}
三、总结
继续分析了参数的设置以及一些初始化方法,其中有许多set、get方法,很大的一部分篇章体现了封装的思想,除此之外,还有诸如init()的方法,将许多方法包装在里面,初始化调用这些方法,进一步简化了代码。