Android的setFocusArea和自动对焦自动对焦、Android、setFocusArea

由网友(安素若昀)分享简介:我一直在争夺这一功能对于两天来,... I've been battling with this feature for couple of days now...看来,该摄像机是忽略了我定义(?)的重点领域。这里是code片段:It seems, that camera is ignoring(?) focus...

我一直在争夺这一功能对于两天来,...

I've been battling with this feature for couple of days now...

看来,该摄像机是忽略了我定义(?)的重点领域。这里是code片段:

It seems, that camera is ignoring(?) focus areas that I've defined. Here is snippets of the code:

聚焦:

protected void focusOnTouch(MotionEvent event) {
    if (camera != null) {
        Rect rect = calculateFocusArea(event.getX(), event.getY());

        Parameters parameters = camera.getParameters();
        parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
        parameters.setFocusAreas(Lists.newArrayList(new Camera.Area(rect, 500)));

        camera.setParameters(parameters);
        camera.autoFocus(this);
    }
}

重点领域的计算:

Focus area calculation:

private Rect calculateFocusArea(float x, float y) {
    int left = clamp(Float.valueOf((x / getSurfaceView().getWidth()) * 2000 - 1000).intValue(), focusAreaSize);
    int top = clamp(Float.valueOf((y / getSurfaceView().getHeight()) * 2000 - 1000).intValue(), focusAreaSize);

    return new Rect(left, top, left + focusAreaSize, top + focusAreaSize);
}

Camera.AutoFocusCallback#onAutoFocus

Log.d(TAG,的String.Format(自动对焦成功=%s的对焦模式:'%s'的专注于信息:%s             突出重点,             camera.getParameters()。getFocusMode(),             camera.getParameters()getFocusAreas()得到(0).rect.toString()));

Log.d(TAG, String.format("Auto focus success=%s. Focus mode: '%s'. Focused on: %s", focused, camera.getParameters().getFocusMode(), camera.getParameters().getFocusAreas().get(0).rect.toString()));

08-27 11:19:42.240: DEBUG/MyCameraActivity(26268): Auto focus success=true. Focus mode: 'auto'. Focused on: Rect(-109, 643 - -13, 739)
08-27 11:19:55.514: DEBUG/MyCameraActivity(26268): Auto focus success=true. Focus mode: 'auto'. Focused on: Rect(20, 457 - 116, 553)
08-27 11:19:58.037: DEBUG/MyCameraActivity(26268): Auto focus success=true. Focus mode: 'auto'. Focused on: Rect(-159, 536 - -63, 632)
08-27 11:20:00.129: DEBUG/MyCameraActivity(26268): Auto focus success=true. Focus mode: 'auto'. Focused on: Rect(-28, 577 - 68, 673)

在视觉上,它看起来像注重成功的登录区,但它突然失去焦点和重点中心(0,0),或者是利用了更大的一部分 SurfaceView 得到。

Visually it looks like focus succeeds on logged area, but the suddenly it loses focus and focus on center (0, 0), or what takes bigger part of SurfaceView is obtained.

focusAreaSize 在计算中使用的是关于210px(96dp)。 在测试的HTC One其中 Camera.getParameters()。getMaxNumFocusAreas() 1

focusAreaSize used in calculation is about 210px (96dp). Testing on HTC One where Camera.getParameters().getMaxNumFocusAreas() is 1.

(前一次敲击)初始对焦模式设置为 FOCUS_MODE_CONTINUOUS_PICTURE

Initial focus mode (before first tap) is set to FOCUS_MODE_CONTINUOUS_PICTURE.

我是不是做错了什么吗? 摆弄 Camera.Area 矩形大小和重量没有表现出任何明显的影响。

Am I doing something wrong here? Tinkering with Camera.Area rectangle size or weight doesn't show any noticeable effect.

推荐答案

我的问题就简单多了:)

My problem was much simpler :)

我不得不这样做的是取消previously称为自动对焦。基本动作的正确顺序是这样的:

All I had to do is cancel previously called autofocus. Basically the correct order of actions is this:

protected void focusOnTouch(MotionEvent event) {
    if (camera != null) {

        camera.cancelAutoFocus();
        Rect focusRect = calculateTapArea(event.getX(), event.getY(), 1f);
        Rect meteringRect = calculateTapArea(event.getX(), event.getY(), 1.5f);

        Parameters parameters = camera.getParameters();
        parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
        parameters.setFocusAreas(Lists.newArrayList(new Camera.Area(focusRect, 1000)));

        if (meteringAreaSupported) {
            parameters.setMeteringAreas(Lists.newArrayList(new Camera.Area(meteringRect, 1000)));
        }

        camera.setParameters(parameters);
        camera.autoFocus(this);
    }
}

更新

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    ...
    Parameters p = camera.getParameters();
    if (p.getMaxNumMeteringAreas() > 0) {
       this.meteringAreaSupported = true;
    }
    ...
}

/**
 * Convert touch position x:y to {@link Camera.Area} position -1000:-1000 to 1000:1000.
 */
private Rect calculateTapArea(float x, float y, float coefficient) {
    int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();

    int left = clamp((int) x - areaSize / 2, 0, getSurfaceView().getWidth() - areaSize);
    int top = clamp((int) y - areaSize / 2, 0, getSurfaceView().getHeight() - areaSize);

    RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
    matrix.mapRect(rectF);

    return new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF.bottom));
}

private int clamp(int x, int min, int max) {
    if (x > max) {
        return max;
    }
    if (x < min) {
        return min;
    }
    return x;
}
阅读全文

相关推荐

最新文章