What's the best way to call StartPreview() after an image is captured?

后端 未结 2 1667
抹茶落季
抹茶落季 2020-12-25 08:21

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 finishe

相关标签:
2条回答
  • 2020-12-25 08:33

    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());
            }
        }
    };
    
    0 讨论(0)
  • 2020-12-25 08:41

    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.

    0 讨论(0)
提交回复
热议问题