質問

I'm developing an image recognition app and would like the camera to focus automatically all the time. The folks at ZXing have solved this problem by calling autofocus() every few seconds, but on some cameras this doesn't focus smoothly, but zips to one end and refocuses. On my Alcatel 995, gingerbread 2.3.3 API level 10 phone, it actually makes an alarming click every time this happens.

This phone doesn't support FOCUS_MODE_CONTINUOUS_PICTURE. I tried using FOCUS_MODE_CONTINUOUS_VIDEO, which is supported, and it didn't work. I wrote a test app that captured every preview frame of the camera normally with a callback, but it didn't focus. I added a video recorder feature to the app, and when video is being recorded, the camera does autofocus all the time. But video recording takes away the ability to get a callback on each frame, I think. It's been discussed at https://stackoverflow.com/questions/9477042/extract-video-frames-while-recording-the-video-on-android?rq=1 and How to show real time filtered camera preview while recording videos?

Here is some of that test code:

public void surfaceCreated(SurfaceHolder holder) {
    mCamera = Camera.open();
    try {
        Camera.Parameters parameters = mCamera.getParameters();
        mCamera.setDisplayOrientation(90); // just get it right for testing
        mCamera.setParameters(parameters);
        mCamera.setPreviewDisplay(holder);
        mCamera.setPreviewCallback(new PreviewCallback() {
            public void onPreviewFrame(byte[] data, Camera arg1) {
                Log.d(TAG, String.format("Frame %d", mFrameNumber++)); // see the frames in the logcat
            }
        });
    } catch (IOException exception) {
        mCamera.release();
        mCamera = null;
        Log.d(TAG, "exception setting parameters");
    }
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
    Camera.Parameters parameters = mCamera.getParameters();
    List<Size> previewSizes = parameters.getSupportedPreviewSizes();
    Size previewSize = getOptimalPreviewSize(previewSizes, w, h);
    parameters.setPreviewSize(previewSize.width, previewSize.height);
    parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); 
    mCamera.setParameters(parameters);
    mCamera.startPreview();
    if (mRecordingVideo)
        startVideo(mCamera, holder);
}

// derived from http://developer.android.com/guide/topics/media/camera.html#capture-video
private void startVideo(Camera camera, SurfaceHolder holder) {
    camera.stopPreview(); // not specified in documentation but seems to be needed
    camera.unlock();
    mMediaRecorder = new MediaRecorder();
    mMediaRecorder.setCamera(camera);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // No audio is recorded
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
    mMediaRecorder.setOutputFile("/dev/null");
    try {
        mMediaRecorder.setPreviewDisplay(holder.getSurface());
        mMediaRecorder.prepare();
    } catch (IOException e) {
        camera.release();
        Log.d(TAG, "startVideo: Failed.");
        e.printStackTrace();
    }
    mMediaRecorder.start();
}

If I set mRecordingVideo in the above code to start the video recorder, I gain autofocus but lose the per-preview-frame callbacks.

The Camera.Parameters class definition says that FOCUS_MODE_CONTINUOUS_VIDEO is "intended for video recording" but doesn't make plain that it doesn't work otherwise.

  1. Is there anything else I can do to persuade continuous autofocus to work in a gingerbread phone without recording video? Have I missed something out?
  2. Is this phone-specific? Do other phones continuous autofocus in this mode without recording video? I posted the source of a complete test app to Github if anyone would like to try it on their phone.
役に立ちましたか?

解決

Someone kindly helped me out by testing this on another phone on another continent. Thanks very much, Colin!

  1. It appears that the code above is correct and should cause the camera to focus properly.

  2. This behaviour is phone-specific. The Alcatel 995 running 2.3.6 definitely does not focus in this mode without the video recorder running. A Samsung Galaxy Nexus (not sure which OS) running the same code does focus without the video recorder running.

他のヒント

try "setRecordingHint(true)" to the camera parameters

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top