教你用ThinkPHP+Krpano实现全景图
2022-11-24 11:02:51
212
{{single.collect_count}}
下面由thinkphp教程栏目给大家介绍tThinkPHP3.2+Krpano实现全景图,希望对需要的朋友有所帮助!

ThinkPHP3.2+Krpano实现全景图

为了实现全立体的3D全景图效果,我们采用了Krpano软件将普通鱼眼图片渲染为720°全景图

说明:代码有过调整,并不能保证运行,主要说明实现思路。
首先下载软件Krpano全景图生成软件,其中包含Linux版本及Win版本以及简单的使用手册文件。
其实简单的使用只需两步,第一步是将上传的图片生成显示全景图需要的图片,第二步是根据全景图的显示规则和配置文件将全景图显示出来。

【相关推荐:最新的10个thinkphp视频教程

上传图片并生成全景图

原理很简单,将图片上传到服务器,然后将服务器的图片通过Krpano软件生成全景图,并将生成后的图片转移到统一的目录中。

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

# krpano 1.19# 引入基本设置include basicsettings.config# 全景图类型 自动 如果可以识别自动,不能识别图片会询问处理方法panotype=autodetecthfov=360# 输出设置flash=truehtml5=true# convert spherical/cylindrical to cubicalconverttocube=trueconverttocubelimit=360x45# multiresolution settingsmultires=truemaxsize=8000maxcubesize=2048# 输出图片路径tilepath=%INPUTPATH%/pano/%BASENAME%.tbs-pano/3d-pano-[c].jpg# 输出预览图图片设置preview=truegraypreview=falsepreviewsmooth=25previewpath=%INPUTPATH%/pano/%BASENAME%.tbs-pano/3d-pano-preview.jpg# 输出缩略图图片设置makethumb=truethumbsize=240thumbpath=%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* 删除文件夹及文件*/privatefunction 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 "<krpanoversion=\"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>
登录后复制

修改相应的静态资源文件的路径以适应自己的项目,此时已经可以看到我们的全景图了。

php入门到就业线上直播课:立即学习
全程直播 + 实战授课 + 边学 + 边练 + 边辅导

以上就是教你用ThinkPHP+Krpano实现全景图的详细内容,更多请关注php中文网其它相关文章!

回帖
全部回帖({{commentCount}})
{{item.user.nickname}} {{item.user.group_title}} {{item.friend_time}}
{{item.content}}
{{item.comment_content_show ? '取消' : '回复'}} 删除
回帖
{{reply.user.nickname}} {{reply.user.group_title}} {{reply.friend_time}}
{{reply.content}}
{{reply.comment_content_show ? '取消' : '回复'}} 删除
回帖
收起
没有更多啦~
{{commentLoading ? '加载中...' : '查看更多评论'}}