0

我的 Camera-SurfaceHolder 有一个奇怪的问题。

我想在我的活动中显示相机的图像。这一切都在我的 GalaxyS1(CyanogenMod - Android 4.4)上非常有效,另一方面,在我的 S3(也是 CyanogenMod - Android 4.4)上,它看起来很奇怪。

没有标题栏的横向图像还可以,但是当我显示标题栏或将其转换为纵向模式时,它看起来会变形:

在此处输入图像描述

- - 编辑 - -

谢谢亚历克斯科恩的帮助。看起来你是对的。肖像模式的预览现在运行良好。但它在横向视图上看起来仍然失真。我检查了预览比例,看起来还不错。据我所知,我也正确设置了预览大小。那么它有什么问题呢?

这是当前代码:

    private static final String TAG = CameraView.class.getSimpleName();

      private SurfaceHolder surfaceHolder;
      private Camera camera;
      private List<Size> mSupportedPreviewSizes;
      private Size mPreviewSize;

      public CameraView(Activity activity) {
        super(activity);
        surfaceHolder = getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        camera = Camera.open();
        mSupportedPreviewSizes = camera.getParameters()
                .getSupportedPreviewSizes();
        setCameraDisplayOrientation(activity, 0, camera);
      }

      @Override
      public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        Camera.Parameters parameters = camera.getParameters();
        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        camera.setParameters(parameters);
        camera.startPreview();
      }

      @Override
      public void surfaceCreated(SurfaceHolder holder) {
       try {
         camera.setPreviewDisplay(holder);
       } catch (IOException exception) {
             camera.release();
             camera = null;
       }
      }

     @Override
       public void surfaceDestroyed(SurfaceHolder arg0) {
       camera.stopPreview();
       camera.release();
       camera = null;
     }

   @Override
   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
    final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
                setMeasuredDimension(width, height);

    if (mSupportedPreviewSizes != null) {
        mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
    }
  }

  private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w,
                int h) {...}

  public static void setCameraDisplayOrientation(Activity activity,
                int cameraId, Camera camera) {...}

- - 编辑 - -

我记录了 onMeasure 和 surface Changed 的​​值。他们似乎没问题:

肖像:

表面改变:宽度:720 高度:1134

onMeasure:宽度:720 高度:1134

景观:

表面改变:宽度:1280 高度:590

onMeasure:宽度:1280 高度:590

预览尺寸:宽度:704 高度:576

我得到以下可能的预览尺寸。

数组中有 8 个元素:

960×720、1280×720、1184×666、960×640、704×576、640×480、352 × 288、320×240

希望任何人都可以提供帮助!

谢谢,托拜厄斯

4

1 回答 1

2

您的问题的根源是以下行:

parameters.setPreviewSize(w, h);

surfaceChanged()方法。您不能在 Android 中将预览大小设置为任意值。您应该只使用Parameters.getSupportedPreviewSizes()返回的(w, h)对。否则,你碰到的似乎成功是一种有效形式的未定义行为情况。实际上,许多设备只会在 上引发RuntimeException,但您的开发平台选择了不同的行为。camera.setParameters(parameters)

不要求预览大小与用于显示它的表面相同,例如在 640x480 表面上使用 320x240 预览是可以的。但是,如果您的预览和表面具有不同的纵横比,则图像看起来会被拉伸(请参阅http://i.stack.imgur.com/VFwes.jpg)。轻微的失真可能是可以容忍的,例如在 800x400 像素屏幕上使用 1280x720 预览,但超过一定阈值,您别无选择,只能使用部分屏幕,在预览上方和下方留下边距。

您可以找到开发人员社区提出的建议:使用getOptimalPreviewSize()给定的宽度、高度(这只是一个示例)。

于 2014-03-24T08:00:33.957 回答