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

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

这是demo的目录结构

  1. @Controller
  2. public class PanoramaController {
  3.  
  4. /**
  5. * @Description: 文件上传以及全景合成
  6. * @Date: 15:58 2018/7/6
  7. * @Params: * @param null
  8. */
  9.  
  10. @RequestMapping("/upload")
  11. public ModelAndView login07(@RequestParam(value = "file", required = false)MultipartFile[] files,
  12. @RequestParam(value = "title",defaultValue = "未命名") String title,HttpServletRequest request) {
  13. ModelAndView mv=new ModelAndView("success.html");
  14. MultipartFile tempMultipartFile;
  15. //基本路径
  16. StringBuffer sb=new StringBuffer();
  17. String baseURL="E:/demo";
  18. String tempStr = "/" + UUID.randomUUID().toString();
  19. for (int j = 0; j < files.length; j++) {
  20. tempMultipartFile = files[j];
  21. // 获得上传的文件名称-带有后缀
  22. String fileNameAndSuffixName = tempMultipartFile.getOriginalFilename();
  23. // 获取上传的文件名称
  24. //String fileName = fileNameAndSuffixName.substring(0, fileNameAndSuffixName.lastIndexOf("."));
  25. String urlPath;
  26. urlPath = Imgeupload.fileUpdata(tempMultipartFile, "E:/demo", "" + tempStr);
  27. System.out.println("=====" + urlPath);
  28. if (j==files.length-2){
  29. sb.append(baseURL+tempStr+"/"+urlPath);
  30. break;
  31. }else if (j<files.length-2){
  32. sb.append(baseURL+tempStr+"/"+urlPath+",");
  33. }else {
  34. System.out.println();
  35. }
  36.  
  37. }
  38. //拼接URL
  39. System.out.println("拼接URL"+sb.toString());
  40. //调用native
  41. String result= OpenCVUtil.changeArrValue(sb.toString());
  42.  
  43. if(!result.contains(",")){
  44. mv.setViewName("failure.html");
  45. return mv;
  46. }
  47. //System.out.println(result);
  48. //复制图片
  49. String basedirNew=UUID.randomUUID().toString()+","+title;
  50. String dirNew="D:\\tupian\\img\\"+basedirNew+"\\";
  51. try {
  52. copyFile(new File("D:/result.jpg"),new File(dirNew+title+".jpg"),dirNew);
  53. } catch (IOException e) {
  54. e.printStackTrace();
  55. }
  56. mv.addObject("imgUrl","/img/"+basedirNew+"/"+title+".jpg");
  57. mv.addObject("title",title);
  58. mv.addObject("fileName",basedirNew);
  59. return mv;
  60. }
  61.  
  62. @RequestMapping("/index")
  63. public String login06() {
  64. return "upload.html";
  65. }
  66.  
  67. /**
  68. * @Description: 复制生成的图片到全景图静态区
  69. * @Date: 9:45 2018/7/5
  70. * @Params: * @param null
  71. */
  72.  
  73. public void copyFile(File fromFile, File toFile,String fromUrl) throws IOException {
  74. File file=new File(fromUrl);
  75. if (!file.exists()) {
  76. file.mkdir();
  77. }
  78. FileInputStream ins = new FileInputStream(fromFile);
  79. FileOutputStream out = new FileOutputStream(toFile);
  80. byte[] b = new byte[1024];
  81. int n=0;
  82. while((n=ins.read(b))!=-1){
  83. out.write(b, 0, n);
  84. }
  85.  
  86. ins.close();
  87. out.close();
  88. }
  89.  
  90. }

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

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

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

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

  1. public class CmdBat {
  2.  
  3. /*public static void main(String[] args) {
  4. Room r = new Room();
  5. //项目的位置
  6. String dpath = "D:\\tupian\\vshow";
  7. //全景图的位置
  8. String file = "3";
  9. String[] fn1 = { "2",
  10. "3" };
  11. String[] fn2 = { "客厅", "卧室","大客厅" };
  12. String title = "哈哈哈哈哈哈哈哈";
  13. String music = "vshow/backgroundmusic/default.mp3";
  14. try {
  15. setKrpano(r,dpath, file, fn1, fn2, title,music);
  16. } catch (InterruptedException e) {
  17. e.printStackTrace();
  18. System.out.println("上传失败");
  19. }
  20.  
  21. }*/
  22. /**
  23. * @Description:
  24. * @Date: 10:15 2018/7/6
  25. * @Params: * @param null
  26. */
  27.  
  28. public static void setKrpano(final Room r, final String dpath, final String file,
  29. final String[] fn1, final String[] fn2, final String title, final String music)
  30. throws InterruptedException {
  31. //全景图存的位置
  32. final String temppath = "D:\\tupian\\img\\";
  33. String path = temppath+file;
  34. String ex = "krpanotools32.exe makepano -config=templates\\vtour-multires.config "
  35. + path + "\\*.jpg";
  36. //执行
  37. Runtime runtime = Runtime.getRuntime();
  38. boolean b = true;
  39. Process p = null;
  40. try {
  41. //krpano 安装位置
  42. p = runtime.exec("cmd /c start D:\\Krpano\\krpano.1.19.pr16\\krpano-1.19-pr16\\" + ex);
  43. } catch (Exception e) {
  44. b = false;
  45. }
  46. if (b) {
  47. final InputStream is1 = p.getInputStream();
  48. final InputStream is2 = p.getErrorStream();
  49. new Thread() {
  50. public void run() {
  51. BufferedReader br1 = new BufferedReader(
  52. new InputStreamReader(is1));
  53. try {
  54. String line1 = null;
  55. while ((line1 = br1.readLine()) != null) {
  56. if (line1 != null) {
  57. System.out.println("=AA==========line1======"
  58. + line1);
  59. }
  60. }
  61. } catch (IOException e) {
  62. e.printStackTrace();
  63. } finally {
  64. try {
  65. is1.close();
  66. // 执行文件复制
  67. File f = new File(dpath + "\\" + file);
  68. f.mkdirs();// 创建目录
  69. // 复制文件
  70. boolean b1 = copyFile(temppath + file
  71. + "\\vtour\\tour.js", dpath + "\\" + file
  72. + "\\tour.js");
  73. if (b1) {
  74. boolean b2 = copyFile(temppath + file
  75. + "\\vtour\\tour.swf", dpath + "\\"
  76. + file + "\\tour.swf");
  77. if (b2) {
  78. boolean b3 = copyFile(temppath
  79. + file + "\\vtour\\tour.xml", dpath
  80. + "\\" + file + "\\tour.xml");
  81. if (b3) {
  82. // 复制文件夹
  83. boolean b4 = copyFolder(
  84. temppath + file
  85. + "\\vtour\\panos",
  86. dpath + "\\" + file + "\\panos");
  87. if (b4) {
  88. // 删除临时生成文件
  89. delFolder(temppath + file);
  90. // 修改krpano文件内容
  91. String xmlPath = dpath + "\\"
  92. + file + "\\tour.xml";
  93. File xmlFile = new File(xmlPath);
  94. DocumentBuilderFactory dbFactory = DocumentBuilderFactory
  95. .newInstance();
  96. DocumentBuilder dBuilder;
  97. try {
  98. dBuilder = dbFactory
  99. .newDocumentBuilder();
  100. Document doc = dBuilder
  101. .parse(xmlFile);
  102. doc.getDocumentElement()
  103. .normalize();
  104. for (int i = 0; i < fn1.length; i++) {
  105. updateAttributeValue(doc,
  106. fn1[i], fn2[i]);
  107. }
  108.  
  109. // update Element value
  110. updateElementValue(doc, title);
  111.  
  112. // delete element
  113. deleteElement(doc);
  114.  
  115. // add new element
  116. addElement(doc);
  117.  
  118. updateAttributeColorValue(doc,
  119. "0x000000");
  120. addMusicElement(doc,music);
  121. // write the updated document to
  122. // file or console
  123. doc.getDocumentElement()
  124. .normalize();
  125. TransformerFactory transformerFactory = TransformerFactory
  126. .newInstance();
  127. Transformer transformer = transformerFactory
  128. .newTransformer();
  129. DOMSource source = new DOMSource(
  130. doc);
  131. StreamResult result = new StreamResult(
  132. new File(xmlPath));
  133. transformer.setOutputProperty(
  134. OutputKeys.INDENT,
  135. "yes");
  136. transformer.transform(source,
  137. result);
  138. //生成成功
  139. r.setMark("1");
  140. // AdminService as = ContextUtil.getBean(AdminService.class, "adminService");
  141. // as.updateRoom(r);
  142. /*System.out
  143. .println("XML file updated successfully");*/
  144.  
  145. } catch (
  146. SAXException
  147. | ParserConfigurationException
  148. | IOException
  149. | TransformerException e1) {
  150. e1.printStackTrace();
  151. //生成失败
  152. r.setMark("2");
  153. // AdminService as = ContextUtil.getBean(AdminService.class, "adminService");
  154. // as.updateRoom(r);
  155. }
  156.  
  157. }
  158. }
  159. }
  160. }
  161. } catch (IOException e) {
  162. e.printStackTrace();
  163. }
  164. }
  165. }
  166. }.start();
  167. new Thread() {
  168. public void run() {
  169. BufferedReader br2 = new BufferedReader(
  170. new InputStreamReader(is2));
  171. try {
  172. String line2 = null;
  173. while ((line2 = br2.readLine()) != null) {
  174. if (line2 != null) {
  175. System.out.println("=AA==========line2======"
  176. + line2);
  177. }
  178. }
  179. } catch (IOException e) {
  180. e.printStackTrace();
  181. } finally {
  182. try {
  183. is2.close();
  184. } catch (IOException e) {
  185. e.printStackTrace();
  186. }
  187. }
  188. }
  189. }.start();
  190. p.waitFor();
  191. p.destroy();
  192. } else {
  193. System.out.println("上传失败");
  194. }
  195.  
  196. }
  197.  
  198. /**
  199. * 复制单个文件
  200. *
  201. * @param oldPath
  202. * String 原文件路径 如:c:/fqf.txt
  203. * @param newPath
  204. * String 复制后路径 如:f:/fqf.txt
  205. * @return boolean
  206. */
  207. public static boolean copyFile(String oldPath, String newPath) {
  208. try {
  209. int bytesum = 0;
  210. int byteread = 0;
  211. File oldfile = new File(oldPath);
  212. if (oldfile.exists()) { // 文件存在时
  213. InputStream inStream = new FileInputStream(oldPath); // 读入原文件
  214. FileOutputStream fs = new FileOutputStream(newPath);
  215. byte[] buffer = new byte[1444];
  216. int length;
  217. while ((byteread = inStream.read(buffer)) != -1) {
  218. bytesum += byteread; // 字节数 文件大小
  219. // System.out.println(bytesum);
  220. fs.write(buffer, 0, byteread);
  221. }
  222. inStream.close();
  223. }
  224. } catch (Exception e) {
  225. // System.out.println("复制单个文件操作出错");
  226. e.printStackTrace();
  227. return false;
  228. }
  229. return true;
  230. }
  231.  
  232. /**
  233. * 复制整个文件夹内容
  234. *
  235. * @param oldPath
  236. * String 原文件路径 如:c:/fqf
  237. * @param newPath
  238. * String 复制后路径 如:f:/fqf/ff
  239. * @return boolean
  240. */
  241. public static boolean copyFolder(String oldPath, String newPath) {
  242. try {
  243. (new File(newPath)).mkdirs(); // 如果文件夹不存在 则建立新文件夹
  244. File a = new File(oldPath);
  245. String[] file = a.list();
  246. File temp = null;
  247. for (int i = 0; i < file.length; i++) {
  248. if (oldPath.endsWith(File.separator)) {
  249. temp = new File(oldPath + file[i]);
  250. } else {
  251. temp = new File(oldPath + File.separator + file[i]);
  252. }
  253.  
  254. if (temp.isFile()) {
  255. FileInputStream input = new FileInputStream(temp);
  256. FileOutputStream output = new FileOutputStream(newPath
  257. + "/" + (temp.getName()).toString());
  258. byte[] b = new byte[1024 * 5];
  259. int len;
  260. while ((len = input.read(b)) != -1) {
  261. output.write(b, 0, len);
  262. }
  263. output.flush();
  264. output.close();
  265. input.close();
  266. }
  267. if (temp.isDirectory()) {// 如果是子文件夹
  268. copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i]);
  269. }
  270. }
  271. } catch (Exception e) {
  272. // System.out.println("复制整个文件夹内容操作出错");
  273. e.printStackTrace();
  274. return false;
  275. }
  276. return true;
  277. }
  278.  
  279. // 删除文件夹
  280. public static void delFolder(String folderPath) {
  281. try {
  282. delAllFile(folderPath); // 删除完里面所有内容
  283. String filePath = folderPath;
  284. filePath = filePath.toString();
  285. File myFilePath = new File(filePath);
  286. myFilePath.delete(); // 删除空文件夹
  287. } catch (Exception e) {
  288. e.printStackTrace();
  289. }
  290. }
  291.  
  292. public static boolean delAllFile(String path) {
  293. boolean flag = false;
  294. File file = new File(path);
  295. if (!file.exists()) {
  296. return flag;
  297. }
  298. if (!file.isDirectory()) {
  299. return flag;
  300. }
  301. String[] tempList = file.list();
  302. File temp = null;
  303. for (int i = 0; i < tempList.length; i++) {
  304. if (path.endsWith(File.separator)) {
  305. temp = new File(path + tempList[i]);
  306. } else {
  307. temp = new File(path + File.separator + tempList[i]);
  308. }
  309. if (temp.isFile()) {
  310. temp.delete();
  311. }
  312. if (temp.isDirectory()) {
  313. delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件
  314. delFolder(path + "/" + tempList[i]);// 再删除空文件夹
  315. flag = true;
  316. }
  317. }
  318. return flag;
  319. }
  320.  
  321. private static void addElement(Document doc) {
  322. NodeList employees = doc.getElementsByTagName("krpano");
  323. Element emp = null;
  324.  
  325. // loop for each employee
  326. for (int i = 0; i < employees.getLength(); i++) {
  327. emp = (Element) employees.item(i);
  328. Element vtourskin = doc.createElement("include");
  329. vtourskin.setAttribute("url", "../skin/vtourskin.xml");
  330. emp.appendChild(vtourskin);
  331. Element skinselect = doc.createElement("include");
  332. skinselect.setAttribute("url", "../skinselect.xml");
  333. emp.appendChild(skinselect);
  334. }
  335. }
  336. private static void addMusicElement(Document doc,String music) {
  337. NodeList employees = doc.getElementsByTagName("krpano");
  338. Element emp = null;
  339.  
  340. // loop for each employee
  341. for (int i = 0; i < employees.getLength(); i++) {
  342. emp = (Element) employees.item(i);
  343. Element musicEl = doc.createElement("action");
  344. musicEl.setAttribute("name", "bgsnd_action");
  345. musicEl.setAttribute("autorun", "onstart");
  346. musicEl.appendChild(doc.createTextNode("playsound(bgsnd, '"+music+"', 0);"));
  347. emp.appendChild(musicEl);
  348. }
  349. }
  350. private static void deleteElement(Document doc) {
  351. NodeList employees = doc.getElementsByTagName("krpano");
  352. Element emp = null;
  353. // loop for each employee
  354. for (int i = 0; i < employees.getLength(); i++) {
  355. emp = (Element) employees.item(i);
  356. Node genderNode = emp.getElementsByTagName("include").item(0);
  357. emp.removeChild(genderNode);
  358. }
  359.  
  360. }
  361.  
  362. private static void updateElementValue(Document doc, String title) {
  363. NodeList employees = doc.getElementsByTagName("krpano");
  364. Element emp = null;
  365. // loop for each employee
  366. for (int i = 0; i < employees.getLength(); i++) {
  367. emp = (Element) employees.item(i);
  368. emp.setAttribute("title", title);
  369. }
  370. }
  371.  
  372. private static void updateAttributeValue(Document doc, String oldname,
  373. String newname) {
  374. NodeList employees = doc.getElementsByTagName("scene");
  375. Element emp = null;
  376. // loop for each employee
  377. for (int i = 0; i < employees.getLength(); i++) {
  378. emp = (Element) employees.item(i);
  379. if (emp.getAttribute("title").equals(oldname)) {
  380. emp.setAttribute("title", newname);
  381. break;
  382. }
  383. }
  384. }
  385.  
  386. private static void updateAttributeColorValue(Document doc, String newname) {
  387. NodeList employees = doc.getElementsByTagName("skin_settings");
  388. Element emp = null;
  389. // loop for each employee
  390. for (int i = 0; i < employees.getLength(); i++) {
  391. emp = (Element) employees.item(i);
  392. emp.setAttribute("design_bgcolor", newname);
  393. emp.setAttribute("design_bgalpha", "0.8");
  394. }
  395. }
  396. }  

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

  1. # basic settings
  2. include basicsettings.config
  3. panotype=sphere
  4. # panotype=autodetect
  5. hfov=360
  6. makescenes=true

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

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

  1. @Controller
  2. public class FileLibraryController {
  3. /**
  4. * @Description: 从文件中获取全景图
  5. * @Date: 17:13 2018/7/5
  6. * @Params: * @param null
  7. */
  8.  
  9. @RequestMapping("/all")
  10. public ModelAndView list(Model model){
  11. // List<File> wjList = new ArrayList<File>();//新建一个文件集合
  12. List<PanoramaDO> list=new ArrayList<>();
  13. File file=new File(ConstantBank.PANORAMA_BANK_URL);
  14. ModelAndView mv=new ModelAndView("list.html");
  15. File[] fileList = file.listFiles();//将该目录下的所有文件放置在一个File类型的数组中
  16. for (int i = 0; i < fileList.length; i++) {
  17. if (fileList[i].isDirectory()) {//判断是否为文件
  18. // wjList.add(fileList[i]);
  19. String directoryName=fileList[i].getName();
  20.  
  21. if (!directoryName.equals(ConstantBank.EXCLUSIVE_SECOND_DIR_NAEM)&&!directoryName.equals(ConstantBank.EXCLUSIVE_FIRST_DIR_NAME)){
  22. //分割文件名
  23. String title =directoryName.substring(directoryName.indexOf(",")+1);
  24. PanoramaDO panoramaDO=new PanoramaDO();
  25. panoramaDO.setId(directoryName);
  26. if (title==null||title.equals("")){
  27. panoramaDO.setTitle("未命名");
  28. }else {
  29. panoramaDO.setTitle(title);
  30. }
  31. list.add(panoramaDO);
  32. //System.out.println(directoryName);
  33. //System.out.println(title);
  34. }
  35.  
  36. }
  37. }
  38. System.out.println(list);
  39. mv.addObject("list",list);
  40. return mv;
  41.  
  42. }
  43.  
  44. @RequestMapping("/{id}/temp")
  45. public ModelAndView jump(@PathVariable("id") String vid){
  46.  
  47. ModelAndView mv =new ModelAndView("vr.html");
  48. //mv.getView().
  49. mv.addObject("vid",vid);
  50. String title =vid.substring(vid.indexOf(",")+1);
  51. if (title==null||title.equals("")){
  52. mv.addObject("title","未命名");
  53. }else {
  54. mv.addObject("title",title);
  55. }
  56. System.out.println("===>"+vid);
  57. return mv;
  58. }
  59.  
  60. @RequestMapping("/compound/{fileName}/{title}")
  61. public ModelAndView compound(@PathVariable("fileName") String fileName,
  62. @PathVariable("title") String title){
  63.  
  64. ModelAndView mv =new ModelAndView("redirect:/all");
  65. //mv.getView().
  66. Room r = new Room();
  67. //项目的位置
  68. String dpath = "D:\\tupian\\vshow";
  69. //全景图的文件名
  70. String file = fileName;
  71. String[] fn1 = { "2",
  72. "3" };
  73. String[] fn2 = { "客厅", "卧室","大客厅" };
  74. //String title = "哈哈哈哈哈哈哈哈";
  75. String music = "vshow/backgroundmusic/default.mp3";
  76. try {
  77. CmdBat.setKrpano(r,dpath, file, fn1, fn2, title,music);
  78. } catch (InterruptedException e) {
  79. e.printStackTrace();
  80. System.out.println("上传失败");
  81. }
  82.  
  83. return mv;
  84. }
  85.  
  86. }

 vr.html  公用的vr.html

  1. <!--<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false"%>
  2. <%
  3. String path = request.getContextPath();
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
  5. %>-->
  6. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  7. <!DOCTYPE html>
  8. <html>
  9. <head>
  10. <base href="/">
  11. <title th:text="${title}"> </title>
  12. <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />
  13. <meta name="apple-mobile-web-app-capable" content="yes" />
  14. <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  15. <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  16. <meta http-equiv="x-ua-compatible" content="IE=edge" />
  17. <link rel="shortcut icon" href="images/favicon.png">
  18. <style>
  19. @-ms-viewport { width:device-width; }
  20. @media only screen and (min-device-width:800px) { html { overflow:hidden; } }
  21. html { height:100%; }
  22. body { height:100%; overflow:hidden; margin:0; padding:0; font-family:Arial, Helvetica, sans-serif; font-size:16px; color:#FFFFFF; background-color:#000000; }
  23. </style>
  24. </head>
  25. <body>
  26. <div style="position: absolute;z-index: 1;margin-top: 10px;margin-left: 10px">
  27. <a href="/all"><img src="img/logo.jpg" style="height: 50px"></a>
  28. </div>
  29.  
  30. <script th:src="'/vshow/'+${vid }+'/tour.js'"></script>
  31. <div id="pano" style="width:100%;height:100%;">
  32. <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>
  33. <script>
  34. /*<![CDATA[*/
  35.  
  36. var vid = "[[${vid}]]";
  37. embedpano({swf:"/vshow/"+vid+"/tour.swf", xml:"/vshow/"+vid+"/tour.xml", target:"pano", html5:"prefer", mobilescale:1.0, passQueryParameters:true});
  38.  
  39. /* ]]>*/
  40.  
  41. </script>
  42. </div>
  43.  
  44. </body>
  45. </html>

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

  1. <!DOCTYPE html>
  2. <html lang="en">
  3.  
  4. <head>
  5. <meta charset="UTF-8">
  6. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  7. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  8. <title></title>
  9. <link rel="stylesheet" type="text/css" href="css/normalize.css" />
  10. <link rel="stylesheet" type="text/css" href="css/default.css">
  11. <!--<link rel="stylesheet" href="css/bootstrap.min.css">-->
  12. <link rel="stylesheet" href="css/demo.css">
  13. <link rel="stylesheet" href="css/fakeLoader.css">
  14.  
  15. <style>
  16. .uploadImgBtn {
  17.  
  18. width: 100px;
  19. height: 100px;
  20. cursor: pointer;
  21. position: relative;
  22. background: url("img/plus.png") no-repeat;
  23. -webkit-background-size: cover;
  24. background-size: cover;
  25. }
  26.  
  27. .uploadImgBtn .uploadImg {
  28. position: absolute;
  29. right: 0;
  30. top:0;
  31. width: 100%;
  32. height: 100%;
  33. opacity: 0;
  34. cursor: pointer;
  35. }
  36. //这是一个用做回显的盒子的样式
  37. .pic{
  38. width: 100px;
  39. height: 100px;
  40. }
  41. .pic img {
  42. width: 200px;
  43. height: 100px;
  44. }
  45. </style>
  46.  
  47. </head>
  48.  
  49. <body>
  50.  
  51. <div class="fakeloader"></div>
  52.  
  53. <form action="/upload" method="post" enctype="multipart/form-data">
  54. <div class="uploadImgBtn" id="uploadImgBtn">
  55. <input class="uploadImg" type="file" name="file" multiple id="file">
  56. </div>
  57. <div>合成全景图片的名字<input type="text" name="title" id="title"></div>
  58. <input type="submit" onclick="haha()" value="上传">
  59. </form>
  60.  
  61. <script src="js/jquery-1.11.0.min.js"></script>
  62. <script src="js/fakeLoader.min.js"></script>
  63.  
  64. <script>
  65.  
  66. function haha() {
  67. var html01='<h4>全景图正在合成请稍等...</h4>';
  68. $(".fakeloader").append($(html01));
  69. $(".fakeloader").fakeLoader({
  70. timeToHide:1200000,
  71. bgColor:"#d9d2e9",
  72. spinner:"spinner2"
  73. });
  74. }
  75. $(document).ready(function(){
  76.  
  77. //为外面的盒子绑定一个点击事件
  78. $("#uploadImgBtn").click(function(){
  79. /*
  80. 1、先获取input标签
  81. 2、给input标签绑定change事件
  82. 3、把图片回显
  83. */
  84. // 1、先回去input标签
  85. var $input = $("#file");
  86. console.log($input)
  87. // 2、给input标签绑定change事件
  88. $input.on("change" , function(){
  89. console.log(this)
  90. //补充说明:因为我们给input标签设置multiple属性,因此一次可以上传多个文件
  91. //获取选择图片的个数
  92. var files = this.files;
  93. var length = files.length;
  94. console.log("选择了"+length+"张图片");
  95. //3、回显
  96. $.each(files,function(key,value){
  97. //每次都只会遍历一个图片数据
  98. var div = document.createElement("div"),
  99. img = document.createElement("img");
  100. div.className = "pic";
  101.  
  102. var fr = new FileReader();
  103. fr.onload = function(){
  104. img.src=this.result;
  105. div.appendChild(img);
  106. document.body.appendChild(div);
  107. }
  108. fr.readAsDataURL(value);
  109. })
  110.  
  111. })
  112.  
  113. //4、我们把当前input标签的id属性remove
  114. $input.removeAttr("id");
  115. //我们做个标记,再class中再添加一个类名就叫test
  116. var newInput = '<input class="uploadImg test" type="file" name="file" multiple id="file">';
  117. $(this).append($(newInput));
  118.  
  119. })
  120.  
  121. })
  122.  
  123. </script>
  124. </body>
  125. </html>

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

 

java实现,使用opencv合成全景图,前端使用krpano展示的更多相关文章

  1. java 实现基于opencv全景图合成

    因项目需要,自己做了demo,从中学习很多,所以分享出来,希望有这方面需求的少走一些弯路,opencv怎么安装网上教程多多,这里不加详细说明,我安装的opencv-3.3.0 如上图所示,找到相应的j ...

  2. OpenCV4Android开发之旅(一)----OpenCV2.4简介及 app通过Java接口调用OpenCV的示例

    转自:  http://blog.csdn.net/yanzi1225627/article/details/16917961 开发环境:windows+ADT Bundle+CDT+OpenCV-2 ...

  3. 基于OpenCv和swing的图片/视频展示Java实现

    基于OpenCv和swing实现图片/视频的展示 图片的展示 swing展示图片,多为操作BufferedImage,这里要关注的核心是将Mat转为BufferedImage. 代码如下: publi ...

  4. [Android Studio] Using Java to call OpenCV

    Environment: Android studio 2.2.3, OpenCV 2.4.9 For Android, Android 6 with api 23 for X86 一.File: b ...

  5. java中使用opencv

    Java + opencv学习:在Eclipse下配置基于Java的OpenCV开发环境 2016-04-08 17:43 6491人阅读 评论(0) 收藏 举报  分类: OpenCV学习(10)  ...

  6. Java后端传Long类型给前端导致的精度丢失

    问题:实体属性是Long类型,在后端值本来是1119102511023023410,但是返回给前端的却是1119102511023023400 解决方案:添加序列化注解 import com.fast ...

  7. python+java全栈工程师 转 向前端的路

    python的优点 简单 简单 简单 我目前在公司用python 1. 增加odoo的各种业务,成本核算.自动跑单.自动备份数据库之类的 ----odoo是国外大佬做的一个开源erp 用的python ...

  8. python利用opencv合成模糊图像

    之前需要评估图像质量来筛选成像质量不错的图片,去除由于对焦,运动等造成的模糊图像,所以在构建数据集的时候考虑用opencv对清晰的图片进行处理获得模糊的图片从而进行训练. 1) 运动模糊图像 一般来说 ...

  9. ImageCombiner - Java服务端图片合成的工具包,好用!

    自己的第一个也是唯一一个开源项目,因为平时比较懒,很少做宣传,今天刚好突破160个star,发到园子里推荐给大家,算是庆祝一下,哈. 项目地址:https://gitee.com/opensource ...

