Android 11.0 Camera2 默认选择拍照尺寸修改及流程分析
Posted 安时光Mrsongs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 11.0 Camera2 默认选择拍照尺寸修改及流程分析相关的知识,希望对你有一定的参考价值。
一、前言
最近有一个需求是修改默认的照片尺寸,这篇文章就总结一下Camara 选择默认的拍照尺寸的逻辑吧。
二、定位代码
2.1、根据“照片大小” text 可以定位到布局文件 picturesize_preference.xml.
代码路径:
android\\vendor\\mediatek\\proprietary\\packages\\apps\\Camera2\\feature\\setting\\picturesize\\res\\xml\\picturesize_preference.xml`**
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<com.mediatek.camera.common.preference.Preference
android:key="key_picture_size"
android:title="@string/pref_camera_picturesize_title"
android:persistent="false"
android:order="40"/>
</PreferenceScreen>
Java 引用文件为:
代码路径: android\\vendor\\mediatek\\proprietary\\packages\\apps\\Camera2\\feature\\setting\\picturesize\\src\\com\\mediatek\\camera\\feature\\setting\\picturesize\\PictureSizeSettingView.java
三、流程逻辑分析
3.1、PictureSizeSettingView 照片尺寸列表值的初始化
PictureSizeSettingView 的 setEntryValues 是传入照片尺寸列表的,这里是在其他地方调用传入值得。
代码路径: android\\vendor\\mediatek\\proprietary\\packages\\apps\\Camera2\\feature\\setting\\picturesize\\src\\com\\mediatek\\camera\\feature\\setting\\picturesize\\PictureSizeSettingView.java
/**
* Set the picture sizes supported.
*
* @param entryValues The picture sizes supported.
*/
public void setEntryValues(List<String> entryValues) {
mEntryValues = entryValues;
}
3.2、PictureSize.java 设置默认尺寸和可选尺寸
全局搜一下可以发现是在PictureSize.java 中传入EntryValue的
代码路径: vendor/mediatek/proprietary/packages/apps/Camera2/feature/setting/picturesize/src/com/mediatek/camera/feature/setting/picturesize/PictureSize.java
总结一下流程:
1、获取屏幕的尺寸来计算出宽高比作为全屏的宽高比。
2、获取Sensor 传上来的可支持的照片尺寸supportedPictureSize。
3、从supportedPictureSize这里遍历选出可以用的尺寸里面最接近全屏宽高比的尺寸。
4、将全屏宽高比里面尺寸作为默认选中的尺寸。
/**
* Invoked after setting's all values are initialized.
*
* @param supportedPictureSize Picture sizes which is supported in current platform.
*/
public void onValueInitialized(List<String> supportedPictureSize) {
LogHelper.d(TAG, "[onValueInitialized], supportedPictureSize:" + supportedPictureSize);
//1、这里获取屏幕的尺寸来计算出宽高比作为全屏的宽高比。
double fullRatio = PictureSizeHelper.findFullScreenRatio(mActivity);
List<Double> desiredAspectRatios = new ArrayList<>();
desiredAspectRatios.add(fullRatio);
desiredAspectRatios.add(PictureSizeHelper.RATIO_4_3);
PictureSizeHelper.setDesiredAspectRatios(desiredAspectRatios);
PictureSizeHelper.setFilterParameters(DEGRESSIVE_RATIO, MAX_COUNT);
if (sFilterPictureSize) {
supportedPictureSize = PictureSizeHelper.filterSizes(supportedPictureSize);
LogHelper.d(TAG, "[onValueInitialized], after filter, supportedPictureSize = "
+ supportedPictureSize);
}
...
/*
**已省略部分代码......
*/
...
//2、获取Sensor 传上来的可支持的照片尺寸supportedPictureSize。
setSupportedPlatformValues(supportedPictureSize);
setSupportedEntryValues(supportedPictureSize);
setEntryValues(supportedPictureSize);
refreshViewEntry();
String valueInStore = mDataStore.getValue(getKey(), null, getStoreScope());
Log.d("PictureSize 1,","onValueInitialized valueInStore="+valueInStore);
if (valueInStore != null
&& !supportedPictureSize.contains(valueInStore)) {
LogHelper.d(TAG, "[onValueInitialized], value:" + valueInStore
+ " isn't supported in current platform");
valueInStore = null;
mDataStore.setValue(getKey(), null, getStoreScope(), false);
}
if (valueInStore == null) {
// Default picture size is the max full-ratio size.
List<String> entryValues = getEntryValues();
//3、这里遍历选出可以用的尺寸里面最接近全屏宽高比的尺寸。
for (String value : entryValues) {
if (PictureSizeHelper.getStandardAspectRatio(value) == fullRatio) {
valueInStore = value;
break;
}
}
}
// If there is no full screen ratio picture size, use the first value in
// entry values as the default value.
if (valueInStore == null) {
valueInStore = getEntryValues().get(0);
}
Log.d("PictureSize 2,","onValueInitialized valueInStore="+valueInStore);
//4、将全屏宽高比里面尺寸作为默认选中的尺寸。
setValue(valueInStore);
}
四、Any question ?
1、全屏的宽高比如何计算的 ?
2、默认的尺寸如果全屏宽高比有好几个怎么选择 ?
4.1、全屏的宽高比如何计算的
在上面提到获取全屏宽高比的地方是 PictureSizeHelper.findFullScreenRatio
//1、这里获取屏幕的尺寸来计算出宽高比作为全屏的宽高比。
double fullRatio = PictureSizeHelper.findFullScreenRatio(mActivity);
代码路径: android\\vendor\\mediatek\\proprietary\\packages\\apps\\Camera2\\feature\\setting\\picturesize\\src\\com\\mediatek\\camera\\feature\\setting\\picturesize\\PictureSizeHelper.java
在这里可以很清楚的看到计算全屏宽高比的步骤。
1、首选通过Display获取屏幕的尺寸。
2、计算屏幕尺寸的宽高比。
3、根据绝对值函数选取最靠近屏幕宽高比的数值作为全屏宽高比。
/**
* Compute full screen aspect ratio.
*
* @param context The instance of {@link Context}.
* @return The full screen aspect ratio.
*/
public static double findFullScreenRatio(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
//1、首选通过Display获取屏幕的尺寸。
Display display = wm.getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
display.getRealMetrics(dm);
int width = Math.max(dm.widthPixels, dm.heightPixels);
int height = Math.min(dm.widthPixels, dm.heightPixels);
//2、计算屏幕尺寸的宽高比。
double displayRatio = (double) width / (double) height;
Log.d("PictureSizeHelper",",findFullScreenRatio width="+width+",height="+height+",displayRatio="+displayRatio);
double find = RATIO_4_3;
//3、根据绝对值函数选取最靠近屏幕宽高比的数值作为全屏宽高比。
for (int i = 0; i < RATIOS.length; i++) {
double ratio = RATIOS[i];
if (Math.abs(ratio - displayRatio) < Math.abs(find - displayRatio)) {
find = ratio;
}
}
return find;
}
4.2、默认的尺寸如果全屏宽高比有好几个怎么选择。
在PictureSize中的 onValueInitialized方法中不考虑各个MODE功能的情况下,根据先来后到原则,最先匹配上全屏宽高比的尺寸作为默认选中的尺寸。看到这里有点失望,本来以为会比较一下比如16:9里面选择最大的作为默认尺寸。
if (valueInStore == null) {
// Default picture size is the max full-ratio size.
List<String> entryValues = getEntryValues();
for (String value : entryValues) {
if (PictureSizeHelper.getStandardAspectRatio(value) == fullRatio) {
valueInStore = value;
break;
}
}
五、定制将支持照片尺寸里面选择最大的作为默认尺寸。
diff --git a/vendor/mediatek/proprietary/packages/apps/Camera2/feature/setting/picturesize/src/com/mediatek/camera/feature/setting/picturesize/PictureSize.java b/vendor/mediatek/proprietary/packages/apps/Camera2/feature/setting/picturesize/src/com/mediatek/camera/feature/setting/picturesize/PictureSize.java
index f3a3954b727..77247a04614 100755
--- a/vendor/mediatek/proprietary/packages/apps/Camera2/feature/setting/picturesize/src/com/mediatek/camera/feature/setting/picturesize/PictureSize.java
+++ b/vendor/mediatek/proprietary/packages/apps/Camera2/feature/setting/picturesize/src/com/mediatek/camera/feature/setting/picturesize/PictureSize.java
@@ -48,6 +48,8 @@ import com.mediatek.camera.portability.SystemProperties;
import java.util.ArrayList;
import java.util.List;
+import android.util.Log;
+
/**
* Picture size setting item.
@@ -114,6 +116,7 @@ public class PictureSize extends SettingBase implements
mSettingView.setEntryValues(getEntryValues());
mSettingView.setEnabled(getEntryValues().size() > 1);
}
+
}
@Override
@@ -245,6 +248,7 @@ public class PictureSize extends SettingBase implements
refreshViewEntry();
String valueInStore = mDataStore.getValue(getKey(), null, getStoreScope());
+ Log.d("PictureSize 1,","onValueInitialized valueInStore="+valueInStore);
if (valueInStore != null
&& !supportedPictureSize.contains(valueInStore)) {
LogHelper.d(TAG, "[onValueInitialized], value:" + valueInStore
@@ -254,19 +258,23 @@ public class PictureSize extends SettingBase implements
}
if (valueInStore == null) {
// Default picture size is the max full-ratio size.
- List<String> entryValues = getEntryValues();
+ //add begin...
+ /*List<String> entryValues = getEntryValues();
for (String value : entryValues) {
if (PictureSizeHelper.getStandardAspectRatio(value) == fullRatio) {
valueInStore = value;
break;
}
- }
+ }*/
+ valueInStore =PictureSizeHelper.getMaxPictureSize(getEntryValues());
+ //add end..
}
// If there is no full screen ratio picture size, use the first value in
// entry values as the default value.
if (valueInStore == null) {
valueInStore = getEntryValues().get(0);
}
+ Log.d("PictureSize 2,","onValueInitialized valueInStore="+valueInStore);
setValue(valueInStore);
}
@@ -295,6 +303,7 @@ public class PictureSize extends SettingBase implements
setEntryValues(supportedPictureSize);
refreshViewEntry();
setValue(forceChosenPictureSize);
+ Log.d("PictureSize,","onValueInitialized forceChosenPictureSize="+forceChosenPictureSize);
mDataStore.setValue(getKey(), getValue(), getStoreScope(), false);
LogHelper.d(TAG, "[onValueInitialized] -");
}
diff --git a/vendor/mediatek/proprietary/packages/apps/Camera2/feature/setting/picturesize/src/com/mediatek/camera/feature/setting/picturesize/PictureSizeHelper.java b/vendor/mediatek/pro
prietary/packages/apps/Camera2/feature/setting/picturesize/src/com/mediatek/camera/feature/setting/picturesize/PictureSizeHelper.java
index d2f9ec9a33b..06cfe7713b9 100755
--- a/vendor/mediatek/proprietary/packages/apps/Camera2/feature/setting/picturesize/src/com/mediatek/camera/feature/setting/picturesize/PictureSizeHelper.java
+++ b/vendor/mediatek/proprietary/packages/apps/Camera2/feature/setting/picturesize/src/com/mediatek/camera/feature/setting/picturesize/PictureSizeHelper.java
@@ -57,6 +57,7 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import android.util.Log;
/**
* Picture size helper to provide util methods.
@@ -109,7 +110,7 @@ public class PictureSizeHelper {
int width = Math.max(dm.widthPixels, dm.heightPixels);
int height = Math.min(dm.widthPixels, dm.heightPixels);
double displayRatio = (double) width / (double) height;
-
+ Log.d("PictureSizeHelper",",findFullScreenRatio width="+width+",height="+height+",displayRatio="+displayRatio);
double find = RATIO_4_3;
for (int i = 0; i < RATIOS.length; i++) {
double ratio = RATIOS[i];
@@ -279,6 +280,23 @@ public class PictureSizeHelper {
return ratio;
}
+ //add begin.
+ public static String getMaxPictureSize(List<String> supportedEntryValues){
+ int temp=0;
+ int maxSize=0;
+ int maxIndex=0;
+ for (int i=0;i< supportedEntryValues.size();i++) {
+ Size size = valueToSize(supportedEntryValues.get(i));
+ temp = size.width * size.height;
+ if (temp > maxSize) {
+ maxSize = temp;
+ maxIndex = i;
+ }
+ }
+ return supportedEntryValues.get(maxIndex);
+ }
+ //add end.
+
private static List<Size> pickUpToThree(List<Size> sizes) {
if (sDegressiveRatio == 0 || sMaxCount == 0) {
return sizes;
六、结语
Okay,So much for this !
以上是关于Android 11.0 Camera2 默认选择拍照尺寸修改及流程分析的主要内容,如果未能解决你的问题,请参考以下文章
Android 11.0 修复Camera 启用后置摄像头在拍照界面下,白平衡按钮无法点击
Android 11.0 修复Camera 使用闪光灯拍照后,查看图片时详细信息为“未使用闪光灯”状态