您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了使用ThinkPHP+Krpano實(shí)現(xiàn)全景圖的方法,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶大家一起來研究并學(xué)習(xí)一下“使用ThinkPHP+Krpano實(shí)現(xiàn)全景圖的方法”這篇文章吧。
thinkphp屬于一種免費(fèi)的開發(fā)框架,能夠用于開發(fā)前端網(wǎng)頁,最早thinkphp是為了簡化開發(fā)而產(chǎn)生的,thinkphp同時也是遵循Apache2協(xié)議,最初是從Struts演變過來,也把國外一些好的框架模式進(jìn)行利用,使用面向?qū)ο蟮拈_發(fā)結(jié)構(gòu),兼容了很多標(biāo)簽庫等模式,它能夠更方便和快捷的開發(fā)和部署應(yīng)用,當(dāng)然不僅僅是企業(yè)級應(yīng)用,任何php應(yīng)用開發(fā)都可以從thinkphp的簡單、兼容和快速的特性中受益。
ThinkPHP3.2+Krpano實(shí)現(xiàn)全景圖
為了實(shí)現(xiàn)全立體的3D全景圖效果,我們采用了Krpano
軟件將普通魚眼圖片渲染為720°全景圖
說明:代碼有過調(diào)整,并不能保證運(yùn)行,主要說明實(shí)現(xiàn)思路。
首先下載軟件Krpano全景圖生成軟件,其中包含Linux
版本及Win
版本以及簡單的使用手冊文件。
其實(shí)簡單的使用只需兩步,第一步是將上傳的圖片生成顯示全景圖需要的圖片,第二步是根據(jù)全景圖的顯示規(guī)則和配置文件將全景圖顯示出來。
上傳圖片并生成全景圖
原理很簡單,將圖片上傳到服務(wù)器,然后將服務(wù)器的圖片通過Krpano
軟件生成全景圖,并將生成后的圖片轉(zhuǎn)移到統(tǒng)一的目錄中。
在開始上傳圖片前,需要修改Krpano
的配置文件Krpano/templates/normal.config
如下:
# krpano 1.19 # 引入基本設(shè)置 include basicsettings.config # 全景圖類型 自動 如果可以識別自動,不能識別圖片會詢問處理方法 panotype=autodetect hfov=360 # 輸出設(shè)置 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 # 輸出預(yù)覽圖圖片設(shè)置 preview=true graypreview=false previewsmooth=25 previewpath=%INPUTPATH%/pano/%BASENAME%.tbs-pano/3d-pano-preview.jpg # 輸出縮略圖圖片設(shè)置 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']; // 生成 一個隨機(jī)字符串 $str = null; $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123tbs456789abcdefghijklmnopqrstuvwxyz"; $max = strlen($strPol)-1; for($i=0;$i<$length;$i++){ $str.=$strPol[rand(0,$max)];//rand($min,$max)生成介于min和max兩個數(shù)之間的一個隨機(jī)整數(shù) } //$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 * 將當(dāng)前傳入的圖片 渲染成為全景圖 */ 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; //執(zhí)行生成圖片命令 exec($kr_command, $log, $status); } catch (\Exception $e){ $this->ajaxCallMsg(250,$e->getMessage()); } return true; } /** * @param $pano_img_path * @return string * 全景圖生成后再調(diào)用這個方法,把全景圖移到對應(yīng)的目錄供 xml 文件獲取內(nèi)容 */ 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);//獲取當(dāng)前文件目錄 if ($dh = @opendir($now_path)){ //打開目錄 while (($file = readdir($dh)) !== false){ //循環(huán)獲取目錄的 文件 if (($file != '.') && ($file != '..')) { //如果文件不是.. 或 . 則就是真實(shí)的文件 if($file=="pano"){ //全景圖切片目錄 $t_d_path =$root_path .'TreeDPic/'. $ig_name; if(!file_exists($t_d_path)){ //不存在就創(chuàng)建 @mkdir($t_d_path, 0777, true); } if(file_exists($t_d_path.'/'.$file)){ //判斷是否已經(jīng)存在 當(dāng)前名字的 全景圖 文件 return false; }else{ //否則就 把 當(dāng)前上傳的生成 的全景文件切片,移動到指定的目錄 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 !== "..") { //排除當(dāng)前目錄與父級目錄 $file = $dir . '/' . $file; if (is_dir($file)) { $this->deleteDir($file); } else { @unlink($file); } } } @rmdir($dir); }
此時,我們已經(jīng)可以通過上傳接口上傳圖片并通過Krpano
渲染圖片為全景圖了。
要將圖片顯示出來,我們必須按照Krpano
規(guī)則生成必須的xml
配置文件。
我們將根據(jù)上傳圖片是生成的唯一碼作為依據(jù)生成全景圖。
// 解析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/\" />--> <!-- 視圖設(shè)置 <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
并不會當(dāng)前的效果圖渲染出來,而是在我們在多張全景圖之間進(jìn)行選擇的時候通過DOM.call("toggle_item_hotspots();");
自動觸發(fā)。
設(shè)置顯示頁面的路由及方法:
public function panorama(){ //先 獲取id (md5值) $code =trim(I("code")); //圖片切割方式 6圖(采集的是6圖) 和12圖(比較復(fù)雜建議生成圖片 用6圖 配置切割) $cutNum =intval(I("cutNum")); $this->assign("codeVal",$code); $this->assign("cutNum",$cutNum); $this->display(); }
相應(yīng)的視圖文件中:
<!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>
修改相應(yīng)的靜態(tài)資源文件的路徑以適應(yīng)自己的項(xiàng)目,此時已經(jīng)可以看到我們的全景圖了。
以上就是關(guān)于“使用ThinkPHP+Krpano實(shí)現(xiàn)全景圖的方法”的內(nèi)容,如果改文章對你有所幫助并覺得寫得不錯,勞請分享給你的好友一起學(xué)習(xí)新知識,若想了解更多相關(guān)知識內(nèi)容,請多多關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。