中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用ThinkPHP+Krpano實現全景圖的方法

發布時間:2021-03-03 09:39:28 來源:億速云 閱讀:475 作者:清風 欄目:編程語言

這篇文章主要為大家展示了使用ThinkPHP+Krpano實現全景圖的方法,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶大家一起來研究并學習一下“使用ThinkPHP+Krpano實現全景圖的方法”這篇文章吧。

thinkphp是什么

thinkphp屬于一種免費的開發框架,能夠用于開發前端網頁,最早thinkphp是為了簡化開發而產生的,thinkphp同時也是遵循Apache2協議,最初是從Struts演變過來,也把國外一些好的框架模式進行利用,使用面向對象的開發結構,兼容了很多標簽庫等模式,它能夠更方便和快捷的開發和部署應用,當然不僅僅是企業級應用,任何php應用開發都可以從thinkphp的簡單、兼容和快速的特性中受益。

ThinkPHP3.2+Krpano實現全景圖

為了實現全立體的3D全景圖效果,我們采用了Krpano軟件將普通魚眼圖片渲染為720°全景圖

說明:代碼有過調整,并不能保證運行,主要說明實現思路。
首先下載軟件Krpano全景圖生成軟件,其中包含Linux版本及Win版本以及簡單的使用手冊文件。
其實簡單的使用只需兩步,第一步是將上傳的圖片生成顯示全景圖需要的圖片,第二步是根據全景圖的顯示規則和配置文件將全景圖顯示出來。

上傳圖片并生成全景圖

原理很簡單,將圖片上傳到服務器,然后將服務器的圖片通過Krpano軟件生成全景圖,并將生成后的圖片轉移到統一的目錄中。

在開始上傳圖片前,需要修改Krpano的配置文件Krpano/templates/normal.config如下:

# krpano 1.19

# 引入基本設置
include basicsettings.config
# 全景圖類型 自動 如果可以識別自動,不能識別圖片會詢問處理方法
panotype=autodetect
hfov=360

# 輸出設置
flash=true
html5=true

# convert spherical/cylindrical to cubical
converttocube=true
converttocubelimit=360x45

# multiresolution settings
multires=true
maxsize=8000
maxcubesize=2048

# 輸出圖片路徑
tilepath=%INPUTPATH%/pano/%BASENAME%.tbs-pano/3d-pano-[c].jpg

# 輸出預覽圖圖片設置
preview=true
graypreview=false
previewsmooth=25
previewpath=%INPUTPATH%/pano/%BASENAME%.tbs-pano/3d-pano-preview.jpg

# 輸出縮略圖圖片設置
makethumb=true
thumbsize=240
thumbpath=%INPUTPATH%/pano/%BASENAME%.tbs-pano/3d-pano-thumb.jpg

上傳接口代碼如下:

public function upload_3d_pic()
{
    $file = $_FILES["imgUpload"];
    $u_name =$file['name'];
    $u_temp_name =$file['tmp_name'];
    $u_size =$file['size'];
    
    // 生成 一個隨機字符串
    $str = null;
    $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123tbs456789abcdefghijklmnopqrstuvwxyz";
    $max = strlen($strPol)-1;
    for($i=0;$i<$length;$i++){
        $str.=$strPol[rand(0,$max)];//rand($min,$max)生成介于min和max兩個數之間的一個隨機整數
    }
    
    //$md5Code 會做為文件夾的名字 跟文件的名字,要保持唯一性
    $md5Code =md5_16bit(hash("sha256",$u_name.time().$rand_char)).$str;
    $datePath =date("Y-m-d",time());

    $root_path ='./upload_3dpic/';
    $url_path ='/upload_3dpic/';    //外部訪問url
    $f_up_to_path =$root_path .'/'. $datePath.'/'.$md5Code;
    if(!file_exists($f_up_to_path)){
        mkdir($f_up_to_path, 0777, true);
    }
    $type = strtolower(substr($u_name, strrpos($u_name, '.') + 1));
    $img_file_name =$md5Code."." . $type;

    $saveFileName = $f_up_to_path."." . $type;
    $true_img_url =$url_path . $datePath.'/'.$md5Code."." . $type; //外部訪問鏈接
    if (!move_uploaded_file($u_temp_name, $saveFileName)) {
        $this->ajaxReturn(array("error_code"=>250,"msg"=>"圖片上傳失敗,請稍后重試!","return"=>"move pic fail>>temp_name=".$u_temp_name.">>save file name=".$saveFileName));
    } else {
        @rmdir($f_up_to_path);
    }

    //判斷文件是否存在
    if(file_exists($saveFileName)){
        //如果存在 則生成 全景圖
        $this->create_pano_pic($saveFileName);
        // 如果 此時沒有生成圖片 需要刪除上傳圖片并報錯 平面圖可能生成不了圖片
        $dirName = dirname($saveFileName) . '/pano' . '/' . $md5Code . '.tbs-pano';
        if ( !file_exists($dirName) ) {
            unlink($saveFileName); // 刪除文件
            $this->ajaxReturn(array('error_code'=>250,"msg"=>"上傳圖片不能生成全景圖"));
        }

        //移動全景圖到指定的目錄 圖片在哪里全景圖將會生成在那個目錄
        $mvres = $this->mv_to_pano_path($saveFileName,$img_file_name);
        if ( $mvres === false ) {
            $this->ajaxReturn(array('error_code'=>250,"msg"=>"移動文件失敗"));
        }
    }else{

        $this->ajaxReturn(array('error_code'=>250,"msg"=>"img not exists!",'img_url'=>$true_img_url));
    }
    // 移動后的縮略圖路徑
    $thumb_url = $url_path . 'TreeDPic/' . $md5Code . '/pano/' . $md5Code . '.tbs-pano/3d-pano-thumb.jpg';
    $this->ajaxReturn(array(
        'error_code'=>0,
        'msg'=>"sucess",
        'img_url'=>$true_img_url,
        "pano_name"=>$md5Code,
        'thumb_url'=>$thumb_url)
     );
}

