zoukankan      html  css  js  c++  java
  • VR全景视图 Google VrPanoramaView

    一、背景简介

    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中做出相应处理

    最后给大家分享一份非常系统和全面的Android进阶技术大纲及进阶资料,及面试题集

    想学习更多Android知识,请加入Android技术开发企鹅交流 7520 16839

    进群与大牛们一起讨论,还可获取Android高级架构资料、源码、笔记、视频

    包括 高级UI、Gradle、RxJava、小程序、Hybrid、移动架构、React Native、性能优化等全面的Android高级实践技术讲解性能优化架构思维导图,和BATJ面试题及答案!

    群里免费分享给有需要的朋友,希望能够帮助一些在这个行业发展迷茫的,或者想系统深入提升以及困于瓶颈的朋友,在网上博客论坛等地方少花些时间找资料,把有限的时间,真正花在学习上,所以我在这免费分享一些架构资料及给大家。希望在这些资料中都有你需要的内容。

    转载于:https://my.oschina.net/u/3956562/blog/3018409

  • 相关阅读:
    python 包管理工具 pip 的配置
    Python 变量作用域 LEGB (下)—— Enclosing function locals
    Python 变量作用域 LEGB (上)—— Local,Global,Builtin
    2020 Java 面试题 小结 (答案慢慢补上,有错误请指出)
    mysql 根据日期(date)做年,月,日分组统计查询
    jvm指令
    正则表达式 分割地址 获取省市区详细地址
    .Net 异常记录
    WCF设计服务协议(一)
    plsql ORA-01789:查询块具有不正确的结果列数
  • 原文地址:https://www.cnblogs.com/twodog/p/12135094.html
Copyright © 2011-2022 走看看