30

Android(より具体的にはGalaxy S4)カメラアプリのように、タップしてフォーカスを実装することになっているカスタムカメラ画面を持つアプリに取り組んでいます。

こちらで概説されている手順を使用してみましたが、目立ったフォーカスは発生していないようです。フォーカス モードは連続画像に設定されています (特定のデバイスのみをサポートしています)。

ユーザーがカメラのプレビューをタップすると、画像の上半分に焦点を合わせる必要があります。このために、コードスニペットを使用します

Parameters parameters = mCamera.getParameters();

if (parameters.getMaxNumFocusAreas() > 0) {

    ArrayList<Area> focusAreas = new ArrayList<Camera.Area>(1);
    focusAreas.add(new Area(new Rect(-1000, -1000, 1000, 0), 750));

    parameters.setFocusAreas(focusAreas);
    mCamera.setParameters(parameters);
}

画像に焦点を合わせるのに時間がかかりすぎるため、オートフォーカスは必要ありません。画像の上半分だけに興味があります。連写モードと一緒にタップしてフォーカスをうまく実装した人はいますか?

4

5 に答える 5

27

最近、この問題にぶつかりました。MatheusJardimB が言ったように、この質問 は大いに役立ちます。

ただし、私の場合は、モードで開始し、ContinuousPictureタップしてフォーカスし、モードを続行できるようにしたいと考えていましたContinuousPicture

onAutoFocusのメソッドを使用して、なんとか動作させることができましたCamera.AutoFocusCallback()。それが最善の方法なのか、最も美しい方法なのかはわかりませんが、うまくいくようです。

コードは次のとおりです。

setOnTouchListener(new View.OnTouchListener() {         
    @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (mCamera != null) {
                Camera camera = mCamera.getCamera();
                camera.cancelAutoFocus();
                Rect focusRect = calculateTapArea(event.getX(), event.getY(), 1f);

                Parameters parameters = camera.getParameters();
                parameters.setFocusMode(Parameters.FOCUS_MODE_MACRO);

                if (parameters.getMaxNumFocusAreas() > 0) {
                    List<Area> mylist = new ArrayList<Area>();
                    mylist.add(new Camera.Area(focusRect, 1000));
                    parameters.setFocusAreas(mylist);
                }

                camera.setParameters(parameters);
                camera.autoFocus(new Camera.AutoFocusCallback() {                   
                    @Override
                    public void onAutoFocus(boolean success, Camera camera) {
                        camera.cancelAutoFocus();
                        Parameters params = camera.getParameters();
                        if (!params.getFocusMode().equals(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
                            params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                            camera.setParameters(params);
                        }
                    }
                });
            }
            return true;
        }
        return false;
    });

フォーカスエリアを次のように変更できます

ArrayList<Area> focusAreas = new ArrayList<Camera.Area>(1);
focusAreas.add(new Area(new Rect(-1000, -1000, 1000, 0), 750));

そしてそれはうまくいくはずです。

アップデート

最近、Samsung S5 を入手し、これをテストしました。うまくいかなかったので、いくつかの変更を加えたところ、現在は機能しています。これは、Galaxy S6 および Galaxy Note4 でも正常にテストされました。

変更されたコードは次のとおりです。

setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (mCamera != null) {
            Camera camera = mCamera.getCamera();
            camera.cancelAutoFocus();
            Rect focusRect = calculateTapArea(event.getX(), event.getY(), 1f);

            Parameters parameters = camera.getParameters();
            if (parameters.getFocusMode().equals(
                    Camera.Parameters.FOCUS_MODE_AUTO) {
                parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
            }

            if (parameters.getMaxNumFocusAreas() > 0) {
                List<Area> mylist = new ArrayList<Area>();
                mylist.add(new Camera.Area(focusRect, 1000));
                parameters.setFocusAreas(mylist);
            }

            try {
                camera.cancelAutoFocus();
                camera.setParameters(parameters);
                camera.startPreview();
                camera.autoFocus(new Camera.AutoFocusCallback() {
                    @Override
                    public void onAutoFocus(boolean success, Camera camera) {
                        if (!camera.getParameters().getFocusMode().equals(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
                            Parameters parameters = camera.getParameters();
                            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                            if (parameters.getMaxNumFocusAreas() > 0) {
                                parameters.setFocusAreas(null);
                            }
                            camera.setParameters(parameters);
                            camera.startPreview();
                        }
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return true;
    }
});
于 2014-05-20T07:59:54.850 に答える
22

これには解決策があります。彼のコードに欠けているいくつかのメソッドの実装を追加しました。

private static  final int FOCUS_AREA_SIZE= 300;

///

mCameraPreview.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                focusOnTouch(event);
            }
            return true;
        }
    });

///

 private void focusOnTouch(MotionEvent event) {
    if (mCamera != null ) {

        Camera.Parameters parameters = mCamera.getParameters();
        if (parameters.getMaxNumMeteringAreas() > 0){
            Log.i(TAG,"fancy !");
            Rect rect = calculateFocusArea(event.getX(), event.getY());

            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
            List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
            meteringAreas.add(new Camera.Area(rect, 800));
            parameters.setFocusAreas(meteringAreas);

            mCamera.setParameters(parameters);
            mCamera.autoFocus(mAutoFocusTakePictureCallback);
        }else {
            mCamera.autoFocus(mAutoFocusTakePictureCallback);
        }
    }
}

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

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

private int clamp(int touchCoordinateInCameraReper, int focusAreaSize) {
    int result;
    if (Math.abs(touchCoordinateInCameraReper)+focusAreaSize/2>1000){
        if (touchCoordinateInCameraReper>0){
            result = 1000 - focusAreaSize/2;
        } else {
            result = -1000 + focusAreaSize/2;
        }
    } else{
         result = touchCoordinateInCameraReper - focusAreaSize/2;
    }
    return result;
}

// このコールバックを実装して、フォーカスをトリガーします。

private Camera.AutoFocusCallback mAutoFocusTakePictureCallback = new Camera.AutoFocusCallback() {
        @Override
        public void onAutoFocus(boolean success, Camera camera) {
            if (success) {
                // do something...
                Log.i("tap_to_focus","success!");
            } else {
                // do something...
                Log.i("tap_to_focus","fail!");
            }
        }
    };
于 2015-02-18T02:52:13.177 に答える
-1

同じ問題があります。これを多くのデバイスと多くの Android バージョンで確認しました。

CONTINUOUS focus-mode では focus-area が機能していないようです。

私の回避策は、focus-mode を AUTO または MACRO に設定し、focus-area を設定することです。

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

Galaxy S3 および S4 のストック カメラ アプリは同じように機能することに注意してください。常時連続モードになっています。画面をタッチすると、オートに切り替わり、フォーカスエリアが設定されます。しかし、しばらくすると連続モードに戻り、フォーカス エリアが画面の中央に戻ります。

これが何らかの形で役立つことを願っています。

于 2013-09-29T00:33:46.833 に答える