2016-08-24 15 views
2

マイアプリは、カメラ2のAPIを使用してデバイスのカメラからプレビューを管理します。しかし、問題は私のデバイスが反転したセンサーとよく知られている逆の景観「問題」を持つNexus 5xだということです。 Camera2 APIがこれを「自動的に」扱うところを読んだのですが、キャプチャセッションの設定時にサーフェスビューオブジェクトのサーフェスをターゲットにしている限り、これは真実だと思います。しかし、代わりに私は立体テクスチャに基づいたサーフェスをターゲットにしています。プレビューで立体視を実現するためにさらに使用します。このアプローチでは問題は解決しません。ここでコードはありますが、これはcamera2 APIを使用するときの従来のワークフローとほぼ同じです。カメラ2のAPIを使用してNexus 5xで「逆景観」の問題を解決する方法

private void openCamera() { 
    CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); 
    Log.e(TAG, "is camera open"); 
    try { 
     cameraId = manager.getCameraIdList()[CAMERA_SOURCE]; 
     CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); 
     StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 
     assert map != null; 
     imageDimension = map.getOutputSizes(SurfaceTexture.class)[CAMERA_SOURCE]; 
     // Add permission for camera and let user grant the permission 
     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { 
      ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CAMERA_PERMISSION); 
      return; 
     } 
     manager.openCamera(cameraId, stateCallback, null); 

    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } 
    Log.e(TAG, "openCamera X"); 
} 

private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() { 
    @Override 
    public void onOpened(CameraDevice camera) { 
     //This is called when the camera is open 
     Log.e(TAG, "onOpened"); 
     cameraDevice = camera; 
     createCameraPreview(); 
    } 
    @Override 
    public void onDisconnected(CameraDevice camera) { 
     cameraDevice.close(); 
    } 
    @Override 
    public void onError(CameraDevice camera, int error) { 
     cameraDevice.close(); 
     cameraDevice = null; 
    } 
}; 

protected void createCameraPreview() { 
    try { 

     // Create ImageReader Surface 
     int max = 2; 
     mReader = ImageReader.newInstance(mWidth, mHeight, ImageFormat.YUV_420_888, max); 
     ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() { 
      @Override 
      public void onImageAvailable(ImageReader mReader) { 
       Image image = null; 
       image = mReader.acquireLatestImage(); 
       if (image == null) { 
        return; 
       }       

       byte[] bytes = convertYUV420ToNV21(image); 

       nativeVideoFrame(bytes); 
       image.close(); 
      } 
     };  

     mReader.setOnImageAvailableListener(readerListener, mBackgroundHandler); 

     // Create Texture Surface 
     texture = createTexture(); 
     mSurfaceTexture = new SurfaceTexture(texture); 
     mSurfaceTexture.setOnFrameAvailableListener(this); 
     mSurfaceTexture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight()); 
     mSurface = new Surface(mSurfaceTexture); 

     //Attach surfaces to CaptureRequest 
     List<Surface> outputSurfaces = new ArrayList<Surface>(2); 
     outputSurfaces.add(mReader.getSurface()); 
     outputSurfaces.add(mSurface); 
     captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 
     captureRequestBuilder.addTarget(mSurface); 
     captureRequestBuilder.addTarget(mReader.getSurface()); 

     //Define the capture request 
     cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback(){ 
        @Override 
        public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) { 
         //The camera is already closed 
         if (null == cameraDevice) { 
          return; 
         } 
         // When the session is ready, we start displaying the preview. 
         cameraCaptureSessions = cameraCaptureSession; 
         updatePreview(); 
        } 
        @Override 
        public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) { 
         Toast.makeText(MainActivity.this, "Configuration change", Toast.LENGTH_SHORT).show(); 
        } 
       }, null); 
     } catch (CameraAccessException e) { 
      e.printStackTrace(); 
     } 
} 

protected void updatePreview() { 
    if(null == cameraDevice) { 
     Log.e(TAG, "updatePreview error, return"); 
    } 
    captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); 
    try { 
     cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler); 
    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } 
} 

私の疑問は、自分自身で逆景観の問題を解決するにはどうすればよいですか?どのコード行とどこに追加すればよいですか?

おかげで、

JM

答えて

1

あなたはSurfaceTextureとするImageReaderを使用しているので、あなたがローテーションを自分で処理する必要があります。 Camera2 APIは、SurfaceViewまたはTextureViewと組み合わせて使用​​すると自動的に回転を処理します。

これは、ImageReader.OnImageAvailableListenerコールバック経由で取得したフレームのバイトを手動で回転させることができますし、OpenGLテクスチャでそのアクションを実行するGPU上で直接的には優れているとも言えます。平面

  • カメラテクスチャを描画スケール°

    • 回転180により-1:回転180°は、OpenGLにそれがいずれかのことを意味しており、一度上下回水平バイトを反転と等価であること

      注カメラの質感に

    • 変更SurfaceTexture付きカメラ平面
  • +1

    のUVを紙面のxとyは、あなたがhttps://developer.android.com/reference/anから値を使用する必要がありますGLテクスチャから読み取るdroid/graphics/SurfaceTexture.html#getTransformMatrix(float [])。カメラ2では、正しい向き(TextureViewが正しく取得する方法)が得られます。 ImageReaderでは、カメラデバイスのセンサー方向(https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#SENSOR_ORIENTATION)を見て、正しい順序でピクセルにアクセスする必要があります。 –

    関連する問題