Browse Source

Add an additional level of zoom

Note that this *really* doesn't scale: tile generation has to manipulate
really large images (more than 3 GB RAM for large panorama), and it
produces a hell of a lot of tiles.  And this is for just one additional
level of zoom.

We should instead find a solution where the browser upscales the tiles
when we need more zoom than the base zoom level.
Baptiste Jonglez 9 years ago
parent
commit
7f1e17c9cd

+ 5 - 2
panorama/gen_tiles.py

@@ -19,14 +19,17 @@ import tempfile
 import PIL.Image
 import PIL.Image
 
 
 
 
-def gen_tiles(image, output_path, min_scale=0, max_scale=8, crop_x=256, crop_y=256):
+def gen_tiles(image, output_path, min_scale=-1, max_scale=8, crop_x=256, crop_y=256):
     orig_im = PIL.Image.open(image)
     orig_im = PIL.Image.open(image)
     for scale in range(min_scale, max_scale + 1):
     for scale in range(min_scale, max_scale + 1):
         if scale == 0:
         if scale == 0:
             im = orig_im
             im = orig_im
-        else:
+        elif scale > 0:
             scaled_size = (orig_im.size[0] >> scale, orig_im.size[1] >> scale)
             scaled_size = (orig_im.size[0] >> scale, orig_im.size[1] >> scale)
             im = orig_im.resize(scaled_size)
             im = orig_im.resize(scaled_size)
+        else:
+            scaled_size = (orig_im.size[0] << (-scale), orig_im.size[1] << (-scale))
+            im = orig_im.resize(scaled_size, resample=PIL.Image.BILINEAR)
         for x in range(0, im.size[0], crop_x):
         for x in range(0, im.size[0], crop_x):
             for y in range(0, im.size[1], crop_y):
             for y in range(0, im.size[1], crop_y):
                 geom = (x, y, min(im.size[0], x + crop_x),
                 geom = (x, y, min(im.size[0], x + crop_x),

+ 7 - 3
panorama/models.py

@@ -157,9 +157,13 @@ class Panorama(ReferencePoint):
         """Hack to feed the current js code with tiles data (we should use the
         """Hack to feed the current js code with tiles data (we should use the
         JSON API instead, and get rid of this function)"""
         JSON API instead, and get rid of this function)"""
         data = dict()
         data = dict()
-        for zoomlevel in range(9):
-            width = self.image_width >> zoomlevel
-            height = self.image_height >> zoomlevel
+        for zoomlevel in range(-1, 9):
+            if zoomlevel >= 0:
+                width = self.image_width >> zoomlevel
+                height = self.image_height >> zoomlevel
+            else:
+                width = self.image_width << (-zoomlevel)
+                height = self.image_height << (-zoomlevel)
             d = dict()
             d = dict()
             d["tile_width"] = d["tile_height"] = 256
             d["tile_width"] = d["tile_height"] = 256
             # Python3-style division
             # Python3-style division

+ 13 - 5
panorama/static/panorama/js/pano.js

@@ -270,11 +270,19 @@ function erase_point() {
  * ex: 3 -> "003"
  * ex: 3 -> "003"
  */
  */
 function zero_pad(number) {
 function zero_pad(number) {
-	var temp = number.toString(10);
-	while (temp.length < 3) {
-		temp = '0' + temp;
-	}
-	return temp;
+    var temp = Math.abs(number).toString(10);
+    var max_len;
+    if (number < 0)
+        max_len = 2;
+    else
+        max_len = 3;
+    while (temp.length < max_len) {
+	temp = '0' + temp;
+    }
+    if (number < 0)
+        return '-' + temp;
+    else
+        return temp;
 }
 }
 
 
 function get_file_name(x, y, z) { // recherche du fichier correspondant au zoom et à la position
 function get_file_name(x, y, z) { // recherche du fichier correspondant au zoom et à la position

+ 1 - 1
panorama/templates/panorama/view.html

@@ -46,7 +46,7 @@
     </canvas>
     </canvas>
 
 
     <fieldset id="control"><legend>contrôle</legend>
     <fieldset id="control"><legend>contrôle</legend>
-      <label>Zoom : <input type="range" min="0" max="2" value="2" id="zoom_ctrl"/></label>
+      <label>Zoom : <input type="range" min="-1" max="2" value="2" id="zoom_ctrl"/></label>
       <label>Cap : <input type="number" min="0" max="360" step="10" value="0" autofocus="" id="angle_ctrl"/></label>
       <label>Cap : <input type="number" min="0" max="360" step="10" value="0" autofocus="" id="angle_ctrl"/></label>
       <label>Élévation : <input type="number" min="-90" max="90" step="1" value="0" autofocus="" id="elvtn_ctrl"/></label>
       <label>Élévation : <input type="number" min="-90" max="90" step="1" value="0" autofocus="" id="elvtn_ctrl"/></label>
     </fieldset>
     </fieldset>