コード例 #1
0
  /**
   * Update preview TextureView rotation to accommodate discrepancy between preview buffer and the
   * view window orientation.
   *
   * <p>Assumptions: - Aspect ratio for the sensor buffers is in landscape orientation, - Dimensions
   * of buffers received are rotated to the natural device orientation. - The contents of each
   * buffer are rotated by the inverse of the display rotation. - Surface scales the buffer to fit
   * the current view bounds. TODO: Make this method works for all orientations
   */
  protected void updatePreviewDisplayRotation(Size previewSize, TextureView textureView) {
    int rotationDegrees = 0;
    Camera2MultiViewCtsActivity activity = (Camera2MultiViewCtsActivity) mContext;
    int displayRotation = activity.getWindowManager().getDefaultDisplay().getRotation();
    Configuration config = activity.getResources().getConfiguration();

    // Get UI display rotation
    switch (displayRotation) {
      case Surface.ROTATION_0:
        rotationDegrees = 0;
        break;
      case Surface.ROTATION_90:
        rotationDegrees = 90;
        break;
      case Surface.ROTATION_180:
        rotationDegrees = 180;
        break;
      case Surface.ROTATION_270:
        rotationDegrees = 270;
        break;
    }

    // Get device natural orientation
    int deviceOrientation = Configuration.ORIENTATION_PORTRAIT;
    if ((rotationDegrees % 180 == 0 && config.orientation == Configuration.ORIENTATION_LANDSCAPE)
        || ((rotationDegrees % 180 != 0
            && config.orientation == Configuration.ORIENTATION_PORTRAIT))) {
      deviceOrientation = Configuration.ORIENTATION_LANDSCAPE;
    }

    // Rotate the buffer dimensions if device orientation is portrait.
    int effectiveWidth = previewSize.getWidth();
    int effectiveHeight = previewSize.getHeight();
    if (deviceOrientation == Configuration.ORIENTATION_PORTRAIT) {
      effectiveWidth = previewSize.getHeight();
      effectiveHeight = previewSize.getWidth();
    }

    // Find and center view rect and buffer rect
    Matrix transformMatrix = textureView.getTransform(null);
    int viewWidth = textureView.getWidth();
    int viewHeight = textureView.getHeight();
    RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
    RectF bufRect = new RectF(0, 0, effectiveWidth, effectiveHeight);
    float centerX = viewRect.centerX();
    float centerY = viewRect.centerY();
    bufRect.offset(centerX - bufRect.centerX(), centerY - bufRect.centerY());

    // Undo ScaleToFit.FILL done by the surface
    transformMatrix.setRectToRect(viewRect, bufRect, Matrix.ScaleToFit.FILL);

    // Rotate buffer contents to proper orientation
    transformMatrix.postRotate((360 - rotationDegrees) % 360, centerX, centerY);
    if ((rotationDegrees % 180) == 90) {
      int temp = effectiveWidth;
      effectiveWidth = effectiveHeight;
      effectiveHeight = temp;
    }

    // Scale to fit view, cropping the longest dimension
    float scale =
        Math.max(viewWidth / (float) effectiveWidth, viewHeight / (float) effectiveHeight);
    transformMatrix.postScale(scale, scale, centerX, centerY);

    Handler handler = new Handler(Looper.getMainLooper());
    class TransformUpdater implements Runnable {
      TextureView mView;
      Matrix mTransformMatrix;

      TransformUpdater(TextureView view, Matrix matrix) {
        mView = view;
        mTransformMatrix = matrix;
      }

      @Override
      public void run() {
        mView.setTransform(mTransformMatrix);
      }
    }
    handler.post(new TransformUpdater(textureView, transformMatrix));
  }