C/C++プログラマの管理者が, Androidプログラムにチャレンジ. AndroidプログラミングのTipsをメモっていく予定です.

Androidのカメラは横向き(Landscape)が基本であるが, Android 2.2以降ではCamera#setDisplayOrientationメソッドを利用することで縦向き(Portrait)にすることができる.

ディスプレイの向き設定(API Level 8)

  • src/MainActivity.java
    • SurfaceHolder#surfaceCreatedメソッドをオーバーライドする.
      • Camera#openメソッドで, カメラIDを指定してカメラを起動する.
    注) カメラIDについては, 「フロント/バックのカメラを指定する」を参照.
      • setCameraDisplayOrientationメソッドで, ディスプレイの向きを設定する.
    • setCameraDisplayOrientationメソッドを実装する.
      • Camera#getCameraInfoメソッドで, カメラの情報を取得する.
      • Display#getRotationメソッドで, ディスプレイの回転情報を取得する.
      • 回転情報かからディスプレイの向きを求める.
      • フロント/バックカメラの場合に分けて, カメラの向きとディスプレイの向きからプレビューの向きを計算する.
      • Camera#setDisplayOrientationメソッドで, ディスプレイの向きを設定する.
    注) Android Developersのサンプルコードを参照.
package com.moonlight_aska.android.camera03;

import java.io.IOException;

import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MainActivity extends Activity implements SurfaceHolder.Callback {
  private Camera mCamera = null;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    SurfaceView preview = (SurfaceView)findViewById(R.id.preview_id);
    SurfaceHolder holder = preview.getHolder();
    holder.addCallback(this);
  }

  @Override
  public void surfaceCreated(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    int cameraId = 0;
    mCamera = Camera.open(cameraId);
    // ディスプレイの向き設定
    setCameraDisplayOrientation(cameraId);
    try {
      mCamera.setPreviewDisplay(holder);
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  @Override
  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    // TODO Auto-generated method stub
    mCamera.stopPreview();
    // プレビュー画面のサイズ設定
    Camera.Parameters params = mCamera.getParameters();
    List<Size> previewSizes = params.getSupportedPreviewSizes();
    Size size = previewSizes.get(0);
    params.setPreviewSize(size.width, size.height);
    mCamera.setParameters(params);
    // プレビュー開始
    mCamera.startPreview();
  }

  @Override
  public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    mCamera.stopPreview();
    mCamera.release();
    mCamera = null;
  }

  // ディスプレイの向き設定
  public void setCameraDisplayOrientation(int cameraId) {
    // カメラの情報取得
    CameraInfo cameraInfo = new CameraInfo();
    Camera.getCameraInfo(cameraId, cameraInfo);
    // ディスプレイの向き取得
    int rotation = 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 (cameraInfo.facing == cameraInfo.CAMERA_FACING_FRONT) {
      result = (cameraInfo.orientation + degrees) % 360;
      result = (360 - result) % 360; // compensate the mirror
    }
    else { // back-facing
      result = (cameraInfo.orientation - degrees + 360) % 360;
    }
    // ディスプレイの向き設定
    mCamera.setDisplayOrientation(result);
  }
}
  • 動作例
MSI Primo81 / Android 4.4
対応前対応後



コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu


逆引き(基礎編)

画面表示/操作(49)

フラグメント(1)

逆引き(応用編)

Firebase(2)

AD



管理人/副管理人のみ編集できます