如何在Android相机API中调整触摸对焦区域

3

我有一段代码,可以将相机对准屏幕上的触摸位置。左右触摸位置可以正确对焦,但是上下触摸位置无法正常工作。请问有人能帮忙解决这个问题吗?

 // Surface view on touch
 @Override
 public boolean onTouchEvent(MotionEvent event) {
     ((CameraActivity) getContext()).touchFocus(event);
     return true;
 }

public void touchFocus(MotionEvent event) {

    if (event.getAction() != MotionEvent.ACTION_DOWN) {
        return;
    }

    float x = event.getX();
    float y = event.getY();


    Rect touchRect = new Rect(
            (int) (x - 100),
            (int) (y - 100),
            (int) (x + 100),
            (int) (y + 100));

    final Rect targetFocusRect = new Rect(
            touchRect.left * 2000 /mPreview.getWidth()  - 1000,
            ((touchRect.top * 2000) /mPreview.getHeight()) - 1000,
            touchRect.right * 2000 /mPreview.getWidth() - 1000,
            ((touchRect.bottom * 2000) /mPreview.getHeight()) - 1000);        

    final List<Camera.Area> focusList = new ArrayList<Camera.Area>();
    Camera.Area focusArea = new Camera.Area(targetFocusRect, 1000);
    focusList.add(focusArea);

    Camera.Parameters para = mCamera.getParameters();
    para.setFocusAreas(focusList);
    para.setMeteringAreas(focusList);
    try {
        mCamera.setParameters(para);
        mCamera.autoFocus(mAutoFocusTakePictureCallback);
    } catch (Exception e) {
        AppController.log(TAG, "focusOnTouch : " + e.getLocalizedMessage());
    }
}

private Camera.AutoFocusCallback mAutoFocusTakePictureCallback = new Camera.AutoFocusCallback() {
    @Override
    public void onAutoFocus(boolean success, Camera camera) {
        if (success) {
            AppController.log(TAG, "Success");
        } else {
            AppController.log(TAG, "Failed");
        }
    }
};
1个回答

0

我找到了触摸对焦的解决方案,我们需要考虑相机的方向。

 private void setFocusing(int focusWidth, int focusHeight, int x, int y, int width, int height) {       
    if (mMatrix == null) {
        mMatrix = new Matrix();
        mPreview.setMatrix(width, height, cameraOrientation);
    }

    Rect targetFocusRect = new Rect();
    calculateTapArea(focusWidth, focusHeight, 1f, x, y, width, height, targetFocusRect);

    final List<Camera.Area> focusList = new ArrayList<>();
    Camera.Area focusArea = new Camera.Area(targetFocusRect, 1000);
    focusList.add(focusArea);

    Camera.Parameters parameters = mCamera.getParameters();
    if (parameters.getMaxNumFocusAreas() > 0) {
        parameters.setFocusAreas(focusList);
    }

    if (parameters.getMaxNumMeteringAreas() > 0) {
        parameters.setMeteringAreas(focusList);
    }

    try {
        mCamera.setParameters(parameters);
        if (parameters.getMaxNumFocusAreas() > 0) {
            mCamera.autoFocus(autoFocus);
        }
    } catch (Exception e) {
        Log.d(TAG, "focusOnTouch : " + e.getLocalizedMessage());
    }
}

Camera.AutoFocusCallback autoFocus = new Camera.AutoFocusCallback() {
    @Override
    public void onAutoFocus(boolean success, Camera camera) {
        Log.d(TAG, "Focus Status : " + success);
    }
};

private void calculateTapArea(int focusWidth, int focusHeight, float areaMultiple, int x, int y, int previewWidth, int previewHeight, Rect rect) {
    int areaWidth = (int) (focusWidth * areaMultiple);
    int areaHeight = (int) (focusHeight * areaMultiple);
    int left = clamp(x - areaWidth / 2, 0, previewWidth - areaWidth);
    int top = clamp(y - areaHeight / 2, 0, previewHeight - areaHeight);

    RectF rectF = new RectF(left, top, left + areaWidth, top + areaHeight);
    mMatrix.mapRect(rectF);
    rectFToRect(rectF, rect);
}

public static int clamp(int x, int min, int max) {
    if (x > max) return max;
    if (x < min) return min;
    return x;
}

public static void rectFToRect(RectF rectF, Rect rect) {
    rect.left = Math.round(rectF.left);
    rect.top = Math.round(rectF.top);
    rect.right = Math.round(rectF.right);
    rect.bottom = Math.round(rectF.bottom);
}

我尝试使用这个方法。但在我的情况下,targetFocusRect在许多原因上越过了边界。我猜测mMatrix的值是在这个问题之后。你能分享一下你的mMatrix的用法吗?这样我就可以得到一些线索了。 - Mostafa Imran
你能提一下你在传递 "focusWidth, focusHeight, x, y, width, height" 参数时传递了哪些值吗? - Kamalanathan
使用数值(假设为30)作为focusWidth和focusHeight,x、y是触摸点的坐标,width和height是相机预览的宽度和高度。我的问题是有时会得到一个超出限制范围(-1000:1000)的矩形。谢谢。 - Mostafa Imran
什么是 mPreview?它是对象视图吗? - faiyaz meghreji

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接