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

发布于 2025-01-02 15:39:10 字数 233 浏览 0 评论 0原文

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

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

我当前最好的猜测是创建一个 Handler 并从 JPEG 回调(或最后定义的回调返回的那个)向其发送延迟的 Runnable。

Once a call is made to Camera.takePicture(), my preview will stop updating as described in the docs. What's the best way to detect that the image capture process is finished and call startPreview() to make it start updating again?

The call can't be placed in any of the callbacks passed to takePicture, according to the docs, as they should all have returned before I invoke it.

My current best guess is to create a Handler and post a delayed Runnable to it from the JPEG callback (or whichever is the most last defined callback to return).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

关于从前 2025-01-09 15:39:10

由于 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
    }
}

第二种方法是使用匿名函数,例如:

mCamera.takePicture(null, null, new PictureCallback(){
    ...
});

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

Since the PictureCallback is started in a separate thread anyway (it will not lock the UI), you don't need to use an AsyncTask to call the capture.

There are two ways to do what you want to do, the easiest is the following:

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

The second would be using an anonymous function, e.g.:

mCamera.takePicture(null, null, new PictureCallback(){
    ...
});

Both have their uses, depending on your needs.

蓝咒 2025-01-09 15:39:10

您应该从 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();
}

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

}

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

You should start the mCamera.takePicture from within an AsyncTask (or a thread) however AsyncTaks's are the easier option.

A really simple implementation (which of course can be modified) is to:

The method called to take the picture

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

The AsyncTask subclass

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

}

The PictureCallback field

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());
        }
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文