/***
* @param string $img_path
* @return string
* 將當前傳入的圖片 渲染成為全景圖
*/
private function create_pano_pic($img_path="")
{
    if(empty($img_path)){
        return $img_path;
    }
    if(!file_exists($img_path)){
        return "圖片不存在!";
    }
    //軟件注冊碼
    $r_code ="Krpano的注冊碼";

    $pano_path=C("KRPANO_PATH"); //krpano 路徑 自己配置

    $pano_tools ="krpanotools";

    //krpano 生成圖片的命令
    $dealFlat = ''; // 處理 非球面圖
    if(PHP_OS == 'WINNT'){
        $pano_path=$pano_path."Win";
        $pano_tools ="krpanotools32.exe";
    } else {
        // 上傳平面圖時 直接跳過圖片生成 否則會一直等待
        $dealFlat = 'echo -e "0\n" | '; 
    }
    
    $kr_command = $dealFlat . $pano_path . "/".$pano_tools." makepano -config=" . $pano_path . "/templates/normal.config ";

    try{
        //在生成圖片之前 先注冊一下碼,要不生成的全景圖會有水印
        exec( $pano_path . '/'.$pano_tools.' register ' .$r_code);
        $kr_command =$kr_command.$img_path;
        //執行生成圖片命令
        exec($kr_command, $log, $status);
    } catch (\Exception $e){
        $this->ajaxCallMsg(250,$e->getMessage());
    }
    return true;
}

/**
* @param $pano_img_path
* @return string
* 全景圖生成后再調用這個方法,把全景圖移到對應的目錄供 xml 文件獲取內容
*/
private function mv_to_pano_path($pano_img_path,$img_name){
    $ig_name =explode(".",$img_name)[0];
    $root_path = './upload_3dpic/';

    if(!file_exists($pano_img_path) ||empty($pano_img_path)){
        $this->up_error_log($pano_img_path.'》》圖片路徑文件不存在');
        return '';
    }

    $now_path =dirname($pano_img_path);//獲取當前文件目錄

    if ($dh = @opendir($now_path)){
        //打開目錄
        while (($file = readdir($dh)) !== false){
            //循環獲取目錄的 文件
            if (($file != '.') && ($file != '..')) {
                //如果文件不是.. 或 . 則就是真實的文件
                if($file=="pano"){
                    //全景圖切片目錄
                    $t_d_path =$root_path .'TreeDPic/'. $ig_name;

                    if(!file_exists($t_d_path)){
                        //不存在就創建
                        @mkdir($t_d_path, 0777, true);
                    }
                    if(file_exists($t_d_path.'/'.$file)){
                        //判斷是否已經存在 當前名字的  全景圖 文件
                        return false;
                    }else{
                        //否則就 把 當前上傳的生成 的全景文件切片,移動到指定的目錄
                        rename($now_path.'/'.$file,$t_d_path.'/'.$file);
                    }
                }else if ($file !==$img_name){
                    //刪除不是 原圖片的文件
                    if(is_dir($file)){
                        $this->deleteDir($now_path.'/'.$file);
                    }else{
                        @unlink($now_path.'/'.$file);
                    }
                }else{
                    return false;
                }
            }
        }
        closedir($dh);
    }else{
        return false;
    }

}
/**
* @param $dir
* @return bool
* 刪除文件夾及文件
*/
private  function deleteDir($dir)
{
    if (!$handle = @opendir($dir)) {
        return false;
    }
    while (false !== ($file = readdir($handle))) {
        if ($file !== "." && $file !== "..") {       //排除當前目錄與父級目錄
            $file = $dir . '/' . $file;
            if (is_dir($file)) {
                $this->deleteDir($file);
            } else {
                @unlink($file);
            }
        }
    }
    @rmdir($dir);
}

