概要
Androidで360°写真(またはパノラマ写真)を表示させるためのサンプルや、日本語の解説が少なかったため、備忘録としてサンプルを作成してみました。
【完成サンプルコード】
GitHub - Android VrViewSample
開発準備
新規プロジェクトを作成
新しくプロジェクトを作成する。
Activityは特に指定がなければEmptyActivityを選択。
Google VR SDK をプロジェクトに追加
Android Studioのターミナルから以下のコマンドで追加
$ git clone https://github.com/googlevr/gvr-android-sdk.git
【上記の方法がうまくいかない場合】
こちらよりGoogle VR SDKをダウンロードし、解凍する
解答したフォルダ(gvr-android-sdk)をプロジェクトの直下に追加する
開発
setting.gradleに追記
include ':app'
include ':gvr-android-sdk/libraries:audio'
include ':gvr-android-sdk/libraries:base'
include ':gvr-android-sdk/libraries:common'
include ':gvr-android-sdk/libraries:commonwidget'
include ':gvr-android-sdk/libraries:panowidget'
include ':gvr-android-sdk/libraries:videowidget'
上記を追加したらSync Nowをする
もし、Unregistered VCS root detectedというメッセージが出てきたら、ignoreを選択する
app/build.gradleに追記
dependenciesに以下を追加する
compile project(':gvr-android-sdk/libraries:common')
compile project(':gvr-android-sdk/libraries:commonwidget')
compile project(':gvr-android-sdk/libraries:panowidget')
入力したら、SyncNowをする
※minSdkVersionが19以上になっていないと、エラーが出るので注意
xmlにVrPanoramaViewを追加
表示したいレイアウトにVrPanoramaViewを追加する
<com.google.vr.sdk.widgets.pano.VrPanoramaView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/vr_view"
android:scrollbars="none"/>
ImageLoaderTask.java を追加
public class ImageLoaderTask extends AsyncTask<AssetManager, Void, Bitmap> {
private static final String TAG = "ImageLoaderTask";
private final String assetName;
private final WeakReference<VrPanoramaView> viewReference;
private final VrPanoramaView.Options viewOptions;
private static WeakReference<Bitmap> lastBitmap = new WeakReference<>(null);
private static String lastName;
@Override
protected Bitmap doInBackground(AssetManager... params) {
AssetManager assetManager = params[0];
if (assetName.equals(lastName) && lastBitmap.get() != null) {
return lastBitmap.get();
}
try(InputStream istr = assetManager.open(assetName)) {
Bitmap b = BitmapFactory.decodeStream(istr);
lastBitmap = new WeakReference<>(b);
lastName = assetName;
return b;
} catch (IOException e) {
Log.e(TAG, "Could not decode default bitmap: " + e);
return null;
}
}
@Override
protected void onPostExecute(Bitmap bitmap) {
final VrPanoramaView vw = viewReference.get();
if (vw != null && bitmap != null) {
vw.loadImageFromBitmap(bitmap, viewOptions);
}
}
public ImageLoaderTask(VrPanoramaView view, VrPanoramaView.Options viewOptions, String assetName) {
viewReference = new WeakReference<>(view);
this.viewOptions = viewOptions;
this.assetName = assetName;
}
}
MainActivity.javaにメソッドを追加
public class MainActivity extends AppCompatActivity {
private VrPanoramaView panoWidgetView;
private ImageLoaderTask backgroundImageLoaderTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
panoWidgetView = (VrPanoramaView) findViewById(R.id.vr_view);
loadPanoImage();
}
@Override
public void onPause() {
panoWidgetView.pauseRendering();
super.onPause();
}
@Override
public void onResume() {
panoWidgetView.resumeRendering();
super.onResume();
}
@Override
public void onDestroy() {
// Destroy the widget and free memory.
panoWidgetView.shutdown();
super.onDestroy();
}
private synchronized void loadPanoImage() {
ImageLoaderTask task = backgroundImageLoaderTask;
if (task != null && !task.isCancelled()) {
// Cancel any task from a previous loading.
task.cancel(true);
}
// pass in the name of the image to load from assets.
VrPanoramaView.Options viewOptions = new VrPanoramaView.Options();
viewOptions.inputType = VrPanoramaView.Options.TYPE_MONO;
// use the name of the image in the assets/ directory.
String panoImageName = "YOUR_PANORAMA_IMAGE_NAME.jpg";
// create the task passing the widget view and call execute to start.
task = new ImageLoaderTask(panoWidgetView, viewOptions, panoImageName);
task.execute(getAssets());
backgroundImageLoaderTask = task;
}
}
assetsフォルダを app/src/main 配下に追加
パノラマ写真の表示設定について
パノラマ写真の設定には、
VrPanoramaView.Options.TYPE_MONO
VrPanoramaView.Options.TYPE_STEREO_OVER_UNDER
上記の2種類があります。
写真の設定が合っていないと…
このように表示されたりします(空の上に芝生が…)
上記は、TYPE_STEREO_OVER_UNDER用の写真なのに、TYPE_MONOで表示を設定している事が原因です
TYPE_MONOで表示がおかしい場合はTYPE_STEREO_OVER_UNDERに変えてみると上手く表示されるかもしれません
【TYPE_STEREO_OVER_UNDERの写真例】
同じ写真が上下半分で分かれて表示されている感じ