Android捏缩放相机延迟

时间:2016-11-17 15:27:17

标签: android android-camera pinchzoom

我的应用程序中有一个自定义的SurfacePreview表面视图,我正在尝试通过实现这两种方法来实现Pinch缩放:

@Override
    public boolean onTouchEvent(MotionEvent event) {
        Camera camera = getCamera();
        if (camera == null) {
            return true;
        }

        Camera.Parameters params = camera.getParameters();

        int action = event.getAction();

        if (event.getPointerCount() > 1) {
            if (action == MotionEvent.ACTION_POINTER_DOWN) {
                MCLog.v(TAG, "Single ");
                mDist = getFingerSpacing(event);
                MCLog.w(TAG, "Original distance " + mDist);
            } else if (action == MotionEvent.ACTION_MOVE && params.isZoomSupported()) {
                camera.cancelAutoFocus();
                handleZoom(event, params);
            }
        } else {
            if (action == MotionEvent.ACTION_UP) {

                mFirstTime = false;
                handleFocus(event, params);
            }
        }
        return true;
    }

    private void handleZoom(MotionEvent event, Camera.Parameters params) {


        if(mFirstTime) {
            mDist = getFingerSpacing(event);
            mFirstTime = false;
            return;
        }


        List<Integer> zoomRatios = params.getZoomRatios();
        int maxZoom = params.getMaxZoom();
        int zoom = params.getZoom();

        double spacing = getFingerSpacing(event);

        MCLog.w(TAG, String.format("Old zoom is: %s", zoom));

        //Percentage of displacement
        MCLog.w(TAG, String.format("Original distance is: %s, new displacement is %s", mDist, spacing));
        double percentage =  (mDist + spacing)/mDist;
        if(mDist > spacing)
        {
            percentage *= -1;
        }
        MCLog.w(TAG, String.format("Percentage is: %s", percentage));



        zoom = new Double(zoom  + percentage).intValue();
        MCLog.w(TAG, String.format("New zoom is: %s", zoom));


        if (zoom > maxZoom) {
            zoom = maxZoom;
        }

        if (zoom < 0) {
            zoom = 0;
        }
        mDist = spacing;

        params.setZoom(zoom);
        if (mZoomListener != null) {
            mZoomListener.onZoomChanged(zoomRatios.get(zoom));
        }
        getCamera().setParameters(params);
    }

这似乎有效,但缩放有一些轻微的延迟,越长,我放大图像越多。就像我会停止捏,图像仍会继续放大。

除了this one之外,我无法在相机中找到任何捏缩放的实现,所以这可能是做错了。

1 个答案:

答案 0 :(得分:0)

由于您在抬起手指后看到记录继续,这可能意味着您没有足够快地处理触摸事件队列。

setProperties调用并不是特别快。

因此,您需要以某种方式对速率进行限制,并删除您没有时间处理的触摸事件。有多种选择可以进行各种权衡。

我对输入API不是很熟悉,所以不确定是否有一些参数可以调整以降低调用率 - 除非缩放的变化高于晚餐阈值,否则可能只是不做任何事情,并且然后增加阈值,直到缩放没有滞后?

或者您可以将缩放调用发送到另一个线程以实际调用setParameters,如果该线程已经忙于处理上一个调用,则只需将缩放调用放到该楼层。

或者更好的是,有一个'nextZoom'参数,缩放设置线程在完成其先前的调用后会查看该参数,然后在每次调用时让触摸事件处理程序更新nextZoom。然后,缩放设置线程总是在完成最后一次设置调用后检查值是否已更改,如果是,则再次设置它。

然后你将总是得到最新的缩放级别,他们也不会堆积起来。