Add stuff implemented on server side
This commit is contained in:
parent
7a4861cd83
commit
bb20dc3119
4 changed files with 372 additions and 0 deletions
163
eyerevolutionsteal/__init__.py
Normal file
163
eyerevolutionsteal/__init__.py
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
import PIL.Image
|
||||||
|
import urllib.request
|
||||||
|
import io
|
||||||
|
import math
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
import pathlib
|
||||||
|
import os
|
||||||
|
from stitching import tiles_to_equirectangular_blender, multistitch
|
||||||
|
|
||||||
|
def eyerevolution_normalize(url):
|
||||||
|
'''
|
||||||
|
Takes the URL of any image in a eyerevolution panorama and returns a string
|
||||||
|
with substitutable variables for image IDs.
|
||||||
|
|
||||||
|
:param url: URL of an image contained in a eyerevolution panorama
|
||||||
|
:return: string with substitutable variables or False if URL invalid
|
||||||
|
'''
|
||||||
|
|
||||||
|
try:
|
||||||
|
with urllib.request.urlopen(url) as res:
|
||||||
|
assert res.getcode() == 200
|
||||||
|
|
||||||
|
parts = url.split("/")
|
||||||
|
|
||||||
|
assert "_" in parts[-1]
|
||||||
|
parts[-1] = "l%i_%s_%i_%i.jpg"
|
||||||
|
parts[-2] = "%i"
|
||||||
|
parts[-3] = "l%i"
|
||||||
|
parts[-4] = "%s"
|
||||||
|
|
||||||
|
return "/".join(parts)
|
||||||
|
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def eyerevolution_getmaxzoom(schema):
|
||||||
|
'''
|
||||||
|
Takes a normalized string from eyerevolution_normalize() and returns the maximum
|
||||||
|
zoom level available.
|
||||||
|
|
||||||
|
:param schema: normalized URL format output by eyerevolution_normalize()
|
||||||
|
:return: int value of largest available zoom level
|
||||||
|
'''
|
||||||
|
|
||||||
|
l = 1
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
url = schema % ("f", l+1, 1, l+1, "f", 1, 1)
|
||||||
|
with urllib.request.urlopen(url) as res:
|
||||||
|
assert res.getcode() == 200
|
||||||
|
l += 1
|
||||||
|
except:
|
||||||
|
return l
|
||||||
|
|
||||||
|
def eyerevolution_export(schema):
|
||||||
|
'''
|
||||||
|
Takes a normalized string from eyerevolution_normalize() and returns a list of
|
||||||
|
lists of lists containing all images fit for passing into stitch().
|
||||||
|
|
||||||
|
:param schema: normalized URL format output by eyerevolution_normalize()
|
||||||
|
:return: list of lists of lists of PIL.Image() objects for multistitch()
|
||||||
|
'''
|
||||||
|
|
||||||
|
# /{cube}/l{zoom}/{y}/l{zoom}_{cube}_{y}_{x}.jpg
|
||||||
|
|
||||||
|
maxzoom = eyerevolution_getmaxzoom(schema)
|
||||||
|
output = []
|
||||||
|
|
||||||
|
for tile in "frblud":
|
||||||
|
t_array = []
|
||||||
|
y = 1
|
||||||
|
|
||||||
|
while True:
|
||||||
|
r_array = []
|
||||||
|
x = 1
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
# raise Exception(schema % (tile, maxzoom, y, maxzoom, tile, y, x))
|
||||||
|
res = urllib.request.urlopen(schema % (tile, maxzoom, y, maxzoom, tile, y, x))
|
||||||
|
assert res.getcode() == 200
|
||||||
|
fo = io.BytesIO(res.read())
|
||||||
|
img = PIL.Image.open(fo)
|
||||||
|
r_array.append(img)
|
||||||
|
x += 1
|
||||||
|
except Exception as e:
|
||||||
|
# raise
|
||||||
|
break
|
||||||
|
|
||||||
|
if not r_array:
|
||||||
|
break
|
||||||
|
|
||||||
|
t_array.append(r_array)
|
||||||
|
y += 1
|
||||||
|
|
||||||
|
output.append(t_array)
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
def eyerevolution_export_simple(url):
|
||||||
|
'''
|
||||||
|
Exports eyerevolution panoramas which only consist of six complete tiles. Takes
|
||||||
|
the URL of one of these images and returns a list of PIL.Image objects
|
||||||
|
|
||||||
|
:param url: URL of one of the images
|
||||||
|
:return: list of PIL.Image objects
|
||||||
|
'''
|
||||||
|
|
||||||
|
output = []
|
||||||
|
|
||||||
|
for i in "frblud":
|
||||||
|
cur = url[:-5] + i + url[-4:]
|
||||||
|
res = urllib.request.urlopen(cur)
|
||||||
|
assert res.getcode() == 200
|
||||||
|
fo = io.BytesIO(res.read())
|
||||||
|
output += [PIL.Image.open(fo)]
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
def eyerevolution_make_tiles(url):
|
||||||
|
'''
|
||||||
|
Determines the type of processing needed to build the six tiles, then
|
||||||
|
creates and returns them.
|
||||||
|
|
||||||
|
:param urL: URL of any image in a eyerevolution panorama
|
||||||
|
:return: list of stitched PIL.Image objects (back, right, front, left, top,
|
||||||
|
bottom)
|
||||||
|
'''
|
||||||
|
|
||||||
|
parts = url.split("/")
|
||||||
|
|
||||||
|
try:
|
||||||
|
if "pano_" in parts[-1]:
|
||||||
|
return eyerevolution_export_simple(url)
|
||||||
|
else:
|
||||||
|
schema = eyerevolution_normalize(url)
|
||||||
|
images = eyerevolution_export(schema)
|
||||||
|
return multistitch(images)
|
||||||
|
|
||||||
|
except:
|
||||||
|
raise
|
||||||
|
raise ValueError("%s does not seem to be a valid eyerevolution URL." % url)
|
||||||
|
|
||||||
|
|
||||||
|
def eyerevolution_to_equirectangular(url, rotation=[0,0,0], resolution=[3840,1920]):
|
||||||
|
'''
|
||||||
|
Takes the URL of any image in a eyerevolution panorama and returns a finished
|
||||||
|
stitched image.
|
||||||
|
|
||||||
|
:param url: Image URL
|
||||||
|
:return: PIL.Image object containing the final image
|
||||||
|
'''
|
||||||
|
|
||||||
|
stitched = eyerevolution_make_tiles(url)
|
||||||
|
function = tiles_to_equirectangular_blender
|
||||||
|
|
||||||
|
rx, ry, rz = rotation
|
||||||
|
width, height = resolution
|
||||||
|
return function(*stitched, rx=rx, ry=ry, rz=rz, width=width, height=height)
|
||||||
|
|
||||||
|
process_url = eyerevolution_to_equirectangular
|
|
@ -15,6 +15,9 @@ regs = {
|
||||||
r"l\d_[frblud]_\d\d_\d\d.jpg": "giraffesteal",
|
r"l\d_[frblud]_\d\d_\d\d.jpg": "giraffesteal",
|
||||||
r"=x\d-y\d-z\d": "googlesteal",
|
r"=x\d-y\d-z\d": "googlesteal",
|
||||||
r"[brflud]\/\d\/\d_\d\.jpg": "tdvsteal",
|
r"[brflud]\/\d\/\d_\d\.jpg": "tdvsteal",
|
||||||
|
"c\d_l\d_\d_\d.jpg": "pindorasteal",
|
||||||
|
"/[frblud]/l\d/\d/l\d_[frblud]_\d_\d.jpg": "eyerevolutionsteal",
|
||||||
|
"(pos|neg)[xyz]\.jpg": "xvrsteal",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
136
pindorasteal/__init__.py
Normal file
136
pindorasteal/__init__.py
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
import PIL.Image
|
||||||
|
import urllib.request
|
||||||
|
import io
|
||||||
|
import math
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
import pathlib
|
||||||
|
import os
|
||||||
|
from stitching import tiles_to_equirectangular_blender, multistitch
|
||||||
|
|
||||||
|
def pindora_normalize(url):
|
||||||
|
'''
|
||||||
|
Takes the URL of any image in a pindora panorama and returns a string
|
||||||
|
with substitutable variables for image IDs.
|
||||||
|
|
||||||
|
:param url: URL of an image contained in a pindora panorama
|
||||||
|
:return: string with substitutable variables or False if URL invalid
|
||||||
|
'''
|
||||||
|
|
||||||
|
try:
|
||||||
|
with urllib.request.urlopen(url) as res:
|
||||||
|
assert res.getcode() == 200
|
||||||
|
|
||||||
|
parts = url.split("/")
|
||||||
|
|
||||||
|
assert "_" in parts[-1]
|
||||||
|
parts[-1] = "c%i_l%i_%i_%i.jpg"
|
||||||
|
|
||||||
|
return "/".join(parts)
|
||||||
|
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def pindora_getmaxzoom(schema):
|
||||||
|
'''
|
||||||
|
Takes a normalized string from pindora_normalize() and returns the maximum
|
||||||
|
zoom level available.
|
||||||
|
|
||||||
|
:param schema: normalized URL format output by pindora_normalize()
|
||||||
|
:return: int value of largest available zoom level
|
||||||
|
'''
|
||||||
|
|
||||||
|
l = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
url = schema % (0, l+1, 0, 0)
|
||||||
|
with urllib.request.urlopen(url) as res:
|
||||||
|
assert res.getcode() == 200
|
||||||
|
l += 1
|
||||||
|
except:
|
||||||
|
return l
|
||||||
|
|
||||||
|
def pindora_export(schema):
|
||||||
|
'''
|
||||||
|
Takes a normalized string from pindora_normalize() and returns a list of
|
||||||
|
lists of lists containing all images fit for passing into stitch().
|
||||||
|
|
||||||
|
:param schema: normalized URL format output by pindora_normalize()
|
||||||
|
:return: list of lists of lists of PIL.Image() objects for multistitch()
|
||||||
|
'''
|
||||||
|
|
||||||
|
maxzoom = 0 # ? – pindora_getmaxzoom(schema)
|
||||||
|
|
||||||
|
# c{cube}_l{z}_{y}_{x}.jpg
|
||||||
|
|
||||||
|
output = []
|
||||||
|
|
||||||
|
for tile in range(6):
|
||||||
|
t_array = []
|
||||||
|
y = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
r_array = []
|
||||||
|
x = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
res = urllib.request.urlopen(schema % (tile, maxzoom, y, x))
|
||||||
|
assert res.getcode() == 200
|
||||||
|
fo = io.BytesIO(res.read())
|
||||||
|
img = PIL.Image.open(fo)
|
||||||
|
r_array.append(img)
|
||||||
|
x += 1
|
||||||
|
except Exception as e:
|
||||||
|
break
|
||||||
|
|
||||||
|
if not r_array:
|
||||||
|
break
|
||||||
|
|
||||||
|
t_array.append(r_array)
|
||||||
|
y += 1
|
||||||
|
|
||||||
|
output.append(t_array)
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
def pindora_make_tiles(url):
|
||||||
|
'''
|
||||||
|
Determines the type of processing needed to build the six tiles, then
|
||||||
|
creates and returns them.
|
||||||
|
|
||||||
|
:param urL: URL of any image in a pindora panorama
|
||||||
|
:return: list of stitched PIL.Image objects (back, right, front, left, top,
|
||||||
|
bottom)
|
||||||
|
'''
|
||||||
|
|
||||||
|
parts = url.split("/")
|
||||||
|
|
||||||
|
try:
|
||||||
|
schema = pindora_normalize(url)
|
||||||
|
images = pindora_export(schema)
|
||||||
|
return multistitch(images)
|
||||||
|
|
||||||
|
except:
|
||||||
|
raise
|
||||||
|
raise ValueError("%s does not seem to be a valid pindora URL." % url)
|
||||||
|
|
||||||
|
|
||||||
|
def pindora_to_equirectangular(url, rotation=[0,0,0], resolution=[3840,1920]):
|
||||||
|
'''
|
||||||
|
Takes the URL of any image in a pindora panorama and returns a finished
|
||||||
|
stitched image.
|
||||||
|
|
||||||
|
:param url: Image URL
|
||||||
|
:return: PIL.Image object containing the final image
|
||||||
|
'''
|
||||||
|
|
||||||
|
stitched = pindora_make_tiles(url)
|
||||||
|
function = tiles_to_equirectangular_blender
|
||||||
|
|
||||||
|
rx, ry, rz = rotation
|
||||||
|
width, height = resolution
|
||||||
|
return function(*stitched, rx=rx, ry=ry, rz=rz, width=width, height=height)
|
||||||
|
|
||||||
|
process_url = pindora_to_equirectangular
|
70
xvrsteal/__init__.py
Normal file
70
xvrsteal/__init__.py
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
import PIL.Image
|
||||||
|
import urllib.request
|
||||||
|
import io
|
||||||
|
import math
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
import pathlib
|
||||||
|
import os
|
||||||
|
from stitching import tiles_to_equirectangular_blender, multistitch
|
||||||
|
|
||||||
|
def xvr_normalize(url):
|
||||||
|
'''
|
||||||
|
Takes the URL of any image in a xvr panorama and returns a string
|
||||||
|
with substitutable variables for image IDs.
|
||||||
|
|
||||||
|
:param url: URL of an image contained in a xvr panorama
|
||||||
|
:return: string with substitutable variables or False if URL invalid
|
||||||
|
'''
|
||||||
|
|
||||||
|
try:
|
||||||
|
with urllib.request.urlopen(url) as res:
|
||||||
|
assert res.getcode() == 200
|
||||||
|
|
||||||
|
parts = url.split("/")
|
||||||
|
|
||||||
|
assert "_" in parts[-1]
|
||||||
|
parts[-1] = "%s.jpg"
|
||||||
|
|
||||||
|
return "/".join(parts)
|
||||||
|
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def xvr_export_simple(url):
|
||||||
|
'''
|
||||||
|
Exports xvr panoramas which only consist of six complete tiles. Takes
|
||||||
|
the URL of one of these images and returns a list of PIL.Image objects
|
||||||
|
|
||||||
|
:param url: URL of one of the images
|
||||||
|
:return: list of PIL.Image objects
|
||||||
|
'''
|
||||||
|
|
||||||
|
output = []
|
||||||
|
|
||||||
|
for i in ["posz", "posx", "negz", "negx", "posy", "negy"]:
|
||||||
|
cur = url[:-8] + i + url[-4:]
|
||||||
|
res = urllib.request.urlopen(cur)
|
||||||
|
assert res.getcode() == 200
|
||||||
|
fo = io.BytesIO(res.read())
|
||||||
|
output += [PIL.Image.open(fo)]
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
def xvr_to_equirectangular(url, rotation=[0,0,0], resolution=[3840,1920]):
|
||||||
|
'''
|
||||||
|
Takes the URL of any image in a xvr panorama and returns a finished
|
||||||
|
stitched image.
|
||||||
|
|
||||||
|
:param url: Image URL
|
||||||
|
:return: PIL.Image object containing the final image
|
||||||
|
'''
|
||||||
|
|
||||||
|
stitched = xvr_export_simple(url)
|
||||||
|
function = tiles_to_equirectangular_blender
|
||||||
|
|
||||||
|
rx, ry, rz = rotation
|
||||||
|
width, height = resolution
|
||||||
|
return function(*stitched, rx=rx, ry=ry, rz=rz, width=width, height=height)
|
||||||
|
|
||||||
|
process_url = xvr_to_equirectangular
|
Loading…
Reference in a new issue