博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java实现,使用opencv合成全景图,前端使用krpano展示
阅读量:5098 次
发布时间:2019-06-13

本文共 16536 字,大约阅读时间需要 55 分钟。

这周花三天做了一demo,算上之前的,怎么也有五天,上一篇是opencv介绍,以及定义native方法,通过本地图片路径传参,底层调用Opencv图像库合成,有兴趣的可以看看,这篇重点在于krpano的全景图展示,话说刚才上传了22张片照片合成全景图,感觉有半个小时也没有合成完,我这电脑是有多垃圾

那我们代码走一走(都说不上代码是老流氓)

这是demo的目录结构

@Controllerpublic class PanoramaController {     /**         *    @Description:  文件上传以及全景合成         *    @Date:  15:58  2018/7/6         *    @Params:   * @param null         */         @RequestMapping("/upload")    public ModelAndView login07(@RequestParam(value = "file", required = false)MultipartFile[] files,                          @RequestParam(value = "title",defaultValue = "未命名") String title,HttpServletRequest request) {        ModelAndView mv=new ModelAndView("success.html");        MultipartFile tempMultipartFile;        //基本路径        StringBuffer sb=new StringBuffer();        String baseURL="E:/demo";        String tempStr = "/" + UUID.randomUUID().toString();        for (int j = 0; j < files.length; j++) {            tempMultipartFile = files[j];            // 获得上传的文件名称-带有后缀            String fileNameAndSuffixName = tempMultipartFile.getOriginalFilename();            // 获取上传的文件名称            //String fileName = fileNameAndSuffixName.substring(0, fileNameAndSuffixName.lastIndexOf("."));            String urlPath;            urlPath = Imgeupload.fileUpdata(tempMultipartFile, "E:/demo", "" + tempStr);            System.out.println("=====" + urlPath);            if (j==files.length-2){                sb.append(baseURL+tempStr+"/"+urlPath);                break;            }else if (j

  这个主要是文件上传以及全景图合成调用native,生成result.jpg全景图,利用生成的全景图通过krpano工具,生成相应的文件放在tomcat对应webapp,启动tomcat即可访问,这是最开始使用krpano看效果的流程,当然java项目不可能手动复制粘贴文件吧,一切都是通过程序控制,所以不可避免java IO操作,这时遇到一个很大的坑,听我细细道来

  当时想已经通过krpano生成的相应的文件复制到webapp这部分的操作通过io进行操作,后来才发现,用IO发现权限不够,我使用的是spring boot 项目,tomcat是嵌入式,所以复制到当前项目classes文件下,那换一条路既然生成的都是静态文件,那从当前的项目,引用绝对路径,从本地获取静态资源,呵呵,通过指定端口当用的项目,静态资源权限只限当前项目,从网上收集许多资料,最终使用 

 

spring:  resources:    static-locations: //相当于,这块空间和static目录下,resource下,webjar下同级, //而这块空间可以io进行操作

好了,这个问题解决了,那java代码如何将某个图片拖到本地某个应用XX.bat上看如下代码

public class CmdBat {		/*public static void main(String[] args) {		Room r = new Room();		//项目的位置		String dpath = "D:\\tupian\\vshow";		//全景图的位置		String file = "3";		String[] fn1 = { "2",				"3" };		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("上传失败");		}	}*/	     /**	         *    @Description:	         *    @Date:  10:15  2018/7/6	         *    @Params:   * @param null	         */	     	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:\\tupian\\img\\";		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 {			//krpano  安装位置			p = runtime.exec("cmd /c start D:\\Krpano\\krpano.1.19.pr16\\krpano-1.19-pr16\\" + 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);												// 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();			File myFilePath = new 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");		}	}}  

去掉mian函数的注释,启动一下,看看执行结果,这段代码相当于手动拖动图片到.bat上,其中可以修改krpano下的templates下的vtour-multires.config文件

# basic settingsinclude basicsettings.configpanotype=sphere# panotype=autodetecthfov=360makescenes=true

  自动生成一种固定的全景图(柱型,球型...)

Ok,看一下生成文件中哪些是固定的公用的

