Androidのカメラの向きに関する覚え書き
Androidでカメラを使ったアプリを作っているんだが、端末本体(カメラ)の向きに合わせて撮影した写真の向きも変えるのが結構面倒。その辺のAndroid API仕様の覚え書き。
Androidでは、カメラの向きに関するポリシーは、以下のどちらかになると思われる。
- 端末本体の向きに関係なく、アプリの向きlandscape固定にする
- 端末本体の向きに合わせて、アプリの向きや写真の向きを変える
1.が一番簡単。マニフェストファイルの
2.が結構面倒。カメラのプレビュー表示と撮影した写真の2つの向きを、それぞれ端末本体の向きに合うように制御する必要がある。
カメラのプレビュー表示の向きを変える
Cameraをopen()したあと、setDisplayOrientation()メソッドでプレビュー表示の向きを、端末本体の向きに合わせて変更する。これをしないと、カメラから撮影する対象の向きと、プレビュー表示の向きが合わなくなる。コードは、下記を参考に。
Camera#setDisplayOrientation()のAPI doc
撮影した写真の向きを変える
最初は、Camera.Parameters#setRotation()で変えられると思ったが、Camera.PictureCallbackで渡されるJPEG画像の向きが変わるかどうかは機種依存らしい。少なくとも手元のXPERIA arcでは向きは変わらなかった。
Camera.Parameters#setRotation()のAPI doc
仕方ないので、自分でBitmapを操作して、端末の向きに合わせて写真の向きを変える事にした。例えば、onPictureTaken()メソッドを下記のように実装する。
public void onPictureTaken(byte[] data, Camera camera) { 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; } Matrix m = new Matrix(); //Bitmapの回転用Matrix m.setRotate(degrees); Bitmap original = BitmapFactory.decodeByteArray(data, 0, data.length); Bitmap rotated = Bitmap.createBitmap( original, 0, 0, original.getWidth(), original.getHeight(), m, true); savePicture(rotated); }