Added giraffesteal
This commit is contained in:
parent
7bfa0de1d0
commit
1985849140
3 changed files with 171 additions and 12 deletions
136
giraffesteal/__init__.py
Normal file
136
giraffesteal/__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 giraffe_normalize(url):
|
||||||
|
'''
|
||||||
|
Takes the URL of any image in a Giraffe360 panorama and returns a string
|
||||||
|
with substitutable variables for image IDs.
|
||||||
|
|
||||||
|
:param url: URL of an image contained in a Giraffe360 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]
|
||||||
|
assert parts[-1][0] == "l"
|
||||||
|
|
||||||
|
parts[-1] = "l%i_%s_%s_%s.jpg"
|
||||||
|
|
||||||
|
return "/".join(parts)
|
||||||
|
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def giraffe_getmaxzoom(schema):
|
||||||
|
'''
|
||||||
|
Takes a normalized string from giraffe_normalize() and returns the maximum
|
||||||
|
zoom level available.
|
||||||
|
|
||||||
|
:param schema: normalized URL format output by giraffe_normalize()
|
||||||
|
:return: int value of largest available zoom level
|
||||||
|
'''
|
||||||
|
|
||||||
|
l = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
url = schema % (l+1, "f", "01", "01")
|
||||||
|
with urllib.request.urlopen(url) as res:
|
||||||
|
assert res.getcode() == 200
|
||||||
|
l += 1
|
||||||
|
except:
|
||||||
|
return l
|
||||||
|
|
||||||
|
def giraffe_export(schema):
|
||||||
|
'''
|
||||||
|
Takes a normalized string from giraffe_normalize() and returns a list of
|
||||||
|
lists of lists containing all images fit for passing into stitch().
|
||||||
|
|
||||||
|
:param schema: normalized URL format output by giraffe_normalize()
|
||||||
|
:return: list of lists of lists of PIL.Image() objects for multistitch()
|
||||||
|
'''
|
||||||
|
|
||||||
|
maxzoom = giraffe_getmaxzoom(schema)
|
||||||
|
output = []
|
||||||
|
|
||||||
|
for tile in "frblud":
|
||||||
|
t_array = []
|
||||||
|
y = 1
|
||||||
|
|
||||||
|
while True:
|
||||||
|
r_array = []
|
||||||
|
x = 1
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
res = urllib.request.urlopen(schema % (maxzoom, tile, str(y).zfill(2), str(x).zfill(2)))
|
||||||
|
assert res.getcode() == 200
|
||||||
|
fo = io.BytesIO(res.read())
|
||||||
|
img = PIL.Image.open(fo)
|
||||||
|
r_array.append(img)
|
||||||
|
x += 1
|
||||||
|
except urllib.error.HTTPError:
|
||||||
|
break
|
||||||
|
except Exception:
|
||||||
|
raise
|
||||||
|
|
||||||
|
if not r_array:
|
||||||
|
break
|
||||||
|
|
||||||
|
t_array.append(r_array)
|
||||||
|
y += 1
|
||||||
|
|
||||||
|
output.append(t_array)
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
def giraffe_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 Giraffe360 panorama
|
||||||
|
:return: list of stitched PIL.Image objects (back, right, front, left, top,
|
||||||
|
bottom)
|
||||||
|
'''
|
||||||
|
|
||||||
|
parts = url.split("/")
|
||||||
|
|
||||||
|
try:
|
||||||
|
schema = giraffe_normalize(url)
|
||||||
|
images = giraffe_export(schema)
|
||||||
|
return multistitch(images)
|
||||||
|
|
||||||
|
except:
|
||||||
|
raise
|
||||||
|
raise ValueError("%s does not seem to be a valid Giraffe360 URL." % url)
|
||||||
|
|
||||||
|
def giraffe_to_equirectangular(url, rotation=[0,0,0], resolution=[3840,1920]):
|
||||||
|
'''
|
||||||
|
Takes the URL of any image in a Giraffe360 panorama and returns a finished
|
||||||
|
stitched image.
|
||||||
|
|
||||||
|
:param url: Image URL
|
||||||
|
:return: PIL.Image object containing the final image
|
||||||
|
'''
|
||||||
|
|
||||||
|
stitched = giraffe_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 = giraffe_to_equirectangular
|
|
@ -4,12 +4,14 @@ import re
|
||||||
import importlib
|
import importlib
|
||||||
import argparse
|
import argparse
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import traceback
|
||||||
|
|
||||||
regs = {
|
regs = {
|
||||||
"\d/\d/\d_\d\.jpg": "krpanosteal",
|
"\d/\d/\d_\d\.jpg": "krpanosteal",
|
||||||
"pano\_[frblud].jpg": "krpanosteal",
|
"pano\_[frblud].jpg": "krpanosteal",
|
||||||
"my.matterport.com/show/": "matterportsteal",
|
"my.matterport.com/show/": "matterportsteal",
|
||||||
"youtube.com": "youtubesteal"
|
"youtube.com": "youtubesteal",
|
||||||
|
"l\d_[frblud]_\d\d_\d\d.jpg": "giraffesteal"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,6 +54,6 @@ if __name__ == "__main__":
|
||||||
args.output + "/" + args.title + ".thumb.jpg"])
|
args.output + "/" + args.title + ".thumb.jpg"])
|
||||||
else:
|
else:
|
||||||
image.save(args.output + "/" + args.title + ".png")
|
image.save(args.output + "/" + args.title + ".png")
|
||||||
except Exception as e:
|
except Exception:
|
||||||
with open(args.output + "/" + args.title + ".err", "w") as errorfile:
|
with open(args.output + "/" + args.title + ".err", "w") as errorfile:
|
||||||
errorfile.write(str(e))
|
errorfile.write(traceback.format_exc())
|
||||||
|
|
|
@ -14,17 +14,38 @@ from stitching import tiles_to_equirectangular_blender, multistitch
|
||||||
|
|
||||||
def youtube_get_video(url):
|
def youtube_get_video(url):
|
||||||
vid = uuid.uuid4().hex
|
vid = uuid.uuid4().hex
|
||||||
|
with open("/tmp/" + vid, "w") as logfile:
|
||||||
process = subprocess.Popen(
|
process = subprocess.Popen(
|
||||||
['youtube-dl',
|
['youtube-dl',
|
||||||
'--user-agent', '""',
|
'--user-agent', '""',
|
||||||
'-o', vid,
|
'-o', vid,
|
||||||
|
"--merge-output-format", "mkv",
|
||||||
url,
|
url,
|
||||||
], cwd="/tmp/panosteal/youtube/"
|
],
|
||||||
|
cwd="/tmp/panosteal/youtube/",
|
||||||
|
stdout=logfile,
|
||||||
|
stderr=logfile
|
||||||
)
|
)
|
||||||
|
|
||||||
process.wait()
|
process.wait()
|
||||||
|
|
||||||
|
try:
|
||||||
data = open('/tmp/panosteal/youtube/%s.mkv' % vid, 'rb').read()
|
data = open('/tmp/panosteal/youtube/%s.mkv' % vid, 'rb').read()
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
data = open('/tmp/panosteal/youtube/%s.mp4' % vid, 'rb').read()
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
data = open('/tmp/panosteal/youtube/%s.webm' % vid, 'rb').read()
|
||||||
|
process2 = subprocess.Popen(
|
||||||
|
['ffmpeg',
|
||||||
|
'-i', '%s.webm' % vid,
|
||||||
|
'-c:v', "copy",
|
||||||
|
'%s.mkv' % vid],
|
||||||
|
cwd="/tmp/panosteal/youtube/"
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
raise
|
||||||
|
|
||||||
for i in glob.glob("/tmp/panosteal/youtube/%s*" % vid):
|
for i in glob.glob("/tmp/panosteal/youtube/%s*" % vid):
|
||||||
os.remove(i)
|
os.remove(i)
|
||||||
|
|
Loading…
Reference in a new issue