简体   繁体   English

如何使Android相机预览保持聚焦?

[英]How to make an android camera preview stay focused?

I am quite new to Android, thus the code is not from me since I use it only to learn. 我对Android还是很陌生,因此代码不是来自我的,因为我仅将其用于学习。
The application I want to make has to show a camera preview. 我要制作的应用程序必须显示摄像机预览。 I have the preview of the camera on the surface, but it's not focused. 我在表面上有相机的预览,但没有聚焦。 As a work-around I made a runnable that calls auto-focus every 750ms. 作为解决方法,我制作了一个可运行的设备,每750ms调用一次自动对焦。

I would like to know how I can make this better since whenever I call auto-focus the preview will blur until it's focused again. 我想知道如何做得更好,因为每当我调用自动对焦时,预览都会模糊直到再次对焦。

Thank you for any help. 感谢您的任何帮助。

import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;

public class Draw extends Activity {
    private SurfaceView preview = null;
    private SurfaceHolder previewHolder = null;
    private Camera camera = null;
    private boolean inPreview = false;
    private boolean cameraConfigured = false;
    private Handler handler = new Handler();;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.draw);

        preview = (SurfaceView) findViewById(R.id.preview);
        previewHolder = preview.getHolder();
        previewHolder.addCallback(surfaceCallback);

        final Runnable r = new Runnable() {
            @Override
            public void run() {
                camera.autoFocus(autoFocusCallback);
                handler.postDelayed(this, 1000);
            }
        };
        handler.postDelayed(r, 750);
    }

    private AutoFocusCallback autoFocusCallback = new AutoFocusCallback() {

        @Override
        public void onAutoFocus(boolean autoFocusSuccess, Camera arg1) {
        }
    };

    @Override
    public void onResume() {
        super.onResume();

        camera = Camera.open();
        startPreview();
    }

    @Override
    public void onPause() {
        if (inPreview) {
            camera.stopPreview();
        }

        camera.release();
        camera = null;
        inPreview = false;

        super.onPause();
    }

    private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) {
        Camera.Size result = null;

        for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
            if (size.width <= width && size.height <= height) {
                if (result == null) {
                    result = size;
                } else {
                    int resultArea = result.width * result.height;
                    int newArea = size.width * size.height;

                    if (newArea > resultArea) {
                        result = size;
                    }
                }
            }
        }
        return (result);
    }

    private void initPreview(int width, int height) {
        if (camera != null && previewHolder.getSurface() != null) {
            try {
                camera.setPreviewDisplay(previewHolder);
            } catch (Throwable t) {
                Log.e("KritzelKunst-surfaceCallback", "Exception in setPreviewDisplay()", t);
                Toast.makeText(Draw.this, t.getMessage(), Toast.LENGTH_LONG).show();
            }

            if (!cameraConfigured) {
                Camera.Parameters parameters = camera.getParameters();
                Camera.Size size = getBestPreviewSize(width, height, parameters);

                if (size != null) {
                    parameters.setPreviewSize(size.width, size.height);
                    camera.setParameters(parameters);
                    cameraConfigured = true;
                }
            }
        }
    }

    private void startPreview() {
        if (cameraConfigured && camera != null) {
            camera.startPreview();
            inPreview = true;
        }
    }

    SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            // no-op -- wait until surfaceChanged()
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            initPreview(width, height);
            startPreview();
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            // no-op
        }
    };
}

Try adding 尝试添加

<uses-feature android:name="android.hardware.camera.autofocus" />

in your manifest. 在你的清单上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM