【Android】カメラのプレビューを表示する

投稿者: | 2011年7月10日

Androidで、カメラのプレビューを画面に表示させるまでをやってみる。
カメラを使用するためには、AndroidManufest.xmlに何点か追記する必要がある。

まず、カメラを使用することを宣言するため、以下を記述する。

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />

さらに、オートフォーカス機能を使いたいときは、以下の記述も必要である。

<uses-feature android:name="android.hardware.camera.autofocus" />

次に、カメラの画像は横向きで取得されるため、画面の向きを横向きに固定しておく。
それをするために、activityの属性に「android:screenOrientation=”landscape”」という記述を加える。

ここまでで、AndroidManufest.xmlは以下のような感じになるだろう。
追記した部分を赤で示した。

AndroidManufest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.lesson.camera"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name="com.lesson.camera.MainActivity"
                  android:label="@string/app_name"
                  android:screenOrientation="landscape">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

	<uses-permission android:name="android.permission.CAMERA"/>
	<uses-feature android:name="android.hardware.camera" />
</manifest>

次に、カメラから取得した画像を表示するためのビューを作る。このビューはSurfaceViewを継承して作っていくことになる。
コードは以下のようになる。

MyCameraView.java

public class MyCameraView extends SurfaceView{

	private Camera camera;

    /**
     * サーフェイスコールバック
     */
    private final SurfaceHolder.Callback surfaceCallback = new Callback() {

		@Override
		public void surfaceCreated(SurfaceHolder holder) {

			// カメラを取得
	        camera = Camera.open();

	        if( camera != null ){
		        try {
					camera.setPreviewDisplay(holder);
				} catch (IOException e) {
					e.printStackTrace();
				}
	        }
		}

		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {

			// プレビュー開始
	        if( camera != null){
	        	camera.startPreview();
	        }
		}

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			// プレビュー停止
			if( camera != null){
		        camera.stopPreview();
		        camera.release();
		        camera = null;
			}
		}
	};

    /**
     * コンストラクタ
     * @param context
     */
    public MyCameraView(final Context context) {
        super(context);

        final SurfaceHolder holder = getHolder();

        // これをしないと落ちる・・・ SDK3.1では廃止されたようだ
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    	// コールバック登録
        holder.addCallback(surfaceCallback);
    }
}

大まかな流れは、基本的なSurfaceViewのプログラミングと同じである。
まずはコンストラクタから見てみよう。カメラのプログラミングでは、SurfaceViewのタイプを変更することが必要なようである。
56行目、「holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);」の記述がそれにあたる。
この記述が無いと、18行目、「camera.setPreviewDisplay(holder);」を呼び出した段階で落ちてしまった。
そんなこともあって、SurfaceHolder#setType()メソッドがどういうものなのか調べたかったのだが、今現在(2011/7/10)、公式ドキュメントを見ると、SDK3.1ではSurfaceHolder#setType()は廃止された、としか書いていない・・・。新しいSDKでは、このあたりの事情は違ってくるのかも知れない。

SurfaceCallbackの処理へ移る。14行目、Cameraのopen()を呼ぶことで、端末がカメラをサポートしている場合はカメラオブジェクトを取得できる。
18行目で、プレビューするための画面をカメラ側へセットしている。
後はsurfaceChangedのタイミングでプレビューを開始し、surfaceDestroyedのタイミングでプレビューの終了とカメラの開放を行っている。

最後に、Activityはビューをセットしているだけである。

MainActivity.java

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);

        setContentView(new MyCameraView(this));
    }
}

ここまでのプログラムを実行すると、カメラのプレビュー画像が画面に表示されるだろう。

【Android】カメラのプレビューを表示する」への1件のフィードバック

  1. ピンバック: 【Android】カメラで撮った画像を保存する – ザワプロ!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です