2015-09-11 17 views
6

Có thể ai đó đã làm sai ... Tôi muốn chụp ảnh mà tôi có màn hình xem trước bằng SurfaceView. Tôi có thể hiển thị bản xem trước ở chế độ xem bề mặt.Android: Camera2 Đối số sai được chuyển đến dịch vụ camera

Đây là mã của tôi để chụp ảnh

if (mCameraSession == null && mCameraDevice == null) return; 

    ImageReader reader = ImageReader.newInstance(mTexturePreviewSize.getWidth(), 
          mTexturePreviewSize.getHeight(), 
          ImageFormat.JPEG, 1); 
    reader.setOnImageAvailableListener(imageAvailableListener, mBackgroundHandler); 

    Surface surface = reader.getSurface(); 
    try { 

     CaptureRequest.Builder requestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); 
     requestBuilder.addTarget(surface); 
     mCameraSession.capture(requestBuilder.build(), sessionCaptureListener, null); 

Dưới đây là thông báo lỗi tôi nhận được.

java.lang.IllegalArgumentException: Bad argument passed to camera service 
     at android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:114) 
     at android.hardware.camera2.utils.CameraBinderDecorator$CameraBinderDecoratorListener.onAfterInvocation(CameraBinderDecorator.java:73) 
     at android.hardware.camera2.utils.Decorator.invoke(Decorator.java:81) 
     at java.lang.reflect.Proxy.invoke(Proxy.java:397) 
     at $Proxy2.submitRequestList(Unknown Source) 
     at android.hardware.camera2.impl.CameraDeviceImpl.submitCaptureRequest(CameraDeviceImpl.java:617) 
     at android.hardware.camera2.impl.CameraDeviceImpl.capture(CameraDeviceImpl.java:503) 
     at android.hardware.camera2.impl.CameraCaptureSessionImpl.capture(CameraCaptureSessionImpl.java:161) 
     at Control.CameraApi21Plus.captureSinglePhoto(CameraApi21Plus.java:171) 
     at com.CameraActivity$2.onClick(CameraActivity.java:108) 

Chụp một chức năng bức ảnh duy nhất:

public void captureSinglePhoto() { 

    if (mCameraSession == null && mCameraDevice == null) return; 

    ImageReader reader = ImageReader.newInstance(mTexturePreviewSize.getWidth(), 
      mTexturePreviewSize.getHeight(), 
      ImageFormat.JPEG, 1); 
    reader.setOnImageAvailableListener(imageAvailableListener, mBackgroundHandler); 

    Surface surface = reader.getSurface(); 
    try { 

     CaptureRequest.Builder requestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); 
     requestBuilder.addTarget(surface); 

     mCameraSession.stopRepeating(); 
     mCameraSession.capture(requestBuilder.build(), sessionCaptureListener, null); 

    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } 
} 

private ImageReader.OnImageAvailableListener imageAvailableListener = new ImageReader.OnImageAvailableListener() 
{ 
    @Override 
    public void onImageAvailable(ImageReader reader) { 
     Image img = reader.acquireLatestImage(); 
    } 
}; 

private CameraCaptureSession.CaptureCallback sessionCaptureListener = new CameraCaptureSession.CaptureCallback() { 
    @Override 
    public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) { 
     //super.onCaptureCompleted(session, request, result); 
    } 
}; 

Trả lời

7

Bạn chỉ có thể chụp một bề mặt được định cấu hình cho phiên, vì vậy bạn nên chuẩn bị bề mặt trước khi phiên được tạo.

Trong tài liệu chính thức:

IllegalArgumentException nếu các chỉ tiêu yêu cầu không có bề mặt hoặc Bề mặt được không được cấu hình như đầu ra cho phiên này; ...

Cũng giống như ở đó, bạn cần phải có bề mặt mImageReader.getSurface() sẵn sàng khi bạn tạo phiên

  mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()), 
       new CameraCaptureSession.StateCallback() { 
        ... 
       }, null); 

mẫu chính thức:

https://github.com/googlesamples/android-Camera2Basic/tree/master/Application/src/main/java/com/example/android/camera2basic

+0

tôi muốn đưa ra một đánh dấu với Diyoda nhưng cái của bạn trực tiếp hơn. Tôi nhìn vào mẫu, có quá nhiều thứ trong đó AF, AE tôi không có ý tưởng làm thế nào nó hoạt động trong máy ảnh. Tôi không biết nhiều về máy ảnh. – LittleFunny

+0

Có, luồng máy ảnh thực sự khá phức tạp. Nếu bạn chỉ muốn có ảnh, bạn nên sử dụng Camera Intent, http://developer.android.com/training/camera/photobasics.html, chúc may mắn –

+0

Và, TBH, nếu bạn hiểu chi tiết bạn sẽ biết rằng Diyoda tuyên bố trên 'bạn đang gọi một phiên khép kín' thực sự không phải là trường hợp, nghĩa là bạn có thể xem bản xem trước của mình. –

1

Trong Camera2 API,

Trích dẫn từ tài liệu của CameraCaptureSession,

Nếu một phiên mới được tạo ra bởi máy ảnh thiết bị, sau đó phiên trước đó bị đóng và liên kết của nó là onClosed cal lback sẽ được gọi. Tất cả các phương pháp phiên sẽ ném một IllegalStateException nếu được gọi khi phiên được đóng.

Vì vậy, như tài liệu ngụ ý, bạn đang gọi một phiên đã đóng. tìm ra điều này. Tôi có thể giúp bạn nhiều hơn một chút để đưa thêm mã.

Và ngoài ra, tôi hy vọng bạn đang bắt chước mã mẫu Camera2 API.Nếu không, tôi khuyên bạn nên xem it.

Các vấn đề liên quan