揭开VR View之全景图的神秘面纱

来源:互联网 发布:怎么看端口号是什么 编辑:程序博客网 时间:2024/06/08 08:09

    GoogleVR SDK简称GVR在一些休闲娱乐、旅行观光或房地产类型的App中,我们可以通过VR技术动态添加内容来提升用户体验,让人们足不出户享受虚拟场景所带给的惊喜。这里以VR全景图为探索起点,让你不再对VR感到陌生,同时了解VR全景图实现细节。上图:


下面是针对VR全景视图官网案例做一些重要功能的介绍(VR全景图官网传送门):

全景图像规格(英文描述

VR图像可以保存为PNG、JPEG、GIF,Google建议使用JPEG(可以尽可能的节省内存) ;
为了最大化性能和兼容设备,图像尺寸应该是2的倍数(例如,1024、2048或4096);

单个图像纵横比应为2:1(例如4096×2048) ;
立体图像纵横比应为1:1(例如4096×4096)。
如图:




支持平台和设备:PC端(Windows、 macOS、Linux、Unity),客户端(Android、iOS);苹果8以及以上、安卓API 19: Android 4.4 (KitKat)以及以上。

Panowidget————Google提供专门显示VR全景图的依赖库,所在包见下图:


该库中有三个常用类:
VrPanoramaRendererrenderer;//Vr全景图渲染类
VrPanoramaEventListener eventListener;//事件监听类,可以重写4个方法,详见java代码

全景图赋值方式一:
loadImageFromBitmap(Bitmapbitmap,com.google.vr.sdk.widgets.pano.VrPanoramaView.Optionsoptions)
赋值方式二:

将图片转换为byte[],这里以获取assets中图片资源为例,见完整java代码
loadImageFromByteArray(byte[]jpegImageData,com.google.vr.sdk.widgets.pano.VrPanoramaView.Optionsoptions)

可以使用到的Options参数:
public static final int TYPE_MONO = 1;  


     从gif中可以看到图像预先沿着水平轴360度进行渲染,垂直范围根据图像的宽高比来显示,(如果一个1000x250像素的图像,全景图水平将覆盖360x90度,垂直范围是-45至+45度)。
public staticfinal int TYPE_STEREO_OVER_UNDER = 2;


包含两个大小相等的投影全景图垂直叠加。顶部图像被显示给左眼、底部图像被显示给右眼,中间有一个黑色的圆,(如果一个1000x500像素的图像中给出(即1000x250像素/每个眼睛),全景将覆盖360x90度与垂直范围是-45至+45度)。

隐藏界面自带的按钮设置:
       vrPanoramaView.setStereoModeButtonEnabled(false);//隐藏VR模式按钮
       vrPanoramaView.setFullscreenButtonEnabled (false);//隐藏全屏模式按钮
       vrPanoramaView.setInfoButtonEnabled(false);//隐藏信息按钮

VrPanoramaView继承关系图:


完整代码如下:

依赖引入:

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

布局文件参考:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"   >    <com.google.vr.sdk.widgets.pano.VrPanoramaView        android:id="@+id/vr_view"        android:layout_width="match_parent"        android:layout_height="match_parent"       >    </com.google.vr.sdk.widgets.pano.VrPanoramaView></RelativeLayout>

JAVA代码参考:

package com.android.vrpictureimport android.app.Activity;import android.graphics.Bitmap;import android.os.Bundle;import android.widget.Toast;import com.google.vr.sdk.widgets.pano.VrPanoramaEventListener;import com.google.vr.sdk.widgets.pano.VrPanoramaView;import java.io.ByteArrayOutputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;public class MainActivity extends Activity {    /**     * 定义VR 全景视图控件     */    private VrPanoramaView vrPanoramaView;    /**     * assets文件夹下的文件全称     */    private String fileUri = "sea.jpg";    /**     * 创建一个bitmap     */    private    Bitmap bitmap=null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        vrPanoramaView= (VrPanoramaView) findViewById(R.id.vr_view);//加载控件,防止空指针        /**设置加载VR图片的相关设置         **/        VrPanoramaView.Options   options = new VrPanoramaView.Options();        options.inputType = VrPanoramaView.Options.TYPE_MONO ;        vrPanoramaView.setStereoModeButtonEnabled(false);//隐藏全屏模式按钮        vrPanoramaView.setInfoButtonEnabled(false<span lang="EN-US" style="" color:"="">);//隐藏信息按钮/** * 控件赋值 */   vrPanoramaView.loadImageFromByteArray(imageToByte(fileUri),options);        vrPanoramaView.setEventListener(new VrPanoramaEventListener(){            @Override            public void onLoadSuccess() {                super.onLoadSuccess();                Toast.makeText(MainActivity.this, "视图成功加载", Toast.LENGTH_SHORT<span lang="EN-US" style="" color:"="">).show();            }            @Override            public void onLoadError(String errorMessage) {                super.onLoadError(errorMessage);                Toast.makeText(MainActivity.this, "视图加载失败了", Toast.LENGTH_SHORT).show();            }            @Override            public void onClick() {                super.onClick();                Toast.makeText(MainActivity.this, "点击了全景图", Toast.LENGTH_SHORT).show();            }            /**             * 显示模式改变回调             * 1.默认             * 2.全屏模式             * 3.VR观看模式,即横屏分屏模式             * @param newDisplayMode 模式             */            @Override            public void onDisplayModeChanged(int newDisplayMode) {                Toast.makeText(MainActivity.this, "显示模式改变了", Toast.LENGTH_SHORT).show();            }        });    }    //Assets中图片转byte数组    public byte[] imageToByte(String path){        byte[] data = null;        InputStream input = null;        ByteArrayOutputStream output = null;        try {            input = getAssets().open(path);             output = new ByteArrayOutputStream();            byte[] buf = new byte[1024];            int numBytesRead = 0;            while ((numBytesRead = input.read(buf)) != -1) {                output.write(buf, 0, numBytesRead);            }            data = output.toByteArray();        }        catch (FileNotFoundException ex1) {            ex1.printStackTrace();        }        catch (IOException ex1) {            ex1.printStackTrace();        }        finally {            try {                if (input != null) {                    input.close();                }                if (output != null) {                    output.close();                }            } catch (IOException e) {                e.printStackTrace();            }        }        return data;    }    /**     * 获得焦点,恢复3D渲染和跟踪 */    @Override    protected void onResume() {        super.onResume();        if (vrPanoramaView != null) {            vrPanoramaView.resumeRendering();        }    }    //暂停3D渲染和跟踪    @Override    protected void onPause() {        super.onPause();        if (vrPanoramaView != null) {            vrPanoramaView.pauseRendering();        }    }    /**     * 销毁页面,释放资源     */    @Override    protected void onDestroy() {        vrPanoramaView.shutdown();//关闭渲染下并释放相关的内存 一定要在onDestroy()时调用。        /**         * 如果图片不为空,且没有被系统GC,执行回收,释放资源         */        if(bitmap!=null && !bitmap.isRecycled())        {            bitmap.recycle();            System.gc();        }        super.onDestroy();    }}

github上有一个sdk-simplepanowidget——全景图Demo案例,大家可以下载参考,传送门直达,效果图参考如下:


总结:


  • 一般来讲,在清单文件中不进行ConfigChanges配置,屏幕旋转时,Activity的生命周期会重新来过,但在对应的Activity中加入VrPanoramaView控件后,无论怎样旋转屏幕,Activity的生命周期只走一次,同时支持与Activity生命周期联动,亲测。
  • VrPanoramaView内部自动调用陀螺仪传感器,不需要额外进行陀螺仪的配置。
  • VrPanoramaView目前只在水平方向上支持触摸滑动。

欢迎大家留言......


原创粉丝点击