camera缩放倍数频率修改

【问题操作步骤】打开相机,拍照时,平滑缩放比例不正确,跳跃式的,x1.0 -> x1.3 -> x1.5....

【预期结果】平滑,是0.1,还是0.05看效果,手机上是0.1

先通过抓取log看看有没有什么信息;

经验可知mtk的camera是有日志开关的:

vendor\mediatek\proprietary\packages\apps\Camera2\common\src\com\mediatek\camera\common\debug\LogUtil.java

    /**
     * log tag check and log level check.
     * @param tag the log tag.
     * @param level log level.
     * @return true if log tag and log level is OK.
     */
    public static boolean isLoggable(Tag tag, int level) {
        boolean checkLevelResult = false;
        boolean checkResult = true;
        int overrideLogLevel = getOverrideLevelFromProperty();
        if (overrideLogLevel > -1
                || sPersistLogLevel > -1) {
            // Self-defined log level are:
            // MTKCAM_LOG_LEVEL_ERROR   = 0;
            // MTKCAM_LOG_LEVEL_WARNING = 1;
            // MTKCAM_LOG_LEVEL_INFO    = 2;
            // MTKCAM_LOG_LEVEL_DEBUG   = 3;
            // MTKCAM_LOG_LEVEL_VERBOS  = 4;
            // Only loggable when current log level <= property's level.
            // For example: when property's level is set to 2 by
            // "adb shell setprop vendor.debug.mtkcam.loglevel 2",
            // only ERROR, WARNING, INFO  can loggable.
            checkLevelResult = getLogLevelFromSystemLevel(level) <= overrideLogLevel;
            checkLevelResult = checkLevelResult ||
                    (getLogLevelFromSystemLevel(level) <= sPersistLogLevel);
        }
        shouldLog(tag, level);
        checkResult = checkLevelResult || shouldLog(tag, level) || isDebugOsBuild();
        return checkResult;
    }

将vendor.debug.mtkcam.loglevel属性设置为4方便抓取更多信息;

camera的缩放模块是zoom,找到Zoom.java

vendor\mediatek\proprietary\packages\apps\Camera2\feature\setting\zoom\src\com\mediatek\camera\feature\setting\zoom\Zoom.java

    /**
     * Initialize setting. This will be called when do open camera.
     *
     * @param app the instance of IApp.
     * @param cameraContext the CameraContext.
     * @param settingController the SettingController.
     */
    public void init(IApp app,
                     ICameraContext cameraContext,
                     ISettingManager.SettingController settingController) {
        super.init(app, cameraContext, settingController);
        mTag = new Tag(Zoom.class.getSimpleName() + "-" + settingController.getCameraId());
        mModeHandler = new Handler(Looper.myLooper());
        mZoomGestureImpl.init();
        mZoomViewCtrl.init(app);
        initSettingValue();
        mApp.registerOnOrientationChangeListener(mOrientationListener);
        mAppUi.registerGestureListener(mZoomGestureImpl, IApp.DEFAULT_PRIORITY);
        LogHelper.d(mTag, "[init] zoom: " + this + ", Gesture: " + mZoomGestureImpl);
        // [Add for bit true test] Receive KEYCODE_ZOOM_IN and KEYCODE_ZOOM_OUT @{
        mMainHandler = new MainHandler(mActivity.getMainLooper());
        mApp.registerKeyEventListener(mZoomKeyEventListener, IApp.DEFAULT_PRIORITY);
        // @}
    }

mTag = new Tag(Zoom.class.getSimpleName() + "-" + settingController.getCameraId());

通过mTag抓取关键字log——"Zoom-"

搜索calculateDistanceRatio:

找到打印位置:

        private double calculateDistanceRatio(ScaleGestureDetector scaleGestureDetector) {
            float currentSpan = scaleGestureDetector.getCurrentSpan();
            double distanceRatio = (currentSpan - mPreviousSpan) / mScreenDistance;
            LogHelper.d(mTag, "[calculateDistanceRatio] distanceRatio = " + distanceRatio);
            return distanceRatio;
        }

发现是calculateDistanceRatio方法;并在onScale中调用了该方法;

        @Override
        public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
            //First, if it should not zoom, return false.
            String curValue = getValue();
            if (IZoomConfig.ZOOM_OFF.equals(curValue)) {
                return false;
            }
            if (mZoomConfig != null) {
                double distanceRatio = calculateDistanceRatio(scaleGestureDetector);
                mZoomConfig.onScalePerformed(distanceRatio);
                if (Math.abs(distanceRatio - mLastDistanceRatio) > 0.08) {
                    requestZoom();
                    mLastDistanceRatio = distanceRatio;
                }
            }
            return true;
        }

