{"id":3160,"date":"2018-05-14T04:13:21","date_gmt":"2018-05-14T04:13:21","guid":{"rendered":"https:\/\/max-drake.cc\/?p=3160"},"modified":"2019-02-12T21:24:28","modified_gmt":"2019-02-12T21:24:28","slug":"python-6-creating-html-pages-for-360-panorama-files","status":"publish","type":"post","link":"https:\/\/max-drake.cc\/?p=3160","title":{"rendered":"Python 6. How to automate the creation of HTML pages for 360 Panorama&#8217;s"},"content":{"rendered":"<p>Panoramic files (360\/180) can be viewed directly with a programme such as Paint, but they do not make much sense.<\/p>\n<p><img decoding=\"async\" class=\"wp-image-3192 aligncenter lazyload\" data-src=\"https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp05-1024x738.jpg\" alt=\"\" width=\"1262\" height=\"910\" data-srcset=\"https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp05-1024x738.jpg 1024w, https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp05-300x216.jpg 300w, https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp05-768x554.jpg 768w\" data-sizes=\"(max-width: 1262px) 100vw, 1262px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1262px; --smush-placeholder-aspect-ratio: 1262\/910;\" \/><\/p>\n<p>You need a specific Panoramic programme to read the files correctly.<\/p>\n<p>I use the FREE<strong> <a href=\"https:\/\/photo-sphere-viewer.js.org\/\" target=\"_blank\" rel=\"noopener\">photo sphere viewer<\/a> <\/strong>by Jeremy Heleine. Follow the link to see the demos.<\/p>\n<p>The method that the programme uses is to display the file to a web browser. It creates a html file and calls a mainly javascript programme to run the image viewer inside the web page. Each image needs a distinct html file.<\/p>\n<p>I had previously experimented with using a PDF with hyperlinks to link a floor plan with room photospheres. See my post <a href=\"https:\/\/max-drake.cc\/2017\/05\/22\/panorama-photos-spaces-linked-pdf-visualise-space\/\" target=\"_blank\" rel=\"noopener\"><strong>here<\/strong><\/a>. One issue with the PDF with hyperlinks was that you had the pdf open and the hyperlinks, when clicked, opened in the browser in the background. You needed to switch between the 2 programmes to move between the images, which is not very elegant. I wondered about using a more seemless method to transition between images.<\/p>\n<p>There is a sophisticated tool, <a href=\"https:\/\/matterport.com\/\" target=\"_blank\" rel=\"noopener\">Matterport<\/a>, on the market that uses an expensive camera &amp; you upload everything to their cloud and rent their cloud space for others to view.<\/p>\n<p>The simplicity of the method using Jeremy Heleine&#8217;s photo sphere viewer method is that you can either self host or even give someone a copy of the files on a USB. Reading the image files from a LAN, local PC or USB is much quicker as files are in the 4Mb range and are slow to download over the internet.<\/p>\n<p>One powerful aspect of the Matterport process was the linking of the images, so you can flow from one to another via links. I had first got enthusiastic about Panoramic photo&#8217;s about a year ago, and at that time there were no FREE panorama viewers that would allow hotlinks between\u00a0 images, but Jeremy Heleine&#8217;s photo sphere viewer has been updated to allow this to happen. So you are now able to stitch the panoramas to allow for a linked tour through spaces.<\/p>\n<h3>The process for a basic set of Panoramas.<\/h3>\n<p>See the final result <a href=\"https:\/\/pir2.tk\/web\/data\/Omori360\/Data\/examples\/Ground%20Dining.html\" target=\"_blank\" rel=\"noopener\"><strong>HERE<\/strong><\/a>.( <em>Very slow to load as large file sizes<\/em>).<\/p>\n<p>After taking panoramic photos in all the rooms, you then have to create a HTML file for each image. Most of it is block code and there are only a few points that change within the HTML file, One being the title (that shows up on the tab on the web browser) and the other is the specific file name.<\/p>\n<p>If you have hotspots or wish to put text information at a point in an image, you have to find the actual pixel coordinates and make a specific marker for each particular image. This is more tailored and is specific to each individual image.<\/p>\n<p>So of the 2 parts of the process, the first can be automated, the second is bespoke. But if you can create all of the files programmatically this cuts down time spent on doing the mundane and you can focus on the tailored area of linking the images together.<\/p>\n<p>Here is the basic HTML file that I started with:<\/p>\n<p><img decoding=\"async\" class=\"wp-image-3162 aligncenter lazyload\" data-src=\"https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/htm01-977x1024.jpg\" alt=\"\" width=\"1287\" height=\"1349\" data-srcset=\"https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/htm01-977x1024.jpg 977w, https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/htm01-286x300.jpg 286w, https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/htm01-768x805.jpg 768w, https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/htm01.jpg 1224w\" data-sizes=\"(max-width: 1287px) 100vw, 1287px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1287px; --smush-placeholder-aspect-ratio: 1287\/1349;\" \/><\/p>\n<p>As you can see, there are only 2 points where the script needs to change to accommodate differences between the files, the title and the actual image name.<\/p>\n<p>To simplify further, I gave the tile a generic name of &#8220;Panorama&#8221; so I only needed to change the\u00a0 actual file name. Also, I used a RELATIVE PATH to the image file. This allows for the directory to be used on a USB, Local PC or LAN or over the web as it is a relation to where the HTML activated file and the image file are in relation to each other. This saves a lot of problems with pathing issues (something that is a big pain on the PDF hyperlinks to the HTML files.<\/p>\n<h3>Getting the files.<\/h3>\n<p>The photos have this type of naming convention. It does not tell you very much.<\/p>\n<p><img decoding=\"async\" class=\"wp-image-3174 aligncenter lazyload\" data-src=\"https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp01.jpg\" alt=\"\" width=\"1274\" height=\"537\" data-srcset=\"https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp01.jpg 795w, https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp01-300x126.jpg 300w, https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp01-768x324.jpg 768w\" data-sizes=\"(max-width: 1274px) 100vw, 1274px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1274px; --smush-placeholder-aspect-ratio: 1274\/537;\" \/><\/p>\n<p>One method is to rename the files using a free programme such as <a href=\"https:\/\/www.advancedrenamer.com\/\" target=\"_blank\" rel=\"noopener\"><strong>Advanced Renamer<\/strong><\/a> to Batch rename the files.<\/p>\n<p><img decoding=\"async\" class=\"wp-image-3175 aligncenter lazyload\" data-src=\"https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp02-1024x806.jpg\" alt=\"\" width=\"1256\" height=\"988\" data-srcset=\"https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp02-1024x806.jpg 1024w, https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp02-300x236.jpg 300w, https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp02-768x605.jpg 768w, https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp02.jpg 1572w\" data-sizes=\"(max-width: 1256px) 100vw, 1256px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1256px; --smush-placeholder-aspect-ratio: 1256\/988;\" \/><\/p>\n<p>Which is fine if you want an iterative number code for your file names and they do not need to relate to what is in the actual images (this works with PDF hyperlinks as you are using &#8220;Click&#8221; to open the file, so do not need to read the file name.<\/p>\n<p>Another method is to look at each file and give it a name such as Kitchen.jpg, Hall.jpg etc, so that if someone is opening the files from a list, they can see where the image relates to.\u00a0At the end of the day, you need a list of files so that you can automate the creation of the files.<\/p>\n<p>A simple method of doing this is with Explorer and Excel.<\/p>\n<p>Open Explorer in the file directory that you want, use <strong>Ctrl A<\/strong> to select all the files, then use <strong>Shift (Right Mouse Click)<\/strong> and select <strong>&#8220;Copy as Path&#8221;<\/strong><img decoding=\"async\" class=\"wp-image-3176 alignnone lazyload\" data-src=\"https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp03-997x1024.jpg\" alt=\"\" width=\"1283\" height=\"1317\" data-srcset=\"https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp03-997x1024.jpg 997w, https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp03-292x300.jpg 292w, https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp03-768x789.jpg 768w, https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp03.jpg 1026w\" data-sizes=\"(max-width: 1283px) 100vw, 1283px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1283px; --smush-placeholder-aspect-ratio: 1283\/1317;\" \/><\/p>\n<p>This will select all the files (and their paths ) and copy them to clipboard.<\/p>\n<p>You could paste them to a .TXT file, but I open up Excel &amp; Paste them into excel to save as a CSV file so that you can edit path with FIND\/REPLACE.<\/p>\n<p><img decoding=\"async\" class=\"wp-image-3178 alignnone lazyload\" data-src=\"https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/ipm04.jpg\" alt=\"\" width=\"1277\" height=\"914\" data-srcset=\"https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/ipm04.jpg 999w, https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/ipm04-300x215.jpg 300w, https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/ipm04-768x550.jpg 768w\" data-sizes=\"(max-width: 1277px) 100vw, 1277px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1277px; --smush-placeholder-aspect-ratio: 1277\/914;\" \/><\/p>\n<p>The initial\u00a0 copy as path gives you strings like this:<\/p>\n<p>&#8220;C:\\Users\\drake\\Downloads\\_Omori 360 NEW hotspots\\Data\\examples\\2High\\Stairwell Landing 2.jpg&#8221;<br \/>\n&#8220;C:\\Users\\drake\\Downloads\\_Omori 360 NEW hotspots\\Data\\examples\\2High\\Upper Bathroom.jpg&#8221;<\/p>\n<p>I would then use Excel find\/replace to shorten them to :<\/p>\n<p>&#8220;Stairwell Landing 2.jpg&#8221;<br \/>\n&#8220;Upper Bathroom.jpg&#8221;<\/p>\n<p>but then I found my files had names like:<\/p>\n<p>Staiwell Landing 2.jpg.html<br \/>\nUpper Bathroom.jpg.html<\/p>\n<p>so it was better to use find\/replace to shorten them to :<\/p>\n<p>&#8220;Stairwell Landing 2&#8221;<br \/>\n&#8220;Upper Bathroom&#8221;<\/p>\n<p>so my files had names like:<\/p>\n<p>Staiwell Landing 2.html<br \/>\nUpper Bathroom.html<\/p>\n<p>which was a lot better. I had to add\u00a0 the &#8220;.jpg&#8221; to the concatenation process for the image file later in the code.<\/p>\n<p>This method also allows you to save as CSV for Python read csv method.<\/p>\n<h3>The Simple Python Code<\/h3>\n<p>We now have a list of files that we can iterate through. This is the Python code that I used to read a csv file, for each item it then goes through and creates an HTML file with selected code.<\/p>\n<pre>s='''\r\n&lt;!DOCTYPE html&gt;\r\n&lt;html&gt;\r\n   &lt;head&gt;\r\n      &lt;meta charset=\"utf-8\" \/&gt;\r\n       &lt;title&gt;Panorama&lt;\/title&gt;\r\n      &lt;meta name=\"viewport\" content=\"initial-scale=1.0\" \/&gt;\r\n      &lt;script src=\"three.min.js\"&gt;&lt;\/script&gt;\r\n      &lt;script src=\"photo-sphere-viewer.min.js\"&gt;&lt;\/script&gt;\r\n      &lt;style&gt;\r\n         html, body {\r\n            margin: 0;\r\n            width: 100%;\r\n            height: 100%;\r\n            overflow: hidden;\r\n         }\r\n         #container {\r\n            width: 100%;\r\n            height: 100%;\r\n         }\r\n      &lt;\/style&gt;\r\n   &lt;\/head&gt;\r\n   &lt;body&gt;\r\n&lt;div id=\"container\"&gt;&lt;\/div&gt;\r\n      &lt;script&gt;\r\n         var div = document.getElementById('container');\r\n         var PSV = new PhotoSphereViewer({\r\n'''\r\np='''\r\n               container: div,\r\n               time_anim: 3000,\r\n               usexmpdata: false,\r\n               navbar: true,\r\n               navbar_style: {\r\n                  backgroundColor: 'rgba(58, 67, 77, 0.7)'\r\n               },\r\n            });\r\n      &lt;\/script&gt;\r\n   &lt;\/body&gt;\r\n&lt;\/html&gt;\r\n'''\r\nwith open('lowOrig.csv') as fo:\r\n        for x in fo.read().split(\"\\n\"):\r\n                        with open(x+\".html\",'w')as opf:\r\n                         opf.write(s+\"panorama:'\"+\".\/1Low\/\"+ x +\"',\"+p)\r\n                         opf.close()\r\n        fo.close()<\/pre>\n<p>So I could make 2 code blocks, &#8220;s&#8221; and &#8220;p&#8221;.\u00a0 Basically a variable that is a string for the top and bottom parts of the code.<\/p>\n<p>&#8220;x&#8221; is the image file name and I use it<\/p>\n<p>1\/ To make a file by the &#8220;x&#8221; name with a .html type<\/p>\n<p>2\/ I concatenate (s+&#8221;panorama:'&#8221;+&#8221;.\/1Low\/&#8221;+ x +&#8221;&#8216;,&#8221;+p) to write in the relative path &amp; image file name between the 2 blocks of text, namely &#8220;s&#8221; and &#8220;p&#8221;.<\/p>\n<p>I then move the html files to the correct sub-directory to run (they are created in the python directory where I am writing the python code) and then they are ready to run.<\/p>\n<p>This is the basic code and it works well. I have been adding bits to it to make it do more and hope to refine it even further.<\/p>\n<h3>End thoughts<\/h3>\n<p>As I have the basic code working now, I can always elaborate on it and add more variables to make it create more individual HTML files, like using the file name from the CSV file to give the title that name too.<\/p>\n<p>It would be good to see if I could compile the Python code so that others can use it easily. I have attempted to do that in this <a href=\"https:\/\/max-drake.cc\/2018\/05\/06\/python-4-3dpdfs-csvs-pandas-exes\/\" target=\"_blank\" rel=\"noopener\"><strong>post<\/strong><\/a> but with no success to date.<\/p>\n<p>There are the html &lt;area&gt; tag links that have a bit of complexity to them that may be a ripe area for scripting with python too that could simplify the process further. For another day.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Panoramic files (360\/180) can be viewed directly with a programme such as Paint, but they do not make much sense. You need a specific Panoramic programme to read the files correctly. I use the FREE photo sphere viewer by Jeremy Heleine. Follow the link to see the demos. The method that the programme uses is [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3213,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[130,34,10,12,13,29],"tags":[],"class_list":["post-3160","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-panorama-360-images","category-python","category-surveying","category-visualisation","category-visualise-building-condition","category-web"],"featured_image_src":"https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp08.jpg","featured_image_src_square":"https:\/\/max-drake.cc\/wp-content\/uploads\/2018\/05\/imp08.jpg","author_info":{"display_name":"Max Drake","author_link":"https:\/\/max-drake.cc\/?author=1"},"_links":{"self":[{"href":"https:\/\/max-drake.cc\/index.php?rest_route=\/wp\/v2\/posts\/3160","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/max-drake.cc\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/max-drake.cc\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/max-drake.cc\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/max-drake.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3160"}],"version-history":[{"count":0,"href":"https:\/\/max-drake.cc\/index.php?rest_route=\/wp\/v2\/posts\/3160\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/max-drake.cc\/index.php?rest_route=\/wp\/v2\/media\/3213"}],"wp:attachment":[{"href":"https:\/\/max-drake.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3160"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/max-drake.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3160"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/max-drake.cc\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3160"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}