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)
### Android 11.0 MTK 平板 Camera2 API 横屏拍摄实现 在 Android 11.0 系统下,针对使用 MTK 芯片的平板设备,可以通过调整 `Camera2` 的相关参数以及利用特定的核心类来实现横屏拍摄功能。以下是具体的技术细节: #### 核心类与方法 - **核心类**: - `vendor/mediatek/proprietary/packages/apps/Camera2/host/src/com/mediatek/camera/ui/preview/TextureViewController.java`[^1] 此类负责管理预览纹理视图的方向控制逻辑。 - `vendor/mediatek/proprietary/packages/apps/Camera2/host/src/com/mediatek/camera/CameraActivity.java`[^1] 主要用于处理活动生命周期事件并初始化相机界面。 - **关键函数**: - 在 `PhotoMode.java` 中定义了拍照后的数据回调机制。当用户触发拍照操作时,会调用 `onDataReceived(DataCallbackInfo dataCallbackInfo)` 方法,并进一步执行 `onPostViewCallback(byte[] data)` 函数[^2]。 - 关键在于通过 `BitmapCreator.createBitmapFromYuv()` 创建位图的过程中,动态计算屏幕旋转角度(rotation),从而确保最终保存的照片方向正确。 #### 实现步骤概述 为了完成横屏拍摄的功能需求,需重点关注以下几个方面: 1. **获取屏幕方向** 使用 `getRotation()` 获取当前设备屏幕的旋转状态。此值通常为 0°、90°、180° 或 270°,对应不同的屏幕朝向[^1]。 2. **设置 TextureView 预览方向** 修改 `TextureViewController` 类中的逻辑,使预览流能够根据屏幕方向自动调整其渲染矩阵。例如,在检测到横屏模式时,应将旋转角度设为 90 度或 270 度以匹配实际视觉效果[^1]。 3. **捕获图片时应用旋转补偿** 当用户按下快门按钮后,系统会在后台生成一张临时 YUV 图像缓冲区。此时需要依据前述获得的屏幕方向重新设定目标文件存储时所使用的 rotation 值。如果希望保持一致性的用户体验,则建议统一将该值固定为零(即水平正交位置)。然而考虑到部分机型可能存在特殊定制情况,因此允许开发者灵活配置此项数值范围内的任意合法选项。 4. **优化性能表现** 对于高分辨率视频录制场景而言,频繁切换视角可能会带来额外开销;为此可以考虑引入双缓存策略或者异步线程池技术加以缓解压力,进而提升整体流畅度体验感。 ```java // 设置 TextureView 渲染矩阵示例代码 public void setPreviewOrientation(int displayRotation) { Matrix matrix = new Matrix(); int degrees; switch (displayRotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; default: return; } matrix.postRotate(degrees, previewWidth / 2f, previewHeight / 2f); textureView.setTransform(matrix); // 更新变换矩阵至 UI 组件上 } ``` 以上片段展示了如何基于输入参数 `displayRotation` 动态更新 `TextureView` 上展示的内容方位关系。 --- #### 注意事项 尽管上述方案适用于大多数标准环境下的开发工作流程之中,但在某些极端条件下仍可能出现兼容性问题。比如不同厂商生产的摄像头模组之间存在细微差异可能导致预期之外的结果发生。所以在正式发布前务必进行全面测试验证过程。
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mrsongs的心情杂货铺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值