一、前言

最近有一个需求是修改默认的照片尺寸,这篇文章就总结一下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.Preferenceandroid: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 implementsmSettingView.setEntryValues(getEntryValues());mSettingView.setEnabled(getEntryValues().size() > 1);}
+        }@Override
@@ -245,6 +248,7 @@ public class PictureSize extends SettingBase implementsrefreshViewEntry();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 implementssetEntryValues(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 默认选择拍照尺寸修改及流程分析相关推荐

  1. Android 10.0 Camera2 静音时拍照去掉快门声音

    1.概述 在10.0的系统产品开发中,对于Camera2相机的产品定制化中,发现在Camera2中发现一个问题 当媒体音量静音时,点击拍照还是有拍照声音,产品对这个不满意,所以要修改这个问题,所以针对 ...

  2. Android 9.0 Camera2 静音时拍照去掉快门声音

    1.概述 在9.0的系统产品rom定制化开发中,在原生的camera2的相关功能中,在静音拍照的情况下会听到快门的声音,这个是系统原生camera2的bug,但是在产品定制化的 过程中,显得产品体验不 ...

  3. Android 11.0 设置默认8时区和默认24小时制

    目录 1.概述 2.设置默认8时区和默认24小时制的核心类 3.设置默认8时区和默认24小时制的核

  4. Android 11.0 系统默认授予app安装权限(去掉app首次运行时权限授权弹窗)

    目录 1.概述 2.系统默认授予app安装权限去掉app首次运行时权限授权弹窗功能分析

  5. Android 11.0 锁屏页面时钟显示样式

    一.需求分析 Android 11.0系统默认的锁屏时钟 年月日 显示的样式不符合需求,现在需要定制化.下图是系统默认的时间样式. 目标是改成这样: 二.核心代码路径 frameworks/base/ ...

  6. Android 11.0 Settings源码分析 - 主界面加载

    Android 11.0 Settings源码分析 - 主界面加载 本篇主要记录AndroidR Settings源码主界面加载流程,方便后续工作调试其流程. Settings代码路径: packag ...

  7. Android 11.0 支持exFAT文件系统

    Android 11.0 支持exFAT文件系统 U盘常见文件系统类型有FAT32.NTFS.exFAT, Android默认支持FAT32,  一般也有NTFS类型编译选项, 但是exFAT由于版权 ...

  8. Android 9.0 三方app whatsapp 拍照预览模糊

    之前在进行项目开发时,有碰到 Android 9.0 三方app whatsapp 拍照预览分辨率过低 现象,但是拍照出来的照片是清晰的, 查看log发现priview-size过低导致预览模糊,而p ...

  9. Android 11.0 无源码apk授予QUERY_ALL_PACKAGES权限

    目录 1.概述 2.Android 11.0 无源码apk授予QUERY_ALL_PACKAGES权限的核心类 3.Android 11.0 无源码apk授予QUERY_ALL_

最新文章

  1. ADO.NET的连接模式
  2. 【转载】dirs、pushd、popd指令
  3. Python中类型最佳判断方法
  4. 给wordpress最新文章添加“new”标记
  5. YBTOJ洛谷P1407:稳定婚姻(强连通分量)
  6. mysql启动时报错:Starting MySQL ERROR The server quit without updating PID file
  7. 反应特别慢_孩子反应总是很迟钝?家长多注意一点孩子的兴趣培养
  8. 油漆面积 java_第八屆藍橋杯省賽 JavaA組 第十題 標題:油漆面積
  9. 提高网站打开速度的18点要素和五点建议
  10. python-if判断
  11. stm32是以c语言来编程吗,stm32用什么语言编程
  12. iOS底层:PAGEZERO的作用
  13. Linux:红帽操作系统介绍
  14. java实现康威生命游戏
  15. pdf转jpg的在线与用转换器的转换方法
  16. hive获取数据中位数函数
  17. php手册经常见到,什么是“二进制安全”?
  18. 《响应式Web设计实践》一2.2 字体大小
  19. MySQL - 全局锁、表级锁、行级锁、元数据锁、自增锁、意向锁、共享锁、独占锁、记录锁、间隙锁、临键锁、死锁
  20. android动画制作工具,一款非常好用的动画库Lottie

热门文章

  1. mysql姓名相同成绩不同_MySQL数据库
  2. lopa分析_什么是LOPA分析?
  3. 【车辆计数】基于matlab GUI背景差分法道路行驶多车辆检测【含Matlab源码 1911期】
  4. 今天上班了,周末跟随公司组织的旅游去了四川省南充市阆中市参观了张飞庙了解了一下“张飞身葬阆中,头葬云阳”的故事。...
  5. 数学计算机sci,近十年数学学科中国学者SCI十大发文期刊
  6. 数据结构(C语言)二叉树的链式存储与操作 11月18日
  7. 华为路由器配置命令汇总
  8. 2020少儿编程教育政策大汇总!
  9. 数字手写体识别python实现(全连接神经网络)
  10. surface和华为平板_微软的Surface Duo是手机和平板电脑的完美融合