Edited at

Nexus 5X におけるカメラ画像上下反転問題についての対応

More than 3 years have passed since last update.

Nexus 5Xでカメラ撮影を行うと、アプリによってはpreviewまたは撮影した画像が反転するという不具合があります。その問題についてGoogleのAndroid Camera frameworkのTech Leadから声明(リンク下部)があり、どうやら結論がでたようです。


結論

デバイスの仕様によるもので、アプリ側で対応する必要があります。


何が問題なのか

camera API(deprecated)では明示的にカメラの回転情報を設定する必要がありますが、回転情報を設定していないカメラアプリもあります。それでも問題が発生しなかったのは、多くのAndroid端末ではイメージセンサーが回転を意識せずに済む方向(イメージセンサーの取り付け方は2通りあるようです)に取り付けられていたからのようです。

しかし、Nexus 5Xのイメージセンサーは設計上の制約で 他の多くのAndroid端末と異なり逆(reverse landscape)に取り付けられています。 そのため、rotationが設定されていないアプリはpreviewが反転するようになってしまいました。camera2 APIでは内部的に正しい画面回転情報を取得しているため、この問題は発生しません。なお、この現象は同じようにreverse landscapeで設計されているNexus 6のフロントカメラでも再現するようです。(手元のNexus 6では確認できませんでしたが...)


じゃあどうすればよいのか

以下の2通りの対応が考えられます。


(1) camera2 APIに移行する


camera2 APIに移行すれば、この問題は解決するとのことです。(*)

(2) setDisplayOrientationを設定する


setDisplayOrientation を設定してあげれば解決します。

public static void setCameraDisplayOrientation(Activity activity,

int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}

int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}

camera2 APIはAPI Level 21からなので、(1)の対応を進めつつ、後方のversionは(今のところ反転するメジャーな端末はなさそうですが) (2)を設定して対応する必要がありそうです。

ソース:

https://www.reddit.com/r/Android/comments/3rjbo8/nexus5x_marshmallow_camera_problem/cwqzqgh  

(なぜかリンクが投稿禁止で貼れなかったのでソースコード形式で)

(*)撮影後の画像が反転する問題もあるので、そこの対応も必要そうです。