当前位置: 首页 > 知识库问答 >
问题:

使用Camera2拍摄第二张照片时,setPreviewTexture失败

竺辉
2023-03-14

我试图在没有预览的情况下配置相机兼容性,但在拍摄第二张照片后,应用程序异常崩溃:

2018-12-27 14:36:20.392 123 89-12977/com.example.android.braillefeedere/requestThread-0:捕获调用期间收到设备异常:java.io.ioException:setPreviewTexture在Android.hardware.camera2.legacy.requestThreadManager.dojpegcaptureprepare(requestThreadManager.java:298)在Android.hardware.camera2.legacy.requestThreadManager.-wrap1(未知来源:0)在在Android.os.handler.dispatchMessage(handler.java:101)在Android.os.looper.loop(looper.java:164)在Android.os.handlerThread.run(handlerThread.java:65)

我有这样的代码:

我的目标是28 SDK版本。我想这个问题可能与线程有关,所以我试图在main中初始化线程,但没有成功。

public class CameraService {

// Size of taken photo
private static final int IMAGE_WIDTH = 1280;
private static final int IMAGE_HEIGHT = 960;

private CameraDevice mCameraDevice;
private CameraCaptureSession mCameraCaptureSession;

private HandlerThread backgroundThread;
private Handler backgroundHandler;

private ImageReader mImageReader;

private CameraService() {
}

private static class InstanceHolder {
    private static CameraService sCameraService = new CameraService();
}

public static CameraService getInstance() {
    return InstanceHolder.sCameraService;
}

public void initializeCamera(Context context,
                             ImageReader.OnImageAvailableListener onImageAvailableListener) {

    CameraManager cameraManager = (CameraManager) context.getSystemService(CAMERA_SERVICE);
    String[] camIds = {};
    try {
        camIds = cameraManager.getCameraIdList();
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
    if( camIds.length < 1) {
        Log.e("CameraService", "Camera not available.");
        return;
    }

    startBackgroundThread();

    mImageReader = ImageReader.newInstance(IMAGE_WIDTH, IMAGE_HEIGHT, ImageFormat.JPEG, 2);
    mImageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundHandler);

    try {
        cameraManager.openCamera(camIds[0], mStateCallback, backgroundHandler);
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

private void startBackgroundThread() {
    backgroundThread = new HandlerThread("CameraBackground");
    backgroundThread.start();
    backgroundHandler = new Handler(backgroundThread.getLooper());
}

private void stopBackgroundThread() {
    backgroundThread.quitSafely();
    try {
        backgroundThread.join();
        backgroundThread = null;
        backgroundHandler = null;
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
    @Override
    public void onOpened(@NonNull CameraDevice cameraDevice) {
        mCameraDevice = cameraDevice;
    }

    @Override
    public void onDisconnected(@NonNull CameraDevice cameraDevice) {
        cameraDevice.close();
        mCameraDevice = null;
    }

    @Override
    public void onError(@NonNull CameraDevice cameraDevice, int i) {
        cameraDevice.close();
        mCameraDevice = null;
    }

    @Override
    public void onClosed(@NonNull CameraDevice camera) {
        mCameraDevice = null;
    }
};

public void takePicture() {
    Log.d("CameraService", "takePicture()");
    if( mCameraDevice == null) {
        Log.d("CameraService", "Cannot take picture. Camera device is null.");
        return;
    }
    try {
        mCameraDevice.createCaptureSession(Collections.singletonList(mImageReader.getSurface()),
                new CameraCaptureSession.StateCallback() {
                    @Override
                    public void onConfigured(CameraCaptureSession cameraCaptureSession) {
                        if( mCameraDevice == null) {
                            Log.e("mStateCallback", " mStateCallbackCaptureSession configured");
                            return;
                        }
                        Log.d("CameraService", "imageCapture()");
                        mCameraCaptureSession = cameraCaptureSession;
                        imageCapture();
                    }

                    @Override
                    public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
                        Log.e("mStateCallback", "Configure failed");
                    }
                }, null);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

private void imageCapture() {
    Log.d("CameraService", "imageCapture()");
    try {
        final CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
        builder.addTarget(mImageReader.getSurface());
        builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
        mCameraCaptureSession.stopRepeating();
        mCameraCaptureSession.capture(builder.build(), mCaptureCallback, null);
    } catch (CameraAccessException e) {
        Log.e("imagecapture()", "KOKOTKO");
        e.printStackTrace();
    }
}

private final CameraCaptureSession.CaptureCallback mCaptureCallback =
        new CameraCaptureSession.CaptureCallback() {
            @Override
            public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber) {
                super.onCaptureStarted(session, request, timestamp, frameNumber);
            }

            @Override
            public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
                super.onCaptureProgressed(session, request, partialResult);
            }

            @Override
            public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                if( session != null) {
                     session.close();
                }
            }
};

public void shutdown() {
    Log.d("CameraService", "shutdown()");
    if( mCameraDevice != null) {
        mCameraDevice.close();
    }
    if( mCameraCaptureSession != null) {
        mCameraCaptureSession.close();
    }
    stopBackgroundThread();
}
}

谢谢

共有1个答案

陆飞鸿
2023-03-14

我有相同的isuue与相机2 Api在第二次捕捉图像。这个问题是您在获取字节后没有关闭图像读取器侦听器中的imageimage.close

我希望这能帮上忙

 类似资料:
  • 可使用前端相机或背面相机拍摄照片。 A ) (显示模式) 轻触图标可切换为显示模式。 B ) (位置数据)/(切换相机)/(切换图像大小) 启用位置数据的使用设定即可显示(位置数据)。轻触图标可使用Wi-Fi、GPS*、手机基地台*的信息取得位置数据。取得后会显示(已取得位置数据),拍摄照片时会同时记录位置数据。 * 仅限3G/Wi-Fi机种 C ) (快门) 轻触图标可拍摄照片。 D ) 已拍摄

  • 我需要捕捉多张照片使用Camera2 API后,特定的间隔,如5秒。我需要在没有预演的情况下做。我可以捕获一张单张照片没有预览,但我需要知道如何捕获多张照片?一旦相机打开,我不想一次又一次地设置所有的参数,我只想在特定的间隔后捕捉照片,一旦所有的照片都捕捉到了,然后我会关闭相机。 也只是第一次被捕获的图像。第二次调用takepciture()方法时,什么也没有发生。 下面是我的代码。

  • 问题内容: 我需要在活动中获得并显示照片库中最近拍摄的3张照片,而无需任何点击。 完成此步骤后,滚动时,我应该以3 x 3的方式拍摄其他照片。 您知道快速执行此操作的正确方法吗?谢谢。 问题答案: 这是使用适用于iOS 8+设备的框架的解决方案:

  • 问题内容: 我想在我的应用中以真实的黑白照片。我也在该网站上搜索了解决方案,但是我总是找到将照片放成灰度的解决方案(例如在本主题中),但这不是我想要的… 我还发现了一个提出这一建议的主题: 但是图像质量太差了… 请问有人有主意吗? 谢谢 问题答案: 如果您希望图像为1位黑白,则可以使用简单的(慢速)阈值算法 但是,根据看起来不太好的东西,要获得更好的结果,您需要使用抖动算法,请参阅算法概述 -这是

  • 在我从相机中拍摄了照片之后,在onActivityResult(int requestCode,int resultCode,Intent data)方法中调用。在本例中,我得到了一个NPE,因为数据是空的。 编辑

  • Take a snapshot and save on the Wifi Block.