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】カメラで撮った画像を保存する – ザワプロ!