Step1 カメラ画像へのオーバーレイと方位センサー情報の取得
ARアプリ作成の準備として、カメラ画像の表示と各センサー情報の取得を行います。カメラについては5、6回で行なった内容を、センサーについては7、8回で行なった内容が参考になります。分からない点があればそちらも参考にしてみて下さい。
1.プロジェクトの作成とManifestの設定
はじめにプロジェクの作成を行います。各設定項目は以下のように設定してください。
プロジェクト名 | CompassApp |
Build Target | Google APIs(Android 2.2) |
Application name | GPSARApp |
Package name | com.example.gpsar |
Activity | GPSARApp |
Min SDK Version | 7 |
続いてAndroidManifest.xmlの設定を行います。
AndroidManifest.xmlを開きます。画面を横向きで実行するために、アプリケーションタブを開き、左下ApplicationNodesよりGPSARApp(Activity)を選択、Screenorientationの項目をlandscapeに設定します。
続けて位置情報のライブラリを使用するために、同じくApplicationNodesの追加ボタンを押し、UsesLibraryを選択、nameにcom.google.android.mapを選択します。
次にカメラ、GPSのアクセスを行うために、許可のタブを開き、追加、UsesPermissionよりandroid.permission.Camera、android.permission.ACCESS_FINE_LOCATIONの2つを登録します。
以上で下準備は完了です。それでは第5回の内容でも行なったCameraViewを作成しましょう。
2.CameraViewの作成
今回作成するARアプリではCameraViewを背景として使用します。View自体に機能を持たせることはないので特別な説明は必要無いでしょう。プロジェクトにCameraView.javaを追加し、以下の内容を記述して下さい。
package com.example.gpsarapp; import android.content.Context; import android.hardware.Camera; import android.view.SurfaceHolder; import android.view.SurfaceView; public class CameraView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder surfaceHolder; private Camera camera; // コンストラクタ public CameraView(Context context) { super(context); //サーフェイスホルダーの取得とコールバック通知先の指定 surfaceHolder = getHolder(); surfaceHolder.addCallback(this); // SurfaceViewの種別をプッシュバッファーに変更します surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } @Override public void surfaceCreated(SurfaceHolder surfaceholder) { try { camera = Camera.open(); camera.setPreviewDisplay(surfaceholder); } catch (Exception e) { } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // プレビューの開始 camera.startPreview(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { camera.setPreviewCallback(null); camera.stopPreview(); camera.release(); camera = null; } } |
以上でカメラを使用する準備が整いました。
それではCameraViewを背景とする処理を作成していきましょう。
3.オーバレイと方位センサー情報の取得
それでは実際にカメラ画像の上にオブジェクトの表示を行って行きましょう。Step1ではセンサーの情報を用いて簡単なコンパスを表示します。カメラ画像へのオーバーレイ表示はViewの重ね合わせによって実現します。
CameraViewは先程準備したのでARの内容を表示するARViewを作成しましょう。
まずプロジェクトにARView.javaを追加します。
package com.example.gpsarapp; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.view.View; public class ARView extends View { // コンパスの描画位置を指定する private final float POS_COMPASSX = 20; private final float POS_COMPASSY = 20; // 向きを保持する変数 float direction; public ARView(Context context) { super(context); } // (1)描画処理 @Override protected void onDraw(Canvas canvas) { Paint paint = new Paint(); paint.setAntiAlias(true); // コンパスを描画する drawCompass(canvas, paint); } // (2)コンパスの描画 private void drawCompass(Canvas canvas, Paint paint) { Path path = new Path(); path.moveTo(POS_COMPASSX, POS_COMPASSY - 20); path.lineTo(POS_COMPASSX + 10, POS_COMPASSY + 10); path.lineTo(POS_COMPASSX - 10, POS_COMPASSY + 10); path.moveTo(POS_COMPASSX, POS_COMPASSY - 20); paint.setColor(Color.RED); canvas.rotate(-direction, POS_COMPASSX, POS_COMPASSY); canvas.drawPath(path, paint); canvas.rotate(direction, POS_COMPASSXCOMPASSY, POS_); } // (3)センサー値の取得と再描画 public void drawScreen(float preDirection) { // センサーの値から端末の向きを計算する direction = (preDirection + 450) % 360; // onDrawを呼び出して再描画 invalidate(); } } |
(1)描画処理
図形の描画には主にPaintクラスとCanvasクラスを使用します。Paintクラスでは描画する形式を指定します。
paint.setAntiAlias(true);ではアンチエイリアス処理を有効にしています。
(2)コンパスの描画
Pathクラスを使用してコンパスとなる三角形を描画しています。 Canvas.rotateメソッドを使用することで描画図形をdirectionの値によって回転させています。この処理により、常に北に鋭角を向ける簡易コンパスを実装します。
(3)センサー値の取得と再描画
センサーの値については後述となりますが、引数より北を0度、東を90度、南を180度、西を270度とする端末の向きを取得し、directionに格納します。本来はセンサーの値をそのまま使うことができますが、端末を傾けて使用する場合には角度が90度変化するため上記のような計算が必要になります。
また、invalidate();はonDrawを呼び出す関数となっているのでメソッドdrawScreenを呼び出すことで画面の再描画行えるという事になります。
GPSARApp.javaの内容は以下のようになります。センサーの変化によってメソッドを呼び出すため、SensorEventListenerインターフェースを実装します。
package com.example.gpsarapp; import java.util.List; import android.app.Activity; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.view.Window; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; public class GPSARApp extends Activity implements SensorEventListener { private SensorManager sensorManager; private float[] accelerometerValues = new float[3]; private float[] magneticValues = new float[3]; List |
(1)各種センサーの用意
磁気センサーと加速度センサーを用意します。
(2)Viewの重ね合わせ
最初に作成したCameraViewの上にARViewを重ねて表示します。
(3)センサー値の反映
sensorManager.registerListenerは第1引数にセンサーによって呼び出される関数を持つクラスを、第2引数に対象となる値を、第3引数に呼び出し頻度を指定します。ここでは更新の頻度に一番オーソドックスなSENSOR_DELAY_NORMALを指定しています。ゲームに使用する場合などシビアな更新が必要とされる場合にはSENSOR_DELAY_GAMEなどの値を指定することが出来ます。
(4)センサー値の反映
owSensorChangedはセンサーの値が変わる度に呼び出されるメソッドです。magneticValuesでは3軸方向の磁力密度を、accelerometerValuesでは3軸方向の加速度を取得します。この2つの値を組合わえることで端末の傾きに左右されずに方位を求めることが出来ます。また、このメソッドの中で arView.drawScreenを呼び出すことで、センサー値が更新される度にARViewの再描画を行う事が出来ます。
プログラムを実行すると、下画像のようにカメラ画像へのコンパスのオーバーレイ表示が確認出来ると思います端末の向きを変えることでコンパスの向きも変わることが確認できます。それでは位置情報を使用したARを実現するためにStep2で位置情報の管理を行う処理を作成しましょう。
第10回 ARゲームを作ってみよう(2)
Step1 カメラ画像へのオーバーレイと方位センサー情報の取得
Step2 位置情報の取得とデータベースの作成
Step3 可視判定とテキストの表示
Step4 現在位置の登録