Android setFocusArea и автофокус

Я боролся с этой функцией уже пару дней …

Кажется, что камера игнорирует (?) Области фокусировки, которые я определил. Вот фрагменты кода:

Фокусировка:

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); } } 

Расчет площади фокуса:

 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("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 .

focusAreaSize используемый при расчете, составляет около 210 пикселей (96 дп). Тестирование на HTC One, где Camera.getParameters().getMaxNumFocusAreas()1 .

Режим начальной фокусировки (перед первым нажатием) установлен в положение FOCUS_MODE_CONTINUOUS_PICTURE .

Я здесь что-то не так? Camera.Area с размером или весом прямоугольника Camera.Area не показывают заметного эффекта.

Solutions Collecting From Web of "Android setFocusArea и автофокус"

Моя проблема была намного проще 🙂

Все, что мне нужно было сделать, это отменить ранее называемую автофокусом. В принципе, правильный порядок действий таков:

 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; } 

Помимо настройки:

 parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO); 

Вам необходимо установить:

 parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 

Если вам нужен настоящий «живой» автофокус. Кроме того, будет хорошо проверить доступные фокусы:

 List<String> focusModes = parameters.getSupportedFocusModes(); LLog.d("focusModes=" + focusModes); if (focusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 

На Samsung S6 вы должны установить это с небольшой задержкой (~ 500 мс) после предварительного просмотра камеры.

У меня была эта проблема сегодня: /

И после нескольких часов борьбы я нашел решение!

Это странно, но кажется, что настройка фокус-режима на «макрос» прямо перед настройкой фокуса устраняет проблему;)

 params.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO); params.setFocusAreas(focusAreas); mCamera.setParameters(params); 

У меня Galaxy S3 с Android 4.1.2

Надеюсь, это сработает и для вас 🙂

Используйте FOCUS_MODE_FIXED

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { mCamera = Camera.open(mCameraId); } else { mCamera = Camera.open(); } cameraParams = mCamera.getParameters(); // set the focus mode cameraParams.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED); // set Camera parameters mCamera.setParameters(cameraParams);