捕获多张照片时出现的问题:应用程序停止响应,相机预览变为绿色,并且没有保存任何图片。

4

我已经成功地在Android中使用相机拍摄了单张照片。但是当我尝试一次性拍摄5张照片时,应用程序会停止响应,相机预览变成绿色,并且没有图片被保存。在堆栈跟踪中我看到的部分信息如下:

03-17 14:19:54.804: INFO/QualcommCameraHardware(19268): deinitPreview E 03-17 14:19:54.804: INFO/QualcommCameraHardware(19268): deinitPreview X 03-17 14:19:54.804: DEBUG/QualcommCameraHardware(19268): frame_thread X 03-17 14:19:54.834: DEBUG/QualcommCameraHardware(19268): snapshot_thread E 03-17 14:19:54.854: DEBUG/CameraService(19268): takePicture (pid 20509) 03-17 14:19:54.884: WARN/AudioFlinger(19268): write blocked for 85 msecs 03-17 14:19:55.154: DEBUG/CameraService(19268): postShutter 03-17 14:19:55.284: DEBUG/CameraService(19268): postRaw 03-17 14:19:55.314: DEBUG/QualcommCameraHardware(19268): snapshot_thread X 03-17 14:19:55.344: DEBUG/QualcommCameraHardware(19268): snapshot_thread E 03-17 14:19:55.364: DEBUG/CameraService(19268): takePicture (pid 20509) 03-17 14:19:55.984: DEBUG/CameraService(19268): postShutter 03-17 14:19:56.064: DEBUG/CameraService(19268): postRaw 03-17 14:19:56.074: ERROR/QualcommCameraHardware(19268): native_jpeg_encode: jpeg_encoder_encode failed. 03-17 14:19:56.074: ERROR/QualcommCameraHardware(19268): jpeg encoding failed 03-17 14:19:56.084: DEBUG/QualcommCameraHardware(19268): snapshot_thread X 03-17 14:19:56.154: INFO/DEBUG(19267): * ** * ** * ** * 03-17 14:19:56.164: INFO/DEBUG(19267): Build fingerprint: 'google_ion/google_ion/sapphire/sapphire:1.6/DRC83/14721:user/adp,test-keys' 03-17 14:19:56.164: INFO/DEBUG(19267): pid: 19268, tid: 20813 >>> /system/bin/mediaserver ... ... ... 14:19:59.894: INFO/ServiceManager(46): service 'media.camera' died 03-17 14:19:59.894: WARN/Camera(20509): Camera server died! 03-17 14:19:59.894: WARN/Camera(20509): ICamera died 03-17 14:19:59.894: ERROR/Camera(20509): Error 100 03-17 14:19:59.915: WARN/AudioSystem(71): AudioFlinger server died! 03-17 14:20:00.014: INFO/Process(71): Sending signal. PID: 18636 SIG: 3 03-17 14:20:00.054: INFO/dalvikvm(18636): threadid=7: reacting to signal 3

我正在使用循环调用takePicture方法来拍摄多张照片;

for(int m = 0 ; m < 6; m++) {

    mPrimCamera.takePicture(null, mPictureCallbackMet, mPictureCallbackMet);
}

我正在使用运行Android 1.6的HTC Magic,尝试拍摄多张照片。我认为,我使用的方法不正确。使用Android Camera API拍摄多张照片的正确方法是什么?


3个回答

10
我不确定Android API是否支持连拍模式。但有一点很明确,你不能像那样在循环中直接调用takePicture(),那只是滥用API。
你可以在onPictureTaken()中考虑拍下一张照片。(显然,你需要跟踪已拍摄的照片数量等信息...)
此外,请像文档所说,不要假设它能在每个设备上都运行。
我在2011年写了以上答案,自那时起,相机已经发生了变化。
编辑:现在Camera2支持连拍模式:https://developer.android.com/reference/android/hardware/camera2/package-summary.html 请查看https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession.html

3

只有在回调方法Camera.PictureCallback.onPictureTaken被调用并且相机预览被重新启动后,才可以拍摄下一张照片。

private void takePhoto() {
    if (!(cameraPreview.isRunning())) {
        Log.i(LOG_TAG, "Camera is not ready. Skip frame");
        return;
    }

    camera.takePicture(null, null, this);
    cameraPreview.onPictureTook();
}

public void onPictureTaken(byte[] data, Camera camera) {
    // save photo
    cameraPreview.start();
}


public class CameraPreview extends SurfaceView {

    private boolean previewRunning = false;

    /**
     * Should be called after calling camera.takePicture
     */
    public void onPictureTook() {
        previewRunning = false;
    }

    public boolean isRunning() {
        return previewRunning;
    }

    public void start() {
        try {
            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();
            previewRunning = true;
        } catch (Exception ignored) {
            Log.e(LOG_TAG, "Error starting camera preview", ignored);
        }
    }
}

1

我没有找到任何关于这个的API支持。而且从循环中重复调用takePicture方法也不起作用。所以,我想到了一个解决办法。代码仍然在循环中,但现在我使用了线程;

private class CaptureThread extends Thread {

        @Override
        public void run() {

            int count = 0;

            while(count < mNo) {
                mFileName = mLocation + "/pic" + count + ".jpg";

                mCamera.takePicture(null, mPictureCallback, mPictureCallback);

                count++;

                try {
                    Thread.sleep(3000);
                } catch (InterruptedException exception) {
                    exception.printStackTrace();
                }
            }
        }
}

2
在这里使用Thread.sleep是一个不好的主意。考虑使用PictureCallback。 - Alex
这可能是一篇旧帖子,但我必须为其他初学者发表评论,因为事件存在的原因是为了避免遇到硬件问题。在具有快门的手机相机上,3秒可能不足够。Thread.sleep 是非常糟糕的做法,当你的代码有问题时,我不认为将自己的答案标记为正确是好的做法。 - Wancieho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接