java全自动生成krpano全景漫游
2017-07-30 14:34
239 查看
之前有需求想把krpano功能化,让后台全自动生成,但是在网上并没有看到相关的帖子,于是我就对krpano研究了一天,总算给实现了,随着VR的发展,这项技术肯定会有更多的人学习,我就把我研究出来的解决过程分享给大家吧!!!
准备工作:
1.下载krpano-1.19-pr8(我用的是这个版本),下载地址:https://krpano.com/download/,至于破解我就不讲了,网上有很多
2.java开发环境
3.tomcat
原理:下载krpano后解压文件夹里有一个批处理:MAKE VTOUR (MULTIRES) droplet.bat,直接把全景图片拖动执行这个批处理就会自动生成相应的全景html文件夹。
废话不多说,直接上码:
这些代码主要意思是用代码来拖动全景图片去执行那个批处理,然后等待生成之后修改生成之后的文件以及删除一切多余的文件,因为我做过N次实验及对比,我发现执行后生成的很多文件都是一致的,所以我就整理了一个通用的包(放在vshow文件夹),因为生成文件后必须还得自动发布,所有vshow这个文件夹我是直接放在项目里的:
至于vshow里的文件内容你自己生成一次之后保留这些东西就可以了,继续回到正题,我这个是将全景图片上传了之后,先存放在D:\\temp-room\\里,然后执行cmd命令自动生成,生成了之后将需要的文件复制到vshow文件夹里,只要你仔仔细细看我代码就能明白所有的事情,生成这些文件处理完后,前台访问就直接用一个通用的jsp文件来访问,直接贴上我的源码吧,一定要仔细看代码,不然真的很难懂:
源码地址:http://download.csdn.net/download/u012084981/10107545
有不懂的可以加我微信ymsay5496
准备工作:
1.下载krpano-1.19-pr8(我用的是这个版本),下载地址:https://krpano.com/download/,至于破解我就不讲了,网上有很多
2.java开发环境
3.tomcat
原理:下载krpano后解压文件夹里有一个批处理:MAKE VTOUR (MULTIRES) droplet.bat,直接把全景图片拖动执行这个批处理就会自动生成相应的全景html文件夹。
废话不多说,直接上码:
import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import com.ujum.app.bean.Room; public class CmdBat { public static void main(String[] args) { Room r = new Room(); String dpath = "D:\\Tomcat 8.5\\webapps\\ujum-file\\vshow"; String file = "0049132f-25dd-4984-8505-f6bdf624c6c3"; String[] fn1 = { "1049132f-25dd-4984-8505-f6bdf624c6c3", "2049132f-25dd-4984-8505-f6bdf624c6c3", "3049132f-25dd-4984-8505-f6bdf624c6c3" }; String[] fn2 = { "客厅", "卧室", "大客厅" }; String title = "哈哈哈哈哈哈哈哈"; String music = "vshow/backgroundmusic/default.mp3"; try { setKrpano(r, dpath, file, fn1, fn2, title, music); } catch (InterruptedException e) { e.printStackTrace(); System.out.println("上传失败"); } } public static void setKrpano(final Room r, final String dpath, final String file, final String[] fn1, final String[] fn2, final String title, final String music) throws InterruptedException { final String temppath = "D:\\temp-room\\"; String path = temppath + file; String ex = "krpanotools32.exe makepano -config=templates\\vtour-multires.config " + path + "\\*.jpg"; Runtime runtime = Runtime.getRuntime(); boolean b = true; Process p = null; try { p = runtime.exec("cmd /c start d:\\krpano-1.19-pr8\\" + ex); } catch (Exception e) { b = false; } if (b) { final InputStream is1 = p.getInputStream(); final InputStream is2 = p.getErrorStream(); new Thread() { public void run() { BufferedReader br1 = new BufferedReader( new InputStreamReader(is1)); try { String line1 = null; while ((line1 = br1.readLine()) != null) { if (line1 != null) { System.out.println("=AA==========line1======" + line1); } } } catch (IOException e) { e.printStackTrace(); } finally { try { is1.close(); // 执行文件复制 File f = new File(dpath + "\\" + file); f.mkdirs();// 创建目录 // 复制文件 boolean b1 = copyFile(temppath + file + "\\vtour\\tour.js", dpath + "\\" + file + "\\tour.js"); if (b1) { boolean b2 = copyFile(temppath + file + "\\vtour\\tour.swf", dpath + "\\" + file + "\\tour.swf"); if (b2) { boolean b3 = copyFile(temppath + file + "\\vtour\\tour.xml", dpath + "\\" + file + "\\tour.xml"); if (b3) { // 复制文件夹 boolean b4 = copyFolder(temppath + file + "\\vtour\\panos", dpath + "\\" + file + "\\panos"); if (b4) { // 删除临时生成文件 delFolder(temppath + file); // 修改krpano文件内容 String xmlPath = dpath + "\\" + file + "\\tour.xml"; File xmlFile = new File(xmlPath); DocumentBuilderFactory dbFactory = DocumentBuilderFactory .newInstance(); DocumentBuilder dBuilder; try { dBuilder = dbFactory .newDocumentBuilder(); Document doc = dBuilder .parse(xmlFile); doc.getDocumentElement() .normalize(); for (int i = 0; i < fn1.length; i++) { updateAttributeValue(doc, fn1[i], fn2[i]); } // update Element value updateElementValue(doc, title); / adb1 / delete element deleteElement(doc); // add new element addElement(doc); updateAttributeColorValue(doc, "0x000000"); addMusicElement(doc, music); // write the updated document to // file or console doc.getDocumentElement() .normalize(); TransformerFactory transformerFactory = TransformerFactory .newInstance(); Transformer transformer = transformerFactory .newTransformer(); DOMSource source = new DOMSource( doc); StreamResult result = new StreamResult( new File(xmlPath)); transformer.setOutputProperty( OutputKeys.INDENT, "yes"); transformer.transform(source, result); // 生成成功执行之后的操作,我这里是生成之后更改数据库状态 /*r.setMark("1"); AdminService as = ContextUtil .getBean( AdminService.class, "adminService"); as.updateRoom(r);*/ /* * System.out .println( * "XML file updated successfully" * ); */ } catch ( SAXException | ParserConfigurationException | IOException | TransformerException e1) { e1.printStackTrace(); // 生成失败执行操作 /*r.setMark("2"); AdminService as = ContextUtil .getBean( AdminService.class, "adminService"); as.updateRoom(r);*/ } } } } } } catch (IOException e) { e.printStackTrace(); } } } }.start(); new Thread() { public void run() { BufferedReader br2 = new BufferedReader( new InputStreamReader(is2)); try { String line2 = null; while ((line2 = br2.readLine()) != null) { if (line2 != null) { System.out.println("=AA==========line2======" + line2); } } } catch (IOException e) { e.printStackTrace(); } finally { try { is2.close(); } catch (IOException e) { e.printStackTrace(); } } } }.start(); p.waitFor(); p.destroy(); } else { System.out.println("上传失败"); } } /** * 复制单个文件 * * @param oldPath * String 原文件路径 如:c:/fqf.txt * @param newPath * String 复制后路径 如:f:/fqf.txt * @return boolean */ public static boolean copyFile(String oldPath, String newPath) { try { int bytesum = 0; int byteread = 0; File oldfile = new File(oldPath); if (oldfile.exists()) { // 文件存在时 InputStream inStream = new FileInputStream(oldPath); // 读入原文件 FileOutputStream fs = new FileOutputStream(newPath); byte[] buffer = new byte[1444]; int length; while ((byteread = inStream.read(buffer)) != -1) { bytesum += byteread; // 字节数 文件大小 // System.out.println(bytesum); fs.write(buffer, 0, byteread); } inStream.close(); } } catch (Exception e) { // System.out.println("复制单个文件操作出错"); e.printStackTrace(); return false; } return true; } /** * 复制整个文件夹内容 * * @param oldPath * String 原文件路径 如:c:/fqf * @param newPath * String 复制后路径 如:f:/fqf/ff * @return boolean */ public static boolean copyFolder(String oldPath, String newPath) { try { (new File(newPath)).mkdirs(); // 如果文件夹不存在 则建立新文件夹 File a = new File(oldPath); String[] file = a.list(); File temp = null; for (int i = 0; i < file.length; i++) { if (oldPath.endsWith(File.separator)) { temp = new File(oldPath + file[i]); } else { temp = new File(oldPath + File.separator + file[i]); } if (temp.isFile()) { FileInputStream input = new FileInputStream(temp); FileOutputStream output = new FileOutputStream(newPath + "/" + (temp.getName()).toString()); byte[] b = new byte[1024 * 5]; int len; while ((len = input.read(b)) != -1) { output.write(b, 0, len); } output.flush(); output.close(); input.close(); } if (temp.isDirectory()) {// 如果是子文件夹 copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i]); } } } catch (Exception e) { // System.out.println("复制整个文件夹内容操作出错"); e.printStackTrace(); return false; } return true; } // 删除文件夹 public static void delFolder(String folderPath) { try { delAllFile(folderPath); // 删除完里面所有内容 String filePath = folderPath; filePath = filePath.toString(); java.io.File myFilePath = new java.io.File(filePath); myFilePath.delete(); // 删除空文件夹 } catch (Exception e) { e.printStackTrace(); } } public static boolean delAllFile(String path) { boolean flag = false; File file = new File(path); if (!file.exists()) { return flag; } if (!file.isDirectory()) { return flag; } String[] tempList = file.list(); File temp = null; for (int i = 0; i < tempList.length; i++) { if (path.endsWith(File.separator)) { temp = new File(path + tempList[i]); } else { temp = new File(path + File.separator + tempList[i]); } if (temp.isFile()) { temp.delete(); } if (temp.isDirectory()) { delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件 delFolder(path + "/" + tempList[i]);// 再删除空文件夹 flag = true; } } return flag; } private static void addElement(Document doc) { NodeList employees = doc.getElementsByTagName("krpano"); Element emp = null; // loop for each employee for (int i = 0; i < employees.getLength(); i++) { emp = (Element) employees.item(i); Element vtourskin = doc.createElement("include"); vtourskin.setAttribute("url", "../skin/vtourskin.xml"); emp.appendChild(vtourskin); Element skinselect = doc.createElement("include"); skinselect.setAttribute("url", "../skinselect.xml"); emp.appendChild(skinselect); } } private static void addMusicElement(Document doc, String music) { NodeList employees = doc.getElementsByTagName("krpano"); Element emp = null; // loop for each employee for (int i = 0; i < employees.getLength(); i++) { emp = (Element) employees.item(i); Element musicEl = doc.createElement("action"); musicEl.setAttribute("name", "bgsnd_action"); musicEl.setAttribute("autorun", "onstart"); musicEl.appendChild(doc.createTextNode("playsound(bgsnd, '" + music + "', 0);")); emp.appendChild(musicEl); } } private static void deleteElement(Document doc) { NodeList employees = doc.getElementsByTagName("krpano"); Element emp = null; // loop for each employee for (int i = 0; i < employees.getLength(); i++) { emp = (Element) employees.item(i); Node genderNode = emp.getElementsByTagName("include").item(0); emp.removeChild(genderNode); } } private static void updateElementValue(Document doc, String title) { NodeList employees = doc.getElementsByTagName("krpano"); Element emp = null; // loop for each employee for (int i = 0; i < employees.getLength(); i++) { emp = (Element) employees.item(i); emp.setAttribute("title", title); } } private static void updateAttributeValue(Document doc, String oldname, String newname) { NodeList employees = doc.getElementsByTagName("scene"); Element emp = null; // loop for each employee for (int i = 0; i < employees.getLength(); i++) { emp = (Element) employees.item(i); if (emp.getAttribute("title").equals(oldname)) { emp.setAttribute("title", newname); break; } } } private static void updateAttributeColorValue(Document doc, String newname) { NodeList employees = doc.getElementsByTagName("skin_settings"); Element emp = null; // loop for each employee for (int i = 0; i < employees.getLength(); i++) { emp = (Element) employees.item(i); emp.setAttribute("design_bgcolor", newname); emp.setAttribute("design_bgalpha", "0.8"); } } }
这些代码主要意思是用代码来拖动全景图片去执行那个批处理,然后等待生成之后修改生成之后的文件以及删除一切多余的文件,因为我做过N次实验及对比,我发现执行后生成的很多文件都是一致的,所以我就整理了一个通用的包(放在vshow文件夹),因为生成文件后必须还得自动发布,所有vshow这个文件夹我是直接放在项目里的:
至于vshow里的文件内容你自己生成一次之后保留这些东西就可以了,继续回到正题,我这个是将全景图片上传了之后,先存放在D:\\temp-room\\里,然后执行cmd命令自动生成,生成了之后将需要的文件复制到vshow文件夹里,只要你仔仔细细看我代码就能明白所有的事情,生成这些文件处理完后,前台访问就直接用一个通用的jsp文件来访问,直接贴上我的源码吧,一定要仔细看代码,不然真的很难懂:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE html> <html> <head> <base href="<%=basePath%>"> <title>${title }</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" /> <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="shortcut icon" href="images/favicon.png"> <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; } </style> </head> <body> <div style="position: absolute;z-index: 1;margin-top: 10px;margin-left: 10px"> <a href="<%=basePath%>"><img src="images/logo.png" style="height: 50px"></a> </div> <script src="http://www.sxujum.com/ujum-file/vshow/${vid }/tour.js"></script> <div id="pano" style="width:100%;height:100%;"> <noscript><table style="width:100%;height:100%;"><tr style="vertical-align:middle;"><td><div style="text-align:center;">ERROR:<br/><br/>Javascript not activated<br/><br/></div></td></tr></table></noscript> <script> var vid = "${vid}"; embedpano({swf:"http://www.sxujum.com/ujum-file/vshow/${vid }/tour.swf", xml:"http://www.sxujum.com/ujum-file/vshow/${vid }/tour.xml", target:"pano", html5:"prefer", mobilescale:1.0, passQueryParameters:true}); </script> </div> </body> </html>
源码地址:http://download.csdn.net/download/u012084981/10107545
有不懂的可以加我微信ymsay5496
相关文章推荐
- 基于web的全景漫游自动生成加编辑平台的技术实现(一)----初识krpano引擎
- 基于web的全景漫游自动生成加编辑平台的技术实现(三)----krpano主XML文件
- 基于web的全景漫游自动生成加编辑平台的技术实现(二)----krpano窥探
- 基于web的全景漫游自动生成加编辑平台的技术实现(四)----添加热点
- Java利用Swagger2自动生成对外接口的文档
- eclipse下编写android程序突然不会自动生成R.java文件和包的解决办法
- r cannot be resolved to a variable 问题解决 / r.java文件没有自动生成
- Java程序:自动生成一个n阶矩阵
- Android 导入android源码有错,R.java文件不能自动生成解决方法
- Java Web开发中可否自动生成结构一致的代码?
- BeeFrameWork框架下的ActiveAndroid自动生成数据库表Java文件
- mybatis自动生成java代码
- 使用jsonschema2pojo根据JSON文件自动生成Java POJO类(Java Bean)源文件
- 开启第一个krpano全景漫游网站
- Eclipse导入ApiDemos后R.java不自动生成的问题
- oracle script : java 实体互相付值自动匹配 ,自动生成代码
- 基于Krpano 的全景漫游系统的实现
- 使用自动生成java文件和自动编译的静态代理模式-马士兵设计模式教程
- 如何使用java自动生成数据表id,java.util.UUID类
- myeclipse自动生成POJO类时一直找不到java src folder--解决方案