【Android】カメラ機能を使ってプレビューをSurfaceViewに表示する方法


タイトルとおりの内容です。
カメラを使ったアプリには必ず必要なので是非とも覚えておきたい機能ですね。

今回はプレビューをSurfaceViewに表示する方法までを紹介します。



カメラのプレビューを表示するためには SurfaceView という特殊なViewを使用します。
(↓基本的な使い方を紹介した過去の記事)
【Android】SurfaceViewを使ってゲームっぽいアプリを作ってみる(基幹編)
【Android】SurfaceViewを使ってゲームっぽいアプリを作ってみる(入力編)

AndroidManifestにカメラのパーミッションを追加する

カメラ機能を使うためにはAndroidManifest.xmlを修正する必要があります、

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



これでカメラ機能を使う準備はOKです(^ω^)

プレビューを表示するためのSurfaceViewを用意する


SurfaceViewとSurfaceHolderを用意して、インスタンスの生成。
アクティビティのonCreateコールバック関数を設定します。
今回はクラス SampleCallBack 用意します。

	SurfaceView sv;
	SurfaceHolder sh;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.VERTICAL);
        setContentView(ll);

        sv = new SurfaceView(this);
        sh = sv.getHolder();

        sh.addCallback(  new SampleCallback() );
        sh.setType( SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS );
        ll.addView(sv);

    }




カメラ用の設定として、16行目のsetTypeをします。
これを忘れると何も表示されません(´・ω・`)

Callback関数内でCameraクラスを使う


ようやくカメラの出番です。先ほど指定したコールバック関数用のクラスの中身を書きます。
Cameraクラスの関数をコールバック関数の中でカメラの操作をしていきます。
各関数では以下の様な処理をします。

surfaceCreated関数
 ・カメラのオープン
 ・表示画像のサイズを設定する
surfaceChanged関数
 ・変更されたSurfaceViewのサイズを設定する
 ・変更後の画面の向きを設定する(今回は縦向きのみ)
surfaceDestroyed関数
 ・プレビューを終了
 ・カメラを開放

class SampleCallback implements Callback{

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

	try{
		
		int d = 90;
		cm.setDisplayOrientation(d);
		cm.setPreviewDisplay(sv.getHolder());

		Camera.Parameters pr = cm.getParameters();
		pr.setPictureSize( width , height );
		cm.setParameters(pr);
		cm.startPreview();

	}catch( Exception e ){ }

}

@Override
public void surfaceCreated(SurfaceHolder holder) {

	cm = Camera.open();
	Camera.Parameters pr = cm.getParameters();
	List<Size> ss = pr.getSupportedPictureSizes();
	Size s = ss.get(0);
	pr.setPictureSize( s.width , s.height );
	cm.setParameters(pr);

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
	cm.stopPreview();
	cm.release();
}

}




サンプルプログラム


上記のプログラムをまとめたサンプルです。
プレビューを表示するだけなので撮影機能はまだありませんが…

package com.oukasoft.sample20120712;

import java.util.List;
import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.widget.LinearLayout;

public class Sample20120712Activity extends Activity {

	SurfaceView sv;
	SurfaceHolder sh;
	Camera cm;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.VERTICAL);
        setContentView(ll);

        sv = new SurfaceView(this);
        sh = sv.getHolder();

        sh.addCallback(  new SampleCallback() );
        sh.setType( SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS );
        ll.addView(sv);

    }

    class SampleCallback implements Callback{

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

			try{

				int d = 90;
				cm.setDisplayOrientation(d);
				cm.setPreviewDisplay(sv.getHolder());

				Camera.Parameters pr = cm.getParameters();
				pr.setPictureSize( width , height );
				cm.setParameters(pr);
				cm.startPreview();

			}catch( Exception e ){ }

		}

		@Override
		public void surfaceCreated(SurfaceHolder holder) {

			cm = Camera.open();
			Camera.Parameters pr = cm.getParameters();
			List<Size> ss = pr.getSupportedPictureSizes();
			Size s = ss.get(0);
			pr.setPictureSize( s.width , s.height );
			cm.setParameters(pr);

		}

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			cm.stopPreview();
			cm.release();
		}

    }
}


【実行結果】
カメラ機能を使ってSurfaceViewでプレビューを表示サンプル

次回はカメラ機能を使って撮影を行い、SDカードに画像を保存する方法を…
紹介してみたいです(´・ω・`)


関連記事

【Android】カメラ機能を使ってプレビューをSurfaceViewに表示する方法” への1件のコメント

  1. ピンバック: 【Android】カメラ機能を使って撮影した写真をSDカードに保存する方法 | 桜花満開