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は以下のような感じになるだろう。
追記した部分を赤で示した。
<?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を継承して作っていくことになる。
コードは以下のようになる。
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はビューをセットしているだけである。
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(new MyCameraView(this));
}
}
ここまでのプログラムを実行すると、カメラのプレビュー画像が画面に表示されるだろう。

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