此時,我們已經可以通過上傳接口上傳圖片并通過Krpano渲染圖片為全景圖了。

顯示全景圖

要將圖片顯示出來,我們必須按照Krpano規則生成必須的xml配置文件。

我們將根據上傳圖片是生成的唯一碼作為依據生成全景圖。

// 解析XML文件
public function panorama_xml(){
    $code =I("code");
    $cutNum =intval(I("cutNum"));
    $url_path = '/upload_3dpic/';   
    // 切割模式分為 6圖 和 12圖
    if(!in_array($cutNum,array(6,12))){
        $this->error();
    }
    $this->echoSixXml($url_path,$code);
}

private function echoSixXml($url_path,$code=""){
    echo "<krpano  version=\"1.19\" title=\"Virtual Tour\">
            <!-- the skin -->
            <!-- <include url=\"/3dpic/pano/sixDefaultXml/\" />--> 

            <!-- 視圖設置 <view hlookat=\"0\" vlookat=\"0\" maxpixelzoom=\"1.0\" fovmax=\"150\" limitview=\"auto\" /> -->
            

            <skin_settings maps=\"false\"
                   maps_type=\"google\"
                   maps_bing_api_key=\"\"
                   maps_google_api_key=\"\"
                   maps_zoombuttons=\"false\"
                   gyro=\"true\"
                   webvr=\"true\"
                   webvr_gyro_keeplookingdirection=\"false\"
                   webvr_prev_next_hotspots=\"true\"
                   littleplanetintro=\"false\"
                   title=\"true\"
                   thumbs=\"true\"
                   thumbs_width=\"120\" thumbs_height=\"80\" thumbs_padding=\"10\" thumbs_crop=\"0|40|240|160\"
                   thumbs_opened=\"false\"
                   thumbs_text=\"false\"
                   thumbs_dragging=\"true\"
                   thumbs_onhoverscrolling=\"false\"
                   thumbs_scrollbuttons=\"false\"
                   thumbs_scrollindicator=\"false\"
                   thumbs_loop=\"false\"
                   tooltips_buttons=\"false\"
                   tooltips_thumbs=\"false\"
                   tooltips_hotspots=\"false\"
                   tooltips_mapspots=\"false\"
                   deeplinking=\"false\"
                   loadscene_flags=\"MERGE\"
                   loadscene_blend=\"OPENBLEND(0.5, 0.0, 0.75, 0.05, linear)\"
                   loadscene_blend_prev=\"SLIDEBLEND(0.5, 180, 0.75, linear)\"
                   loadscene_blend_next=\"SLIDEBLEND(0.5,   0, 0.75, linear)\"
                   loadingtext=\"loading...\"
                   layout_width=\"100%\"
                   layout_maxwidth=\"814\"
                   controlbar_width=\"-24\"
                   controlbar_height=\"40\"
                   controlbar_offset=\"20\"
                   controlbar_offset_closed=\"-40\"
                   controlbar_overlap.no-fractionalscaling=\"10\"
                   controlbar_overlap.fractionalscaling=\"0\"
                   design_skin_images=\"vtourskin.png\"
                   design_bgcolor=\"0x2D3E50\"
                   design_bgalpha=\"0.8\"
                   design_bgborder=\"0\"
                   design_bgroundedge=\"1\"
                   design_bgshadow=\"0 4 10 0x000000 0.3\"
                   design_thumbborder_bgborder=\"3 0xFFFFFF 1.0\"
                   design_thumbborder_padding=\"2\"
                   design_thumbborder_bgroundedge=\"0\"
                   design_text_css=\"color:#FFFFFF; font-family:Arial;\"
                   design_text_shadow=\"1\"
                   />
            
    
            <scene name=\"{$code}\" title=\"{$code}\" onstart=\"\" thumburl=\"{$url_path}TreeDPic/{$code}/pano/{$code}.tbs-pano/3d-pano-thumb.jpg\" lat=\"\" lng=\"\" heading=\"\">
        
                <view hlookat=\"0.0\" vlookat=\"0.0\" fovtype=\"MFOV\" fov=\"120\" maxpixelzoom=\"2.0\" fovmin=\"70\" fovmax=\"140\" limitview=\"range\" vlookatmin=\"-58.156\" vlookatmax=\"58.156\" />
        
                <preview url=\"{$url_path}TreeDPic/{$code}/pano/{$code}.tbs-pano/3d-pano-preview.jpg\" />
        
                <image type=\"CUBE\" multires=\"true\" tilesize=\"512\">
                    <cube url=\"{$url_path}TreeDPic/{$code}/pano/{$code}.tbs-pano/3d-pano-%s.jpg\" />
                </image>
            </scene>
            <!--<preview url=\"{$url_path}TreeDPic/{$code}/pano/{$code}.tbs-pano/preview.jpg\" />-->

            <image>
                <cube url=\"{$url_path}TreeDPic/{$code}/pano/{$code}.tbs-pano/3d-pano-%s.jpg\" />
            </image>

        </krpano>";
    }

