捕获图像后调用StartPreview()的最佳方法是什么?

Cap*_*mmo 12 camera android

一旦调用Camera.takePicture(),我的预览将停止更新,如文档中所述.检测图像捕获过程的最佳方法是什么,并调用startPreview()使其再次开始更新?

根据文档,调用不能放在传递给takePicture的任何回调中,因为它们应该在我调用之前返回.

我目前最好的猜测是创建一个Handler并从JPEG回调中发布一个延迟的Runnable(或者是最后一个定义的回调函数).

wbl*_*hko 12

由于PictureCallback无论如何都是在一个单独的线程中启动的(它不会锁定UI),因此您不需要使用AsyncTask来调用捕获.

有两种方法可以做你想做的事,最简单的方法如下:

mCamera.startPreview(); //preview has to be started before you can take a picture
mCamera.takePicture(null, null, mPictureCallback); //take a picture

private PictureCallback mPictureCallback = new PictureCallback() {
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        camera.startPreview(); //once your camera has successfully finished
                               //its capture it's safe to restart the preview
        ... //anything else you want to do to process that image
    }
}
Run Code Online (Sandbox Code Playgroud)

第二个是使用匿名函数,例如:

mCamera.takePicture(null, null, new PictureCallback(){
    ...
});
Run Code Online (Sandbox Code Playgroud)

两者都有其用途,具体取决于您的需求.


小智 6

您应该从AsyncTask(或线程)中启动mCamera.takePicture,但是AsyncTaks是更容易的选择.

一个非常简单的实现(当然可以修改)是:

该方法需要拍照

/**
 * Execute the AsyncTask that will handle the preview of the captured photo.
 */
public void takePicture() {
    TakePictureTask takePictureTask = new TakePictureTask();
    takePictureTask.execute();
}
Run Code Online (Sandbox Code Playgroud)

AsyncTask子类

/**
 * A pretty basic example of an AsyncTask that takes the photo and
 * then sleeps for a defined period of time before finishing. Upon
 * finishing, it will restart the preview - Camera.startPreview().
 */

private class TakePictureTask extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPostExecute(Void result) {
        // This returns the preview back to the live camera feed
        mCamera.startPreview();
    }

    @Override
    protected Void doInBackground(Void... params) {
        mCamera.takePicture(null, null, mPictureCallback);

        // Sleep for however long, you could store this in a variable and
        // have it updated by a menu item which the user selects.
        try {
            Thread.sleep(3000); // 3 second preview
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }

}
Run Code Online (Sandbox Code Playgroud)

PictureCallback字段

private PictureCallback mPictureCallback = new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        File file = null;

        // Check whether the media is mounted with read/write permission.
        if (Environment.MEDIA_MOUNTED.equals(
                Environment.getExternalStorageState())) {
            file = getOutputMediaFile();
        }

        if (file == null) {
            Log.d(TAG, "Error creating media file, check storage persmissions!");
            return;
        }

        try {
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(data);
            fileOutputStream.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }
};
Run Code Online (Sandbox Code Playgroud)