教你用ThinkPHP+Krpano实现全景图

下面由thinkphp教程栏目给大家介绍tthinkphp3.2+krpano实现全景图,希望对需要的朋友有所帮助!

ThinkPHP3.2+Krpano实现全景图

thinkphp

上传图片并生成全景图

原理很简单,将图片上传到服务器,然后将服务器的图片通过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

上传接口代码如下:

立即学习PHP免费学习笔记(深入)”;

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 "0n" | ';      }          $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">             @@##@@             <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实现全景图

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享