Android实现VR全景立体化显示以及优化

    xiaoxiao2021-03-25  119

    实现效果图: 提示:1.由于用虚拟机测试,本图片有部分功能不能显示,建议大家用真机测试。给你不一样的体验 2.最下方附有主页代码; 实现步骤: 1.谷歌官网提供的VR资源下载 网站 https://github.com/googlevr/gvr-android-sdk/此网站是国外的网站,需要翻墙。 2.因为使用VR的资源很小号内存,所以我们为了避免OOM的问题,在清单文件中添加 android:largeHeap="true",提高警报线。 清单文件代码: <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:largeHeap="true" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> 3.由于低版本要用高版本的东西,在Gradle文件中添加 compile 'com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7' 4.导入三个库文件common,commonwidget,panowidget 目录为gvr-android-sdk-master\libraries下的三个文件 再添加到moudle中,Ctrl+Alt+Shift+S,选择你的moudle,点击右上角加号,导入需要的库文件; 5.编译构造版本太低,2.0后的studio没办法导入此model. 会爆出这个异常,解决的办法是进入文件里,修改build.gradle文件 6.在布局文件中添加VR控件: 代码: <com.google.vr.sdk.widgets.pano.VrPanoramaView android:id="@+id/vr" android:layout_width="match_parent" android:layout_height="match_parent"></com.google.vr.sdk.widgets.pano.VrPanoramaView> 7.初始化VrPanoramaView控件 8.在src文件夹下的main文件夹下创建一个资产文件assets,存放VR图片; 9.由于VR资源数据量大,获取需要时间,故把加载图片放到子线程中进行,主线程来显示图片,可以使用一个异步线程AsyncTask或EventBus技术完成; (1)创建一个子线程,继承自AsyncTask<Void,Void,Bitmap>,并创建复写方法; (2)在创建的复写方法在子线程进行,从本地文件中把资源加载到内容分中,从资产目录中拿到资源,返回的结果是字节流,把字节流转换为Bitmap对象;并返回Bitmap对象 (3)把复写的方法运行在主线程中,创建onPostExecute()方法接收;使用VR的控件对象显示效果 代码: private class ImagerLoaderTask extends AsyncTask<Void,Void,Bitmap>{ @Override protected Bitmap doInBackground(Void... params) { try { //从资产目录中拿到资源,返回的结果是字节流; InputStream inputStream = getAssets().open("andes.jpg"); //把字节流转换呗Bitmap对象; Bitmap bitmap = BitmapFactory.decodeStream(inputStream); return bitmap; } catch (IOException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Bitmap bitmap) { //创建VrPanoramaView.options,去决定显示VR是普通效果还是立体效果; VrPanoramaView.Options options = new VrPanoramaView.Options(); //TYPE_STEREO_OVER_UNDER立体效果,就是图片的上半部分放在左眼显示,下半部分放在右眼显示; //TYPE_MONO 普通效果; options.inputType= VrPanoramaView.Options.TYPE_STEREO_OVER_UNDER; //使用VR控件对象,显示效果 需要两个参数1.Bitmap对象2.VrPanoramaView.options; mVrPanoramaView.loadImageFromBitmap(bitmap,options); super.onPostExecute(bitmap); } } 10.在Main方法中使用自定义的AsyncTask,播放VR效果 ImagerLoaderTask imagerLoaderTask = new ImagerLoaderTask(); imagerLoaderTask.execute(); 11.优化VR,因为VR很占用内存,所以当界面进入onPause状态,暂停VR视图显示,进入onResume状态,继续VR视图显示,进入onDestroy状态,杀死VR,关闭异步任务。当结束Activity时判断ImagerLoaderTask是否为空,让不为空的时候再判断activity异步任务是否取消。 创建onPause,onResume和onDestroy方法;(回调:当触动某个方法是自动调用;) 代码: //当失去焦点时,回调 protected void onPause() { //暂停渲染和显示 mVrPanoramaView.pauseRendering(); super.onPause(); } //当重新获取焦点时,回调 @Override protected void onResume() { //继续渲染和显示 mVrPanoramaView.resumeRendering(); super.onResume(); } //当Activity销毁时,回调 @Override protected void onDestroy() { //关闭渲染视图 mVrPanoramaView.shutdown(); if(mImagerLoaderTask!=null){ //在退出Activity时,如果异步任务没有取消,就需要 if(!mImagerLoaderTask.isCancelled()){ mImagerLoaderTask.cancel(true); } } super.onDestroy(); } 12.设置完后运行测试,测试时,VR底部会有2个按钮,不显示,再添加切换VR的模式; 代码: //隐藏掉VR效果左下角的信息按钮显示; mVrPanoramaView.setInfoButtonEnabled(false); //隐藏掉VR效果右下角的信息按钮显示; mVrPanoramaView.setFullscreenButtonEnabled(false); //切换VR模式 // 有两个模式:1.VrWidgetView.DisplayMode.FULLSCREEN_STEREO(手机模式) // 2.VrWidgetView.DisplayMode.FULLSCREEN_MONO(默认模式); mVrPanoramaView.setDisplayMode(VrWidgetView.DisplayMode.FULLSCREEN_STEREO); 13.设置对VR运行状态的监听,如果VR运行出现错误,可以及时的处理; //设置VR运行状态的监听,如果VR运行出错,可以及时处理; mVrPanoramaView.setEventListener(new MyVRLEventistener()); 创建一个VR运行状态监听的类 //VR运行状态监听类,自定义一个类继承 private class MyVRLEventistener extends VrPanoramaEventListener{ //当VR视图加载成功时回调; @Override public void onLoadSuccess() { super.onLoadSuccess(); Toast.makeText(MainActivity.this, "加载成功", Toast.LENGTH_SHORT).show(); } //当VR视图加载失败时回调; @Override public void onLoadError(String errorMessage) { super.onLoadError(errorMessage); Toast.makeText(MainActivity.this, "加载成功", Toast.LENGTH_SHORT).show(); } } MainActivity.java代码: public class MainActivity extends AppCompatActivity { private VrPanoramaView mVrPanoramaView; private ImagerLoaderTask mImagerLoaderTask; @Override //导入三个库文件 commoncommonwidgetpanowidget protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //VR控件实例化; mVrPanoramaView = (VrPanoramaView) findViewById(R.id.vr); //隐藏掉VR效果左下角的信息按钮显示; mVrPanoramaView.setInfoButtonEnabled(false); //隐藏掉VR效果右下角的信息按钮显示; mVrPanoramaView.setFullscreenButtonEnabled(false); //切换VR模式 // 有两个模式:1.VrWidgetView.DisplayMode.FULLSCREEN_STEREO(手机模式) // 2.VrWidgetView.DisplayMode.FULLSCREEN_MONO(默认模式); mVrPanoramaView.setDisplayMode(VrWidgetView.DisplayMode.FULLSCREEN_STEREO); //设置VR运行状态的监听,如果VR运行出错,可以及时处理; mVrPanoramaView.setEventListener(new MyVRLEventistener()); //使用自定义的AsyncTask,实现播放VR效果 mImagerLoaderTask = new ImagerLoaderTask(); mImagerLoaderTask.execute(); } private class ImagerLoaderTask extends AsyncTask<Void,Void,Bitmap>{ @Override protected Bitmap doInBackground(Void... params) { try { //从资产目录中拿到资源,返回的结果是字节流; InputStream inputStream = getAssets().open("andes.jpg"); //把字节流转换呗Bitmap对象; Bitmap bitmap = BitmapFactory.decodeStream(inputStream); return bitmap; } catch (IOException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Bitmap bitmap) { //创建VrPanoramaView.options,去决定显示VR是普通效果还是立体效果; VrPanoramaView.Options options = new VrPanoramaView.Options(); //TYPE_STEREO_OVER_UNDER立体效果,就是图片的上半部分放在左眼显示,下半部分放在右眼显示; //TYPE_MONO 普通效果; options.inputType= VrPanoramaView.Options.TYPE_STEREO_OVER_UNDER; //使用VR控件对象,显示效果 需要两个参数1.Bitmap对象2.VrPanoramaView.options mVrPanoramaView.loadImageFromBitmap(bitmap,options); super.onPostExecute(bitmap); } } @Override //当失去焦点时,回调 protected void onPause() { //暂停渲染和显示 mVrPanoramaView.pauseRendering(); super.onPause(); } //当重新获取焦点时,回调 @Override protected void onResume() { //继续渲染和显示 mVrPanoramaView.resumeRendering(); super.onResume(); } //Activity销毁时,回调 @Override protected void onDestroy() { //关闭渲染视图 mVrPanoramaView.shutdown(); if(mImagerLoaderTask!=null){ //在退出Activity时,如果异步任务没有取消,就需要 if(!mImagerLoaderTask.isCancelled()){ mImagerLoaderTask.cancel(true); } } super.onDestroy(); } //VR运行状态监听类,自定义一个类继承 private class MyVRLEventistener extends VrPanoramaEventListener{ //VR视图加载成功时回调; @Override public void onLoadSuccess() { super.onLoadSuccess(); Toast.makeText(MainActivity.this, "加载成功", Toast.LENGTH_SHORT).show(); } //VR视图加载失败时回调; @Override public void onLoadError(String errorMessage) { super.onLoadError(errorMessage); Toast.makeText(MainActivity.this, "加载成功", Toast.LENGTH_SHORT).show(); } } }
    转载请注明原文地址: https://ju.6miu.com/read-5330.html

    最新回复(0)