Welcome to VR at Googleandroid
进入Google VR主页,发现官方给咱们提供了两套解决观看VR视频的方式:ios
给咱们提供了三个平台的API,分别是:Unity 3D 、Android、IOS;面试
下面看一下官方给这两种方式的描述(
Daydream小程序
Daydream is a platform for high quality, mobile virtual reality.api
白日梦是高质量,移动虚拟现实的平台。在主页上方官方也描述它为:低延迟,身临其境的,互动的移动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 、支持平台等。我挑几个相对重要的介绍一下:
一、图像规格
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及以上
一、添加依赖
compile 'com.google.vr:sdk-panowidget:1.40.0'
二、权限
<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"/>
三、布局
<?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>
四、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//加载图片的主要方法
接下来看看刚刚的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技术开发企鹅交流 7520 16839
进群与大牛们一块儿讨论,还可获取Android高级架构资料、源码、笔记、视频
包括 高级UI、Gradle、RxJava、小程序、Hybrid、移动架构、React Native、性能优化等全面的Android高级实践技术讲解性能优化架构思惟导图,和BATJ面试题及答案!
群里免费分享给有须要的朋友,但愿可以帮助一些在这个行业发展迷茫的,或者想系统深刻提高以及困于瓶颈的朋友,在网上博客论坛等地方少花些时间找资料,把有限的时间,真正花在学习上,因此我在这免费分享一些架构资料及给你们。但愿在这些资料中都有你须要的内容。