【问题标题】:Preview streched in Camera2 API when creating layout programmaticaly以编程方式创建布局时在 Camera2 API 中拉伸的预览
【发布时间】:2018-12-07 17:51:30
【问题描述】:

在更新我们的应用程序后,我们现在使用 Camera2 API,不幸的是,预览在我们的测试设备上被拉伸:Samsung SM-J330F/DS,Android-Version 8.0.0,API 26

因为我们在同一设备上使用 Google 的 Camera2Basic 项目没有遇到此问题,所以我们尝试调整我们的项目以使用相同的预览实现。目前我们只是无法弄清楚两个项目之间的预览不同的确切原因。

这是预期的:

与 Camera2Basic 项目相比,我们的 RelativeLayout 是在 Activity 类中以编程方式创建的,然后将 AutoFitTextureView 添加到此对象中:

mMainLayout = new FrameLayout(this);
mMainLayout.setBackgroundColor(Color.BLACK);
mMainLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT));

mPreview = new AutoFitTextureView(this);
mPreview.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT, Gravity.TOP));

mMainLayout.addView(mPreview);
this.setContentView(mMainLayout);

AutoFitTextureView 的实现与 Camera2Basic 项目中的相同。

稍后在 Camera2 类中将 setUpCameraOutputs() 中的预览设置为 640x480 像素(所有设备都应支持的分辨率)后,我们在 mPreview 上调用 setAspectRatio(width, height)

mPreviewSize = new Size(640, 480);

if (mFrameOrientation == Configuration.ORIENTATION_LANDSCAPE) {
    mTextureView.setAspectRatio(
        mPreviewSize.getWidth(), mPreviewSize.getHeight()
    );
} else {
    mTextureView.setAspectRatio(
        mPreviewSize.getHeight(), mPreviewSize.getWidth()
    );
}

注意:在较新的设备(如荣耀 10)上,预览效果也不错。

【问题讨论】:

    标签: java android android-camera android-camera2


    【解决方案1】:

    我认为问题在于您修复了mPreviewSize 的值。因此,在某些分辨率大于 640*480 的设备中,相机预览会被拉伸。

    mPreviewSize 的大小应与AutoFitTextureView 相同。

    mPreviewSize = new Size(mPreview.getHeight(), mPreview.getWidth());
    

    【讨论】:

      【解决方案2】:

      解决这个问题的方法是在openCamera()onSurfaceTextureSizeChanged()中调用如下函数:

      /**
       * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.
       * This method should be called after the camera preview size is determined in
       * setUpCameraOutputs and also the size of `mTextureView` is fixed.
       *
       * @param viewWidth  The width of `mTextureView`
       * @param viewHeight The height of `mTextureView`
       */
      private void configureTransform(int viewWidth, int viewHeight) {
          Activity activity = getActivity();
          if (null == mTextureView || null == mPreviewSize || null == activity) {
              return;
          }
          int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
          Matrix matrix = new Matrix();
          RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
          RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
          float centerX = viewRect.centerX();
          float centerY = viewRect.centerY();
          if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
              bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
              matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
              float scale = Math.max(
                      (float) viewHeight / mPreviewSize.getHeight(),
                      (float) viewWidth / mPreviewSize.getWidth());
              matrix.postScale(scale, scale, centerX, centerY);
              matrix.postRotate(90 * (rotation - 2), centerX, centerY);
          } else if (Surface.ROTATION_180 == rotation) {
              matrix.postRotate(180, centerX, centerY);
          }
          mTextureView.setTransform(matrix);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-17
        • 1970-01-01
        • 2012-10-01
        相关资源
        最近更新 更多