随机推荐

  1. windows下zookeeper安装和使用

    一,下载 可以到官网下载 官方主页: https://zookeeper.apache.org/ 二,安装 解压即可 三,配置 需要java环境,在加压出来的文件夹中找到zoo_sample.cfg文 ...

  2. SpringBoot起飞系列-使用idea搭建环境(二)

    一.环境配置 安装idea的教程就不说了,相信大家肯定已经安装好了,另外maven环境肯定也安装好了,那么我们就开始使用idea开发工具来创建一个springboot的web项目,这里奉上一个idea ...

  3. 用docker部署RabbitMQ环境

    前置条件: 已经安装好docker 1.查找镜像(有2种方式) ①登录rabbitmq官网找到docker镜像,选择想要的镜像的tag https://www.rabbitmq.com/downloa ...

  4. Nginx反向代理之动静分离

    我们已经知道了什么是正向代理与反向代理,这次我们就讲一下Nginx的动静分离的案例,其实质运用的就是反向代理,专门用一台服务器代理服务器上的图片资源. 想使用代理必然要配置代理,配置反向代理,必须要用 ...

  5. asp.net core3.0 mvc 用 autofac

    好久没有写文章了,最近在用.net core3.0,一些开发中问题顺便记录: 1.首先nuget引入 Autofac Autofac.Extensions.DependencyInjection 2. ...

  6. mysql 遍历方式

    mysql遍历方式可以使用while,loop和repeat来实现,示例如下: BEGIN ; # WHILE DO ; END WHILE; # SELECT i; # LOOP optLoop:L ...

  7. plsql导入导出表结构和数据对象

    一.Tools的导出表结构:export User objects 二.Tools的Export Tables选项 导出表数据:export tables (选择:exp.exe) 三. 导入表结构: ...

  8. VR中的Redirection

    在虚拟现实(Virtual Reality,VR)中,很重要的一点就是用户的在虚拟环境中的漫游(navigation).除了固定视点的VR电影,一般的VR应用,特别是游戏或者其他交互式的应用,都会依赖 ...

  9. Java 学习笔记之 Thread运行过程分析

    Thread运行过程分析: 以下是一个最普通的Thread实现过程,我们今天就来看仔细分析下他是如何运行的. public class ThreadRunMain { public static vo ...

  10. 快学Scala 第九课 (伴生对象和枚举)

    Scala没有静态方法和静态字段, 你可以用object这个语法结构来达到同样的目的. 对象的构造器只有在第一次被使用时才调用. 伴生对象apply方法: 类和它的伴生对象可以互相访问私有特性,他们必 ...