【问题标题】:Image saved with wrong orientation以错误方向保存的图像
【发布时间】:2013-04-19 06:06:54
【问题描述】:

我正在使用此代码:

https://github.com/commonsguy/cw-advandroid/blob/master/Camera/Picture/src/com/commonsware/android/picture/PictureDemo.java

Manifest 中,Activity Orientation 设置为横向

所以,这就像只允许用户在横向模式下拍照,如果是通过手持设备在纵向模式下拍照,保存的图像是这样的:

旋转 90 度的图像。

在寻找解决方案后,我发现了这个:

Android - Camera preview is sideways

解决方案在哪里:

surfaceChanged() 中检查

Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
display.getRotation();

并相应地更改相机的显示方向

camera.setDisplayOrientation(90);

但无论我旋转设备多少次,surfaceChanged() 都不会被调用。

我什至尝试在 Manifest.xml 中删除 orientation="Landscape",但预览本身显示为横向(可能是因为默认 android.view.SurfaceView 应该处于 横向模式?)。

【问题讨论】:

  • 查看此链接,它可能对您有用。 stackoverflow.com/questions/5157984/…
  • 嗯,有个原因,我不再在书中介绍此代码... :-) 由于历史原因,我将它留在了 repo 中,但是肯定是它的问题。 FWIW,我确实计划在未来几个月内重新讨论这个话题,着眼于解决这类问题,我已经做了一个笔记来调查这个问题。但是,现在,我对你没有特别的建议——我很抱歉。

标签: android camera commonsware


【解决方案1】:

试试这个。

public void surfaceCreated(SurfaceHolder holder) {
    try {
        camera = Camera.open();
        camParam = camera.getParameters();
        Camera.Parameters params = camera.getParameters();
        String currentversion = android.os.Build.VERSION.SDK;
        Log.d("System out", "currentVersion " + currentversion);
        int currentInt = android.os.Build.VERSION.SDK_INT;
        Log.d("System out", "currentVersion " + currentInt);

        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            if (currentInt != 7) {
                camera.setDisplayOrientation(90);
            } else {
                Log.d("System out", "Portrait " + currentInt);

                params.setRotation(90);

                /*
                 * params.set("orientation", "portrait");
                 * params.set("rotation",90);
                 */
                camera.setParameters(params);
            }
        }
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            // camera.setDisplayOrientation(0);
            if (currentInt != 7) {
                camera.setDisplayOrientation(0);
            } else {
                Log.d("System out", "Landscape " + currentInt);
                params.set("orientation", "landscape");
                params.set("rotation", 90);
                camera.setParameters(params);
            }
        }
        camera.setPreviewDisplay(holder);
        camera.startPreview();
    } catch (IOException e) {
        Log.d("CAMERA", e.getMessage());
    }
}

【讨论】:

  • 我认为这只会第一次起作用,因为它写在surfaceCreated()。稍后(打开预览后)如果用户更改设备方向,则不会发生任何事情,并且拍摄的照片将再次横向。
【解决方案2】:

由于您已将应用程序强制为横向,因此当您旋转设备时应用程序的配置不会改变,因此您的 UI 不会被重绘。因此,您将永远不会因为它而看到 surfaceCreated/Changed 回调。

无论如何,您的问题不在于预览,而在于捕获的图片。

相机 API 不会自动知道哪条路是向下的;它需要您使用 Camera.Parameters setRotation 方法告诉它您希望如何旋转图像。这里有几个坐标系(相机传感器相对于您的设备的方向;您的 UI 相对于设备的方向;以及设备相对于世界的方向)必须正确完成。

所以我强烈推荐你使用setRotation文档中提供的代码,并继承自OrientationEventListener,实现监听器如下:

 public void onOrientationChanged(int orientation) {
   if (orientation == ORIENTATION_UNKNOWN) return;
   android.hardware.Camera.CameraInfo info =
        new android.hardware.Camera.CameraInfo();
   android.hardware.Camera.getCameraInfo(cameraId, info);
   orientation = (orientation + 45) / 90 * 90;
   int rotation = 0;
   if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
       rotation = (info.orientation - orientation + 360) % 360;
   } else {  // back-facing camera
     rotation = (info.orientation + orientation) % 360;
   }
   mParameters.setRotation(rotation);
 }

这将正确更新您相机的静态图片方向,以便“向上”始终向上,无论您的应用是横向还是纵向,或者您的设备是平板电脑还是手机。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    相关资源
    最近更新 更多