requestZoom()

    private void requestZoom() {
        if (mModeHandler == null) {
            return;
        }
        mModeHandler.post(new Runnable() {
            @Override
            public void run() {
                mSettingChangeRequester.sendSettingChangeRequest();
            }
        });
    }

看到这里,可以知道requestZoom()方法就是去发送sendSettingChangeRequest()的;这里if语句里面的(Math.abs(distanceRatio - mLastDistanceRatio) > 0.08)很重要,稍后会分析;

搜索mSettingChangeRequester看看这个对象是谁:

    @Override
    public ICaptureRequestConfigure getCaptureRequestConfigure() {
        if (mCaptureRequestConfig == null) {
            mCaptureRequestConfig
                    = new ZoomCaptureRequestConfig(this,mSettingDevice2Requester,mCurrentMode);
            mCaptureRequestConfig.setZoomUpdateListener(mZoomLevelUpdateListener);
            mSettingChangeRequester = mCaptureRequestConfig;
            mZoomConfig = mCaptureRequestConfig;
            LogHelper.d(mTag, "[getCaptureRequestConfigure]mZoomConfig: "
                    + mSettingChangeRequester);
        }
        return (ZoomCaptureRequestConfig) mSettingChangeRequester;
    }

mCaptureRequestConfig对象其实就是ZoomCaptureRequestConfig;

vendor\mediatek\proprietary\packages\apps\Camera2\feature\setting\zoom\src\com\mediatek\camera\feature\setting\zoom\ZoomCaptureRequestConfig.java

再去搜索sendSettingChangeRequest():

    @Override
    public void sendSettingChangeRequest() {
        if (isZoomValid()) {
            LogHelper.d(TAG, "[sendSettingChangeRequest]");
            mSettingDevice2Requester.createAndChangeRepeatingRequest();
        }
    }

isZoomValid()

    private boolean isZoomValid() {
        LogHelper.d(TAG, "[isZoomValid] mCurZoomRatio = " + mCurZoomRatio + ", zoomRatio = "
            + calculateZoomRatio(mDistanceRatio) + ", mLastZoomRatio = " + mLastZoomRatio);
        boolean needZoom = mCurZoomRatio >= ZOOM_UNSUPPORTED_DEFAULT_VALUE
                && mCurZoomRatio <= mMaxZoom
                && calculateZoomRatio(mDistanceRatio) != mLastZoomRatio;
        LogHelper.d(TAG, "[isZoomValid] needZoom = " + needZoom);
        return needZoom;
    }

mSettingDevice2Requester.createAndChangeRepeatingRequest()——如此,调用到的camera的api2的接口函数,看名字可知该方法应该是去create和有changed时repeating请求的方法,这应该就是camera缩放倍率显示效果的函数;

手指缓慢的在camera预览界面进行缩放,抓取log:

2024-06-04 10:19:12.156 2957-2957/com.mediatek.camera D/CamAp_Zoom-0: [onScaleBegin], Gesture: com.mediatek.camera.feature.setting.zoom.Zoom$ZoomGestureImpl@ec3730, mZoomConfig: com.mediatek.camera.feature.setting.zoom.ZoomCaptureRequestConfig@c76ff1c
2024-06-04 10:19:12.175 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [isZoomValid] mCurZoomRatio = 1.0, zoomRatio = 1.0, mLastZoomRatio = 1.0
2024-06-04 10:19:12.175 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [isZoomValid] needZoom = false
2024-06-04 10:19:12.190 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [isZoomValid] mCurZoomRatio = 1.0, zoomRatio = 1.0, mLastZoomRatio = 1.0
2024-06-04 10:19:12.190 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [isZoomValid] needZoom = false
2024-06-04 10:19:12.207 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [isZoomValid] mCurZoomRatio = 1.0, zoomRatio = 1.0, mLastZoomRatio = 1.0
2024-06-04 10:19:12.207 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [isZoomValid] needZoom = false
2024-06-04 10:19:12.230 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [isZoomValid] mCurZoomRatio = 1.0, zoomRatio = 1.0, mLastZoomRatio = 1.0
2024-06-04 10:19:12.231 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [isZoomValid] needZoom = false
2024-06-04 10:19:12.241 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [isZoomValid] mCurZoomRatio = 1.0, zoomRatio = 1.0, mLastZoomRatio = 1.0
2024-06-04 10:19:12.241 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [isZoomValid] needZoom = false





