二、VR全景图显示器开发 ---- Android VR视频/Google VR for Android /VR Pano/VR Video
原文地址:
http://blog.csdn.net/qq_24889075/article/details/52128463
http://www.jianshu.com/p/104251a3153d
这篇看下SimpleVrPanorama这个栗子
SimpleVrPanorama
其实这篇应该写SimpleVrPanorama和simplevideowidget 两个,但是由于篇幅过长就分开写了
演示
用AS录的没有触摸点显示,先凑合看吧
预览图观看
介绍
官方在这里介绍了VR view 、支持平台等。我挑几个相对重要的介绍一下:
1、图像规格
VR查看图像可以保存为PNG,JPEG或GIF。Google建议使用JPEG改进压缩。 为了获得最大的兼容性和性能,图像尺寸应该是2的倍数(例如,2048或4096)。单个图像应为2:1纵横比(例如4096×2048)。 立体图像应为1:1纵横比(例如4096×4096)。
如图:
2、 视频规格
VR view视频应该被存储为H264编码的mp4文件。单个视频应是2:1纵横比。立体视频应是1:1纵横比。一些较旧的设备不能解码的视频最大不能超过超过1080(1920×1080)。最大的兼容性和质量是头等大事,Google建议用户同时提供平面视觉1920x1080的视频和2048×2048处以上的立体视频。
3、如何录制VR视频
生活中拍摄:
360度拍摄的照片和视频越来越方便和实惠。 VR视图可以使用由支持上述equirect-全景格式的任何摄像机产生的图像。对于有兴趣在快速入门用户来说,我们最喜欢的解决方案如下:
Cardboard Camera App:这个免费的Android应用程序,允许用户快速捕捉立体图像360。
Ricoh Theta:一个非常流行的,用于捕获单360度的图像和视频相对廉价的解决方案。
CG(计算机动画)拍摄:
遥感影像数据的VR观点并没有从现实世界限于捕获。 CGI软件可以生成360图像和视频,一切从建筑到演练预演的电影。我们的一些最流行的捕获解决方案的列举如下:
360 Panorama Capture for Unity:一个免费的,易于使用的360捕获了Unity插件。
Unreal(虚幻):UE4的最新版本内置了360捕获解决方案。
Domemaster3D for Maya :从玛雅捕获单声道和立体声图像360免费的解决方案。
Renderman:开源库,用于捕捉360的内容。
Rendering Omnidirectional Stereo Content:一个有兴趣的人都在书写自己360捕获解决方案白皮书。
Android平台
在这里官方有这Android平台的详细介绍,主要内容如下:
有这表明在官方SDK中的VR View 功能的两个示例应用程序:simplepanowidget和simplevideowidget。这两个样品的是显示分别使用VrPanoramaView和VrVideoView嵌入全景图像和视频。
允许用户通过旋转他们的电话,看全景的不同部分。
simplevideowidget示例还允许用户暂停(点击 VR View就暂停了。 VR View也就是视频那个区域),可以使用进度条改变进度。允许用户更改模式,分别是全屏模式和纸板模式。
全屏模式:
纸板模式:
代码分析
(^_^ 为了方便学习与理解,基于官方Demo的代码进行了修改 )
前言
这个栗子中需要注意几个知识点:
VrPanoramaView //Google提供给我们现实全景图片的View Options //VrPanoramaView 所需的设置 VrPanoramaEventListener//为 VrPanoramaView 设置监听 loadImageFromBitmap//加载图片的主要方法
AndroidManifest
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <application android:label="SimpleVrPanoramaActivity" android:largeHeap="true" android:theme="@android:style/Theme.Holo.Light"> <activity android:name=".SimpleVrPanoramaActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> <category android:name="com.google.intent.category.CARDBOARD" /> intent-filter> activity> application>
build.gradle
上一篇文章有介绍到这些库
dependencies { compile project(':libraries-common') compile project(':libraries-commonwidget') compile project(':libraries-panowidget')}
布局文件
只有一个主要标签
<com.google.vr.sdk.widgets.pano.VrPanoramaView android:id="@+id/pano_view" android:layout_width="match_parent" android:layout_height="250dip" android:layout_margin="5dip" android:scrollbars="@null"/>
SimpleVrPanoramaActivity
正题来了~
看下我为了本次学习更改过的代码:
不了解Pair的请看这里: http://blog.csdn.net/qq_24889075/article/details/52127398
package com.google.vr.sdk.samples.simplepanowidget;import android.app.Activity;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.os.Bundle;import android.util.Log;import android.util.Pair;import com.google.vr.sdk.widgets.pano.VrPanoramaEventListener;import com.google.vr.sdk.widgets.pano.VrPanoramaView;import com.google.vr.sdk.widgets.pano.VrPanoramaView.Options;import java.io.IOException;import java.io.InputStream;public class SimpleVrPanoramaActivity extends Activity { private static final String TAG = "VrPanorama"; private VrPanoramaView panoWidgetView;//上面说的Google提供给我们现实全景图片的View private String fileUri = "first.jpg";//assets文件夹下的文件名 private Options panoOptions = new Options();//VrPanoramaView需要的设置 private ImageLoaderTask backgroundImageLoaderTask;//异步加载图片 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_layout);//布局上面贴了 panoWidgetView = (VrPanoramaView) findViewById(R.id.pano_view);//初始化VrPanoramaView panoWidgetView.setEventListener(new ActivityEventListener());//为VrPanoramaView添加监听 //如果有任务在执行则停止它 if (backgroundImageLoaderTask != null) { backgroundImageLoaderTask.cancel(true); } //设置inputType 为TYPE_STEREO_OVER_UNDER. 在后面会介绍TYPE_STEREO_OVER_UNDER的,暂时当做一个图片的显示类型就行 panoOptions.inputType = Options.TYPE_STEREO_OVER_UNDER; //创建一个任务 backgroundImageLoaderTask = new ImageLoaderTask(); //执行任务。将图片名(根据项目实际情况传吧)和设置传入 backgroundImageLoaderTask.execute(Pair.create(fileUri, panoOptions)); } //异步任务 class ImageLoaderTask extends AsyncTask, Void, Boolean> { @Override protected Boolean doInBackground(Pair... fileInformation) {//真正写项目根据情况添加条件判断吧 InputStream istr = null; try { istr = getAssets().open(fileInformation[0].first);//获取图片的输入流 } catch (IOException e) { Log.e(TAG, "Could not decode default bitmap: " + e); return false; } Bitmap bitmap = BitmapFactory.decodeStream(istr);//创建bitmap panoWidgetView.loadImageFromBitmap(bitmap, fileInformation[0].second);//参数一为图片的bitmap,参数二为 VrPanoramaView 所需要的设置 try { istr.close();//关闭InputStream } catch (IOException e) { Log.e(TAG, "Could not close input stream: " + e); } return true; } } private class ActivityEventListener extends VrPanoramaEventListener { @Override public void onLoadSuccess() {//图片加载成功 Log.e(TAG, "onLoadSuccess"); } @Override public void onLoadError(String errorMessage) {//图片加载失败 Log.e(TAG, "Error loading pano: " + errorMessage); } @Override public void onClick() {//当我们点击了VrPanoramaView 时候出发 super.onClick(); Log.e(TAG, "onClick"); } @Override public void onDisplayModeChanged(int newDisplayMode) {//改变显示模式时候出发(全屏模式和纸板模式) super.onDisplayModeChanged(newDisplayMode); Log.e(TAG, "onDisplayModeChanged"); } } @Override protected void onPause() { panoWidgetView.pauseRendering();//暂停3D渲染和跟踪 super.onPause(); } @Override protected void onResume() { super.onResume(); panoWidgetView.resumeRendering();//恢复3D渲染和跟踪 } @Override protected void onDestroy() { panoWidgetView.shutdown();//关闭渲染下并释放相关的内存 if (backgroundImageLoaderTask != null) { backgroundImageLoaderTask.cancel(true);//停止异步任务 } super.onDestroy(); }}
看完了有木有感觉炒鸡简单啊?现在你已经掌握了如何使用 VrPanoramaView 了吧。
用 VrPanoramaView 的确简单,但是局限性特别大,后面有机会 会详细说的。
再介绍下代码中没提到的两个方法:
setFullscreenButtonEnabled (false); //隐藏全屏模式按钮setVrModeButtonEnabled(false); //隐藏VR模式按钮
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像素的图像中给出(即1000x250像素每个眼睛),全景将覆盖360x90度与垂直范围是-45至+45度。
我要显示的图片是下图这样的,所以就要设置为 ‘TYPE_STEREO_OVER_UNDER’
那么什么样的图片设置为 ‘TYPE_MONO’ 呢?
请看:
不知道有没有眼神好的同学发现这个问题:TYPE_STEREO_OVER_UNDER类型的图片每次切换模式时候 图片中间都会有一条垂直于水平线的分割线(很浅 很浅 然后逐渐消失),TYPE_MONO 就没有 ^_^
Options类中的代码也十分简单
public static class Options { private static final int TYPE_START_MARKER = 0;//起始标记 public static final int TYPE_MONO = 1; public static final int TYPE_STEREO_OVER_UNDER = 2; private static final int TYPE_END_MARKER = 3;//结束标记 public int inputType = 1;//默认为一 public Options() { } void validate() { if(this.inputType <= 0 || this.inputType >= 3) {//标记错误处理 String var10000 = VrPanoramaView.TAG; int var1 = this.inputType; Log.e(var10000, (new StringBuilder(38)).append("Invalid Options.inputType: ").append(var1).toString()); this.inputType = 1; } } }
调皮的你如果在loadImageFromBitmap(bitmap,options)方法中 将options不小心设置为null了,也没关系。我在源码中我发现下面的代码,感觉挺温馨的
public void loadImageFromBitmap(Bitmap bitmap, VrPanoramaView.Options options) { //有木有那里暖暖的 ^_^ if(options == null) { options = new VrPanoramaView.Options(); } else { options.validate(); } //重点不在这里 可以无视它 this.renderer.loadImageFromBitmap(bitmap, options, this.eventListener); }
至此com.google.vr.sdk.widgets.common包、com.google.vr.sdk.widgets.pano包和com.google.vr.sdk.widgets.video包(代码下一篇介绍) 的主要内容都介绍完了,总结下吧
总结
总结下如何在Android设备上用Google的SDK做一款全景图的显示器(播放器?查看器?… 不知道叫什么合适):
- 导入google的库
- 在相应的布局文件中引入控件 com.google.vr.sdk.widgets.pano.VrPanoramaView
- 初始化控件
- 为VrPanoramaView设置options
- 找到图片的Bitmap
- 调用VrPanoramaView的loadImageFromBitmap方法
- 在onPause、onResume、onDestroy中做出相应处理
原文地址:
http://blog.csdn.net/qq_24889075/article/details/52128463
http://www.jianshu.com/p/104251a3153d
更多相关文章
- andorid 将布局文件(layout)转换为图片(Bitmap)简单使用详解
- MediaRecorder音视频框架
- Android画各种圆,饼图,环图,圆形图片
- 搭建WebRTC Android视频demo
- Android视频文件格式解析相关分析
- android TextView 结合SpannableString对部分内容设置颜色、字体
- android 图片压缩的几种方法
- 2011.10.14——— android 仿照微信的图片展示功能 之 基本功能