VR全景视图 Google VrPanoramaView

作者: 唠嗑008 | 来源:发表于2017-04-17 17:40 被阅读789次

    一、背景简介

    Welcome to VR at Google


    进入Google VR主页,发现官方给我们提供了两套解决观看VR视频的方式:

    给我们提供了三个平台的API,分别是:Unity 3DAndroidIOS

    下面看一下官方给这两种方式的描述(
    Daydream


    Daydream is a platform for high quality, mobile virtual reality.

    白日梦是高质量,移动虚拟现实的平台。在主页上方官方也描述它为:低延迟,身临其境的,互动的移动VR的新平台

    Cardboard

    Cardboard lets you experience virtual reality in a simple, fun, and affordable way.

    纸板可以让你在负担得起的情况下,体验一个简单,有趣的虚拟现实。在主页上方官方也描述它为:是世界上最流行的和方便的移动VR平台(可能是经济成本低吧)

    • 2014年:Google在当年的Google I/O大会上宣布,其将开发纸盒版的HMD(头盔式显示器),年底该设备销量达到了50万。

    • 2015年:Cardboard被大公司所接受,Google将那些刻上了品牌商标的Cardboard分发给了各大合作商,消费者继续购买主题化的HMD。此时,Cardboard的发展又到了另一个高度:销量达到100万。

    • 2016年:在今年的Google I/O大会上,Google宣布Cardboard销量已达到500万部,但与此同时,Google推出了Daydream——一个更高级的移动VR HMD,并将于今年11月进入市场。如今市场上已经产生了成千上万的Cardboard应用,Google Play store上的Cardboard app安装量达到50万至100万次。

    Daydream is a much higher end VR experience. I have Cardboard, and it's neat, but in some ways, it feels like a tech demo. (白日梦是一个更高的终端虚拟现实体验。纸板,它很简洁,但在某些方面,感觉技术演示。)
    那么就此看来,应该是这样的情况:Cardboard是Google先推出的简陋版/测试版/经济适用版,现在占用了很大市场;Daydream 是今年新推出的豪华版/完善版/高端玩家版,会冲击Cardboard的市场。也就是说Cardboard短期不会死 ,Daydream还在发展中。

    介绍

    官方在这里介绍了VR view 、支持平台等。我挑几个相对重要的介绍一下:

    1、图像规格
    VR查看图像可以保存为PNG,JPEG或GIF。Google建议使用JPEG改进压缩。 为了获得最大的兼容性和性能,图像尺寸应该是2的倍数(例如,2048或4096)。单个图像应为2:1纵横比(例如4096×2048)。 立体图像应为1:1纵横比(例如4096×4096)。

    如图:


    案列

    首先下载Demo,
    https://github.com/googlevr/gvr-android-sdk

    项目(gvr-android-sdk )中有几个主要目录可以留意一下:

    • libraries

    • ndk-beta

    • samples

    • samples目录中有四个Demo,分别是:

    • SDK-controllerclient(Daydream的控制端)

    • SDK-simplepanowidget(全景图)

    • SDK-simplevideowidget(全景视频 也就是VR视频)

    • SDK-treasurehunt(寻宝项目)

    注意:运行环境必须是api19以上的手机,也就是Android4.4及以上

    VrPanoramaView(VR全景视图)的实现

    1、添加依赖

    compile 'com.google.vr:sdk-panowidget:1.40.0'
    

    2、权限

     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    

    3、布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.zx.vrview.MainActivity">
    
        <com.google.vr.sdk.widgets.pano.VrPanoramaView
            android:id="@+id/vrPanoramaView"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:scrollbars="none"/>
    
    
    </LinearLayout>
    
    

    4、activity

    /**
     * VR全景视图(图片查看器)
     */
    public class MainActivity extends AppCompatActivity {
    
        private static final String TAG = "MainActivity";
        private VrPanoramaView paNormalView;
        private VrPanoramaView.Options paNormalOptions;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            initVrPaNormalView();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            paNormalView.pauseRendering();
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            paNormalView.resumeRendering();
        }
    
        @Override
        protected void onDestroy() {
            // Destroy the widget and free memory.
            super.onDestroy();
            paNormalView.shutdown();
        }
    
    
        //初始化VR图片
        private void initVrPaNormalView() {
            paNormalView = (VrPanoramaView) findViewById(R.id.vrPanoramaView);
            paNormalOptions = new VrPanoramaView.Options();
            paNormalOptions.inputType = VrPanoramaView.Options.TYPE_STEREO_OVER_UNDER;
    //        paNormalView.setFullscreenButtonEnabled (false); //隐藏全屏模式按钮
            paNormalView.setInfoButtonEnabled(false); //设置隐藏最左边信息的按钮
            paNormalView.setStereoModeButtonEnabled(false); //设置隐藏立体模型的按钮
            paNormalView.setEventListener(new ActivityEventListener()); //设置监听
            //加载本地的图片源
            paNormalView.loadImageFromBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.andes), paNormalOptions);
            //设置网络图片源
    //        panoWidgetView.loadImageFromByteArray();
        }
    
        private class ActivityEventListener extends VrPanoramaEventListener {
            @Override
            public void onLoadSuccess() {//图片加载成功
                Log.i(TAG, "onLoadSuccess------------>");
            }
    
    
            @Override
            public void onLoadError(String errorMessage) {//图片加载失败
                Log.i(TAG, "Error loading pano:------------> " + errorMessage);
            }
    
            @Override
            public void onClick() {//当我们点击了VrPanoramaView 时候出发
                super.onClick();
                Log.i(TAG, "onClick------------>");
            }
    
            @Override
            public void onDisplayModeChanged(int newDisplayMode) {
                //改变显示模式时候出发(全屏模式和纸板模式)
                super.onDisplayModeChanged(newDisplayMode);
                Log.i(TAG, "onDisplayModeChanged------------>" + newDisplayMode);
            }
        }
    }
    

    代码分析

    这个栗子中需要注意几个知识点:

     VrPanoramaView //Google提供给我们现实全景图片的View
     Options //VrPanoramaView 所需的设置
     VrPanoramaEventListener//为 VrPanoramaView 设置监听
     loadImageFromBitmap//加载图片的主要方法
    

    Options

    接下来看看刚刚的VrPanoramaView.Options吧,上文中 是这么设置的

    panoOptions.inputType = Options.TYPE_STEREO_OVER_UNDER;
    

    那么为什么要这样设置呢?先看官方对Options中标签的介绍:

    • public static final int TYPE_MONO = 1;
      图像被预期以覆盖沿着其水平轴360度,而垂直范围是根据图像的宽高比来计算。例如,如果一个1000x250像素的图像,给出所述全景将覆盖360x90度与垂直范围是-45至+45度。

    • public static final int TYPE_STEREO_OVER_UNDER = 2;
      包含两个大小相等的投影 全景图垂直叠加。顶部图像被显示给左眼、底部图像被显示给右眼。//看下图你就懂了

    图像将覆盖沿水平轴360度,而垂直范围是根据图像的宽高比来计算。例如,如果一个1000x500像素的图像中

    这里写图片描述

    我要显示的图片是下图这样的,所以就要设置为 'TYPE_STEREO_OVER_UNDER'


    这里写图片描述

    那么什么样的图片设置为 'TYPE_MONO' 呢?请看:


    这里写图片描述

    不知道有没有眼神好的同学发现这个问题:TYPE_STEREO_OVER_UNDER类型的图片每次切换模式时候 图片中间都会有一条垂直于水平线的分割线(很浅 很浅 然后逐渐消失),

    总结

    总结下如何在Android设备上用Google的SDK做一款全景图的显示器(播放器?查看器?... 不知道叫什么合适):

    • 导入google的库

    • 在相应的布局文件中引入控件com.google.vr.sdk.widgets.pano.VrPanoramaView

    • 初始化控件

    • 为VrPanoramaView设置options

    • 找到图片的Bitmap

    • 调用VrPanoramaView的loadImageFromBitmap方法

    • 在onPause、onResume、onDestroy中做出相应处理

    相关文章

      网友评论

      本文标题:VR全景视图 Google VrPanoramaView

      本文链接:https://www.haomeiwen.com/subject/arntzttx.html