@Controllerpublic class FileLibraryController {         /**             *    @Description:  从文件中获取全景图             *    @Date:  17:13  2018/7/5             *    @Params:   * @param null             */    @RequestMapping("/all")    public ModelAndView list(Model model){       // List
wjList = new ArrayList
();//新建一个文件集合 List
list=new ArrayList<>(); File file=new File(ConstantBank.PANORAMA_BANK_URL); ModelAndView mv=new ModelAndView("list.html"); File[] fileList = file.listFiles();//将该目录下的所有文件放置在一个File类型的数组中 for (int i = 0; i < fileList.length; i++) { if (fileList[i].isDirectory()) {//判断是否为文件 // wjList.add(fileList[i]); String directoryName=fileList[i].getName(); if (!directoryName.equals(ConstantBank.EXCLUSIVE_SECOND_DIR_NAEM)&&!directoryName.equals(ConstantBank.EXCLUSIVE_FIRST_DIR_NAME)){ //分割文件名 String title =directoryName.substring(directoryName.indexOf(",")+1); PanoramaDO panoramaDO=new PanoramaDO(); panoramaDO.setId(directoryName); if (title==null||title.equals("")){ panoramaDO.setTitle("未命名"); }else { panoramaDO.setTitle(title); } list.add(panoramaDO); //System.out.println(directoryName); //System.out.println(title); } } } System.out.println(list); mv.addObject("list",list); return mv; } @RequestMapping("/{id}/temp") public ModelAndView jump(@PathVariable("id") String vid){ ModelAndView mv =new ModelAndView("vr.html"); //mv.getView(). mv.addObject("vid",vid); String title =vid.substring(vid.indexOf(",")+1); if (title==null||title.equals("")){ mv.addObject("title","未命名"); }else { mv.addObject("title",title); } System.out.println("===>"+vid); return mv; } @RequestMapping("/compound/{fileName}/{title}") public ModelAndView compound(@PathVariable("fileName") String fileName, @PathVariable("title") String title){ ModelAndView mv =new ModelAndView("redirect:/all"); //mv.getView(). Room r = new Room(); //项目的位置 String dpath = "D:\\tupian\\vshow"; //全景图的文件名 String file = fileName; String[] fn1 = { "2", "3" }; String[] fn2 = { "客厅", "卧室","大客厅" }; //String title = "哈哈哈哈哈哈哈哈"; String music = "vshow/backgroundmusic/default.mp3"; try { CmdBat.setKrpano(r,dpath, file, fn1, fn2, title,music); } catch (InterruptedException e) { e.printStackTrace(); System.out.println("上传失败"); } return mv; }}

 vr.html  公用的vr.html

  upload.html  这是文件上传以及回显,下面的js等待加载过度

    
合成全景图片的名字

  这写到这把,后续会弄全景漫游....这些都要整合项目里面

 

 

转载于:https://www.cnblogs.com/developerxiaofeng/p/9274854.html

你可能感兴趣的文章
《101 Windows Phone 7 Apps》读书笔记-NOTEPAD
查看>>
简单说springmvc的工作原理
查看>>
奋斗的小蜗牛
查看>>
poj3723 Conscription
查看>>
Python 编程快速上手 第 7章 模式匹配与正则表达式
查看>>
深度解析vuex
查看>>
Android开发之基于监听的事件处理
查看>>
1600802010韩璐——大作业界面
查看>>
CodeVS 1226 倒水问题【DFS/BFS】
查看>>
ROR 第一章 从零到部署--安装环境
查看>>
Validate a sudo puzzle
查看>>
bzoj1044 [HAOI2008]木棍分割——前缀和优化DP
查看>>
jvm性能调优笔记
查看>>
python学习第三天基本数据类型、格式化输入输出、运算符。流程控制
查看>>
FRM-40654 Record has been updated
查看>>
IDEA03 连接数据库、自动生成实体类
查看>>
保险数据分析
查看>>
字程序级别的重构
查看>>
标准的ajax上传
查看>>
extjs4 折线图(实时动态展现数据)实例
查看>>