완전한 3차원 3D 파노라마 효과를 얻기 위해Krpano
소프트웨어를 사용하여 일반 어안 사진을 720° 파노라마로 렌더링합니다 blockquote>Krpano
软件将普通鱼眼图片渲染为720°全景图
说明:代码有过调整,并不能保证运行,主要说明实现思路。
首先下载软件Krpano全景图生成软件,其中包含Linux
版本及Win
版本以及简单的使用手册文件。
其实简单的使用只需两步,第一步是将上传的图片生成显示全景图需要的图片,第二步是根据全景图的显示规则和配置文件将全景图显示出来。
【相关推荐:最新的10个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
上传接口代码如下:
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();");
코드는 조정되었으며 실행이 보장되지 않습니다. 주로 구현 아이디어를 설명합니다.
먼저 Linux
버전, Win
버전과 간단한 사용자 설명서 파일이 포함된 Krpano 파노라마 생성 소프트웨어를 다운로드하세요.
실제로 사용하려면 두 단계만 거치면 됩니다. 첫 번째 단계는 업로드된 사진에서 파노라마를 표시하는 데 필요한 사진을 생성하는 것입니다. 두 번째 단계는 파노라마 표시 규칙 및 구성에 따라 파노라마를 표시하는 것입니다. 파일.
【관련 권장사항: 최신 10개 thinkphp 비디오 튜토리얼
】