Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 二、VR全景圖 ---- Android VR視頻/Google VR for Android /VR Pano/VR Video

二、VR全景圖 ---- Android VR視頻/Google VR for Android /VR Pano/VR Video

編輯:關於Android編程

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(192??0×1080)。最大的兼容性和質量是頭等大事,Google建議用戶同時提供平面視覺1920x1080的視頻和2048×2048處以上的立體視頻。  

3、如何錄制VR視頻

生活中拍攝:

360度拍攝的照片和視頻越來越方便和實惠。 VR視圖可以使用由支持上述equirect-全景格式的任何攝像機產生的圖像。對於有興趣在快速入門用戶來說,我們最喜歡的解決方案如下:

Cardboard Camera App:這個免費的Andr??oid應用程序,允許用戶快速捕捉立體圖像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 功能的兩個示例應用程序:simplepanowidgetsimplevideowidget。這兩個樣品的是顯示分別使用VrPanoramaViewVrVideoView嵌入全景圖像和視頻。
這裡寫圖片描述
允許用戶通過旋轉他們的電話,看全景的不同部分。
simplevideowidget示例還允許用戶暫停(點擊 VR View就暫停了。 VR View也就是視頻那個區域),可以使用進度條改變進度。允許用戶更改模式,分別是全屏模式紙板模式
<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjxjb2RlPjxjb2RlPsirxsHEo8q9o7o8YnIgLz4NCjxpbWcgYWx0PQ=="這裡寫圖片描述" src="/uploadfile/Collfiles/20160806/20160806091707947.jpg" title="\" />

紙板模式:
這裡寫圖片描述


代碼分析

(^_^ 為了方便學習與理解,基於官方Demo的代碼進行了修改 )

前言

這個栗子中需要注意幾個知識點:

 VrPanoramaView //Google提供給我們現實全景圖片的View
 Options //VrPanoramaView 所需的設置
 VrPanoramaEventListener//為 VrPanoramaView 設置監聽
 loadImageFromBitmap//加載圖片的主要方法

AndroidManifest

    
    
    

    
        
        
            
                
                
                
            
        
    

build.gradle

上一篇文章有介紹到這些庫

dependencies {
    compile project(':libraries-common')
    compile project(':libraries-commonwidget')
    compile project(':libraries-panowidget')
}

布局文件

只有一個主要標簽

  

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中做出相應處理
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved