如何在 Android 中设置相机方向?

How to set camera orientation in Android?

我查看了人们提出此问题的其他问题,但我不确定解决此问题的最佳方法是什么。通过 Android 的相机实施指南后,我的相机预览被锁定为风景。我想知道如何调整相机方向以反映 phone.

的方向

我试过了

camera.setDisplayOrientation(90);

这将相机锁定为纵向模式,所以我需要另一种解决方案(最好是适用于大多数设备的解决方案)。

另外,我怎样才能使保存的图像以与预览相同的方式显示?现在,如果我使用上面的那行代码使预览变为纵向,保存的图像仍会旋转为横向。

我使用 Google 的相机应用修复了这个问题。它通过使用传感器获取 phone 的方向,然后适当地设置 EXIF 标签。从相机出来的 JPEG 不是自动定向的。

另外,相机预览只能在横向模式下正常工作。如果您需要 activity 布局纵向,则必须使用方向传感器的值手动完成。

我建议检查照片的 exif 数据并特别寻找

ExifInterface exif = new ExifInterface(SourceFileName);   //API Level 5
String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);

如果对您有帮助,请发表评论让我知道。

在确定要选择的预览尺寸时,您需要考虑方向。例如,ApiDemos 的 CameraPreview 中的 getOptimalPreviewSize() 忽略了方向,只是因为他们的应用程序版本将方向锁定为横向。如果你想让方向浮动,你需要反转目标纵横比来匹配。所以,getOptimalPreviewSize() 有这个

double targetRatio=(double)width / height;

if (displayOrientation == 90 || displayOrientation == 270) {
  targetRatio=(double)height / width;
}

其中 displayOrientation 是一个从 0 到 360 的值,我是从大约 100 行一些非常丑陋的代码中确定的,这就是为什么我将所有这些都包装在一个可重用的组件中,我'很快就会发布。

其次,在控制所用 SurfaceView/TextureView 的纵横比时,需要考虑显示方向。 ApiDemos 中的 CameraPreview activity 有自己的预览 ViewGroup 来处理纵横比,你需要反转纵横比才能在纵向中使用:

if (displayOrientation == 90
        || displayOrientation == 270) {
      previewWidth=mPreviewSize.height;
      previewHeight=mPreviewSize.width;
    }
    else {
      previewWidth=mPreviewSize.width;
      previewHeight=mPreviewSize.height;
    }

其中 displayOrientation 是相同的值(90 和 270 分别是纵向和反向纵向,请注意我还没有尝试让反向纵向或反向横向工作,所以可能有需要更多调整)。

第三 - 您必须在 Camera.Parameters 上调用 setPictureSize() 之前开始预览。否则,就好像图片的宽高比应用于预览帧一样,搞砸了。

Camera.Parameters parameters=camera.getParameters();
Camera.Size pictureSize=getHost().getPictureSize(parameters);

parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);

camera.setParameters(parameters);
camera.startPreview();

parameters=camera.getParameters();
parameters.setPictureSize(pictureSize.width, pictureSize.height);
parameters.setPictureFormat(ImageFormat.JPEG);
camera.setParameters(parameters);
 Camera.Parameters params= mCamera.getParameters();
 params.set("rotation", 90); 
 mCamera.setParameters(params);