2016-07-12 30 views
1

So instanziiere ich den ImageReader.Android Camera2, Ich erwerbe YUV Bild von ImageReader. U- und V-Puffer haben nur eine Zeilen- (Schritt-) Daten, der Rest ist Null.

Size[] sizes = configs.getOutputSizes(ImageFormat.YUV_420_888); 
     mImageReader = ImageReader.newInstance(width, height, ImageFormat.YUV_420_888, 2); 

     mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null); 

     Surface rgbCaptureSurface = mImageReader.getSurface(); 
     List<Surface> surfaces = new ArrayList<Surface>(); 
     surfaces.add(rgbCaptureSurface); 

     //surfaces.add(surface); 

     mPreviewRequestBuilder 
       = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 
     //mPreviewRequestBuilder.addTarget(surface); 

     mPreviewRequestBuilder.addTarget(rgbCaptureSurface); 

     mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() { 


      @Override 
      public void onConfigured(CameraCaptureSession cameraCaptureSession) { 
       // The camera is already closed 
       if (null == mCameraDevice) { 
        return; 
       } 

       // When the session is ready, we start displaying the preview. 
       mCaptureSession = cameraCaptureSession; 
       try { 
        // Auto focus should be continuous for camera preview. 
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, 
          CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO); 

        // Flash is automatically enabled when necessary. 
        //setAutoFlash(mPreviewRequestBuilder); 

        // Finally, we start displaying the camera preview. 
        mPreviewRequest = mPreviewRequestBuilder.build(); 
        mCaptureSession.setRepeatingRequest(mPreviewRequest, 
          mCaptureCallback, null); 
       } catch (CameraAccessException e) { 
        e.printStackTrace(); 
       } 
      } 

Lesung wird folgendermaßen gemacht:

public void onImageAvailable(ImageReader reader) { 
     Image image; 
     while (true) { 
      image = reader.acquireLatestImage(); 

      if (image == null) return; 


      Image.Plane Y = image.getPlanes()[0]; 
      Image.Plane U = image.getPlanes()[1]; 
      Image.Plane V = image.getPlanes()[2]; 

      int Yb = Y.getBuffer().remaining(); 
      int Ub = U.getBuffer().remaining(); 
      int Vb = V.getBuffer().remaining(); 

      byte[] data = new byte[Yb + Ub + Vb]; 


      Y.getBuffer().get(data, 0, Yb); 
      U.getBuffer().get(data, Yb, Ub); 
      V.getBuffer().get(data, Yb + Ub, Vb); 

ich mehrere verschiedene ImageFormats versucht. Ich teste auf LG G3, API 21 und das Problem tritt auf. Auf Nexus 4 habe ich nicht das Problem, API 22.

Antwort

0

Ihre Beobachtung ist richtig. API 21 unterstützt Camera2 nicht ordnungsgemäß. Dies wurde von mehreren Personen unabhängig hier auf SO gefunden, siehe z.B. Camera2 API21 not working

So ist es sinnvoll, Camera2 nicht vor API22 zu verwenden. Es ist nicht nachvollziehbar, warum die Dokumentation in der Zwischenzeit nicht geändert wurde.

Persönlich bin ich weiterhin Camera2 Studien durchführen, aber ich bin immer noch ungern Camera2 in meiner App jetzt zu verwenden. Ich möchte es zunächst auf vielen Geräten testen und für die nahe Zukunft erwarte ich nicht, dass "Camera1" von neuen Geräten nicht mehr unterstützt wird.

+0

Haben Sie eine Beobachtung, wie Sie die Ausrichtung des Bildes korrigieren können? Ich habe dieses Problem auch: http://stackoverflow.com/questions/28845245/image-data-from-android-camera2-api-flipped-squished-on-galaxy-s5 –

+0

Ich habe die Konvertierung YUV420_888 zu RGB gelöst, siehe hier http://stackoverflow.com/q/36212904/5148048. Ich bin mir sicher, dass dies für viele oder sogar alle Geräte funktioniert. Sie müssen RenderScript einrichten, was nicht so schwierig ist. – Settembrini

+0

Bleibt das Skew-Problem beim Renderskript bestehen? –

0

Ich verbesserte auf API 23 und der gleiche Code funktionierte gut. Auch getestet auf API 22 und es hat auch funktioniert.

Gleiche wie: Using Camera2 API with ImageReader