其中scene并不會當前的效果圖渲染出來,而是在我們在多張全景圖之間進行選擇的時候通過DOM.call("toggle_item_hotspots();");自動觸發。

設置顯示頁面的路由及方法:

public function panorama(){

    //先 獲取id (md5值)
    $code =trim(I("code"));
    //圖片切割方式  6圖(采集的是6圖) 和12圖(比較復雜建議生成圖片 用6圖 配置切割)
    $cutNum =intval(I("cutNum"));
    $this->assign("codeVal",$code);
    $this->assign("cutNum",$cutNum);

    $this->display();
}

相應的視圖文件中:

<!DOCTYPE html>
<html>
<head>
    <title>土撥鼠全景漫游圖 - {$pageData.title}</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, viewport-fit=cover" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    <meta http-equiv="x-ua-compatible" content="IE=edge" />
    <link rel="stylesheet" href="{$Think.TBS_STATIC}/common/css/new_base.css?v=1560493706" />
    <link rel="stylesheet" href="/res/impression/vtour/pc/krpano.css"/>
    <style>
        @-ms-viewport { width:device-width; }
        @media only screen and (min-device-width:800px) { html { overflow:hidden; } }
        html { height:100%; }
        body { height:100%; overflow:hidden; margin:0; padding:0; font-family:Arial, Helvetica, sans-serif; font-size:16px; color:#FFFFFF; background-color:#000000; }
        .loading{
            /* display: none; */
            width: 100%;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 3;
            background-color: #fff;
            color:#333;
            z-index: 100;
        }
        .loadingimg {
            width: 184px;
            height: 108px;
            position: absolute;
            top: 50%;
            left: 50%;
            -webkit-transform: translateX(-50%) translateY(-50%);
            -moz-transform: translateX(-50%) translateY(-50%);
            -ms-transform: translateX(-50%) translateY(-50%);
            transform: translateX(-50%) translateY(-50%);
            text-align: center;
        }
        .loadingimg img {
            width: 100%;
            height: 100%;
        }
        .poiner {
            display: inline-block;
            width: 16px;
            vertical-align: bottom;
            overflow: hidden;
            /* animation: poiner 3s infinite step-start; */
        }
    </style>
</head>
<body>
<script src="vtour/tour.js"></script>
    <p class="loading">
        <p class="loadingimg">
            <img src="{$Think.TBS_STATIC}/impression/vtour/img/loading.png">
            <p>加載中</p>
        </p>
    </p>
    <p id="pano" style="width:100%;height:100%;">
    </p>
</body>
    <script>
        // var krpano = null;
        embedpano({
            swf: "{$Think.TBS_STATIC}/impression/vtour/tour.swf?v={$Think.CDNTIME}",
            xml: "/3dpic/panoxml/{$cutNum}_{$codeVal}",
            target: "pano",
            html5: "auto",
            mobilescale: 1.0,
            passQueryParameters: true,
        });
    </script>
    <script type="text/javascript" src="vtour/krpano.js"></script>
</html>

修改相應的靜態資源文件的路徑以適應自己的項目,此時已經可以看到我們的全景圖了。

以上就是關于“使用ThinkPHP+Krpano實現全景圖的方法”的內容,如果改文章對你有所幫助并覺得寫得不錯,勞請分享給你的好友一起學習新知識,若想了解更多相關知識內容,請多多關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

达拉特旗| 宁河县| 怀柔区| 永仁县| 凤山市| 巴里| 会同县| 历史| 石阡县| 南通市| 恭城| 莱西市| 卢龙县| 永平县| 宜兴市| 乃东县| 林西县| 汶川县| 西吉县| 晋城| 青冈县| 东安县| 京山县| 凯里市| 庄浪县| 陇南市| 沐川县| 大方县| 汉川市| 依安县| 富裕县| 青浦区| 柳林县| 昆明市| 广水市| 莆田市| 大连市| 琼海市| 栾城县| 双流县| 化隆|