2024-06-04 10:19:17.515 2957-2957/com.mediatek.camera D/CamAp_Zoom-0: [onScaleBegin], Gesture: com.mediatek.camera.feature.setting.zoom.Zoom$ZoomGestureImpl@ec3730, mZoomConfig: com.mediatek.camera.feature.setting.zoom.ZoomCaptureRequestConfig@c76ff1c
2024-06-04 10:19:17.549 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [isZoomValid] mCurZoomRatio = 1.0, zoomRatio = 1.2535437, mLastZoomRatio = 1.0
2024-06-04 10:19:17.549 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [isZoomValid] needZoom = true
2024-06-04 10:19:17.550 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [sendSettingChangeRequest]
2024-06-04 10:19:17.556 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [configCaptureRequest] this: com.mediatek.camera.feature.setting.zoom.ZoomCaptureRequestConfig@c76ff1c, mCurZoomRatio = 1.2535437, mDistanceRatio = 0.0845145732164383 mZoomRatioSupported = true mSensorRect = Rect(0, 0 - 3264, 2448)
2024-06-04 10:19:17.682 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [isZoomValid] mCurZoomRatio = 1.2535437, zoomRatio = 1.5060472, mLastZoomRatio = 1.2535437
2024-06-04 10:19:17.682 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [isZoomValid] needZoom = true
2024-06-04 10:19:17.682 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [sendSettingChangeRequest]
2024-06-04 10:19:17.688 2957-3677/com.mediatek.camera D/CamAp_ZoomCaptureRequestConfig: [configCaptureRequest] this: com.mediatek.camera.feature.setting.zoom.ZoomCaptureRequestConfig@c76ff1c, mCurZoomRatio = 1.5060472, mDistanceRatio = 0.16868239641189575 mZoomRatioSupported = true mSensorRect = Rect(0, 0 - 3264, 2448)

发现camera缩放倍率=1.0x的时候,zoomRatio = 1.0;缩放倍率=1.2x的时候,zoomRatio = 1.2535437;

    private float calculateZoomRatio(double distanceRatio) {
        float find = ZOOM_UNSUPPORTED_DEFAULT_VALUE; // if not find, return 1.0f.
        float maxRatio = mMaxZoom;//4.0f
        float minRatio = ZOOM_UNSUPPORTED_DEFAULT_VALUE;//1.0f
        float curRatio = (float) (mBasicZoomRatio + (maxRatio - minRatio) * distanceRatio);
        if (curRatio <= minRatio) {
            find = minRatio;
        } else if (curRatio >= maxRatio) {
            find = maxRatio;
        } else {
            find = curRatio;
        }
        return find;
    }

由该方法可知,在[1,4]这个倍率区间里,mBasicZoomRatio 初始值=1.0f;zoomRatio =1.0 + (4.0 - 1.0) * distanceRatio;

还记得前面说过的if语句判断条件吗?

        @Override
        public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
            //First, if it should not zoom, return false.
            String curValue = getValue();
            if (IZoomConfig.ZOOM_OFF.equals(curValue)) {
                return false;
            }
            if (mZoomConfig != null) {
                double distanceRatio = calculateDistanceRatio(scaleGestureDetector);
                mZoomConfig.onScalePerformed(distanceRatio);
                if (Math.abs(distanceRatio - mLastDistanceRatio) > 0.08) {
                    requestZoom();
                    mLastDistanceRatio = distanceRatio;
                }
            }
            return true;
        }

有一句mZoomConfig.onScalePerformed(distanceRatio)

    @Override
    public void onScalePerformed(double distanceRatio) {
        mDistanceRatio = distanceRatio;
    }

calculateZoomRatio(mDistanceRatio);前面计算公式的distanceRatio就是这个mDistanceRatio,所以distanceRatio = 0.08;所以每次变化0.08的手指缩放间距,camera缩放倍数就会增加0.24的倍数;可以得出,如果想要0.1x的渐变缩放效果,需要改成每0.033的变化就发送请求一次;

                if (Math.abs(distanceRatio - mLastDistanceRatio) > 0.033) {
                    requestZoom();
                    mLastDistanceRatio = distanceRatio;
                }

验证结果:

最后修改diff:

--- a/mediatek/proprietary/packages/apps/Camera2/feature/setting/zoom/src/com/mediatek/camera/feature/setting/zoom/Zoom.java
+++ b/mediatek/proprietary/packages/apps/Camera2/feature/setting/zoom/src/com/mediatek/camera/feature/setting/zoom/Zoom.java
@@ -291,7 +291,7 @@ public class Zoom extends SettingBase {
             if (mZoomConfig != null) {
                 double distanceRatio = calculateDistanceRatio(scaleGestureDetector);
                 mZoomConfig.onScalePerformed(distanceRatio);
-                if (Math.abs(distanceRatio - mLastDistanceRatio) > 0.08) {
+                if (Math.abs(distanceRatio - mLastDistanceRatio) > 0.033) {
                     requestZoom();
                     mLastDistanceRatio = distanceRatio;
                 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值