Heim >PHP-Framework >Denken Sie an PHP >Bringen Sie Ihnen bei, wie Sie mit ThinkPHP+Krpano ein Panorama erstellen

Bringen Sie Ihnen bei, wie Sie mit ThinkPHP+Krpano ein Panorama erstellen

藏色散人
藏色散人nach vorne
2021-03-02 15:41:323437Durchsuche

Die folgende Tutorial-Kolumne stellt Ihnen das Panorama von tThinkPHP3.2+Krpano von thinkphp vor. Ich hoffe, dass es Freunden in Not hilfreich sein wird!

ThinkPHP3.2+Krpano realisiert Panorama

Um einen vollständigen dreidimensionalen 3D-Panoramaeffekt zu erzielen, verwenden wir die Software Krpano, um gewöhnliche Fischaugenbilder in ein 720°-Panorama zu rendern 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 =&#39;./upload_3dpic/&#39;;
    $url_path =&#39;/upload_3dpic/&#39;;    //外部访问url
    $f_up_to_path =$root_path .&#39;/&#39;. $datePath.&#39;/&#39;.$md5Code;
    if(!file_exists($f_up_to_path)){
        mkdir($f_up_to_path, 0777, true);
    }
    $type = strtolower(substr($u_name, strrpos($u_name, &#39;.&#39;) + 1));
    $img_file_name =$md5Code."." . $type;

    $saveFileName = $f_up_to_path."." . $type;
    $true_img_url =$url_path . $datePath.&#39;/&#39;.$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();");

Hinweis:

Der Code wurde angepasst und es kann nicht garantiert werden, dass er ausgeführt wird. Er erklärt hauptsächlich die Implementierungsideen.
Laden Sie zunächst die Software Krpano Panorama Generation herunter, die eine Linux-Version und eine Win-Version sowie eine einfache Benutzerhandbuchdatei enthält.
Tatsächlich sind für die Verwendung nur zwei Schritte erforderlich. Der erste Schritt besteht darin, die für die Anzeige des Panoramas erforderlichen Bilder aus den hochgeladenen Bildern zu generieren. Der zweite Schritt besteht darin, das Panorama gemäß den Panorama-Anzeigeregeln und -Konfiguration anzuzeigen Dateien.

【Verwandte Empfehlungen: Die neuesten 10 Thinkphp-Video-Tutorials

Bilder hochladen und Panorama erstellen Das Bildprinzip 🎜🎜🎜 ist sehr einfach. Laden Sie das Bild auf den Server hoch, verwenden Sie dann das Serverbild, um über die Krpano-Software ein Panorama zu erstellen, und übertragen Sie das generierte Bild in ein einheitliches Verzeichnis. 🎜Bevor Sie mit dem Hochladen von Bildern beginnen, müssen Sie die Konfigurationsdatei Krpano/templates/normal.config von Krpano wie folgt ändern: 🎜
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();
}
🎜Die Upload-Schnittstelle Der Code lautet wie folgt: 🎜
<!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>
🎜Zu diesem Zeitpunkt können wir bereits Bilder über die Upload-Schnittstelle hochladen und die Bilder über Krpano in Panoramen rendern. 🎜

Panorama anzeigen

🎜Um das Bild anzuzeigen, müssen wir die erforderliche xml-Konfigurationsdatei gemäß den Krpano-Regeln generieren. 🎜Wir erstellen ein Panorama basierend auf dem eindeutigen Code, der aus dem hochgeladenen Bild generiert wird. 🎜rrreee🎜Die scene rendert nicht das aktuelle Rendering, aber wenn wir zwischen mehreren Panoramen wählen, wird DOM.call("toggle_item_hotspots(); ");Automatisch ausgelöst . 🎜🎜Legen Sie die Route und Methode zur Anzeige der Seite fest: 🎜rrreee🎜In der entsprechenden Ansichtsdatei: 🎜rrreee🎜Ändern Sie den Pfad der entsprechenden statischen Ressourcendatei entsprechend Ihrem Projekt. Zu diesem Zeitpunkt können Sie bereits unser Panorama sehen. 🎜🎜

Das obige ist der detaillierte Inhalt vonBringen Sie Ihnen bei, wie Sie mit ThinkPHP+Krpano ein Panorama erstellen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen