Skip to content

Instantly share code, notes, and snippets.

@xgrg
Last active March 18, 2017 18:59
Show Gist options
  • Save xgrg/31353f4d5b94e8536bab8d1933b0afc3 to your computer and use it in GitHub Desktop.
Save xgrg/31353f4d5b94e8536bab8d1933b0afc3 to your computer and use it in GitHub Desktop.
Converting a picture to a scrollable panorama in Facebook
#!/usr/bin/env python
import os
import os.path as osp
import sys
from PIL import Image
dim = {'120, 86':(6000,5343),
'150, 86':(6000, 4274),
'180, 86':(6000,3562),
'240, 86':(6000,2671),
'300, 86': (6000,2137),
'360, 65': (6000,1217),
'360, 86': (6000,1781)}
cmds = {'120, 86':
# 120 h_fov, 86 v_fov
'exiftool -FullPanoWidthPixels=18000 -FullPanoHeightPixels=9000 -CroppedAreaLeftPixels=6000 -CroppedAreaTopPixels=2350 -CroppedAreaImageWidthPixels=6000 -CroppedAreaImageHeightPixels=4300 -ProjectionType=cylindrical %s',
# 150 h_fov, 86 v_fov
'150, 86':
'exiftool -FullPanoWidthPixels=14400 -FullPanoHeightPixels=7200 -CroppedAreaLeftPixels=4200 -CroppedAreaTopPixels=1880 -CroppedAreaImageWidthPixels=6000 -CroppedAreaImageHeightPixels=3440 -ProjectionType=cylindrical %s',
# 180 h_fov, 86 v_fov
'180, 86':
'exiftool -FullPanoWidthPixels=12000 -FullPanoHeightPixels=6000 -CroppedAreaLeftPixels=3000 -CroppedAreaTopPixels=1567 -CroppedAreaImageWidthPixels=6000 -CroppedAreaImageHeightPixels=2867 -ProjectionType=cylindrical %s',
# 240 h_fov, 86 v_fov
'240, 86':
'exiftool -FullPanoWidthPixels=9000 -FullPanoHeightPixels=4500 -CroppedAreaLeftPixels=1500 -CroppedAreaTopPixels=1175 -CroppedAreaImageWidthPixels=6000 -CroppedAreaImageHeightPixels=2150 -ProjectionType=cylindrical %s',
# 300 h_fov, 86 v_fov
'300, 86':
'exiftool -FullPanoWidthPixels=7200 -FullPanoHeightPixels=3600 -CroppedAreaLeftPixels=600 -CroppedAreaTopPixels=940 -CroppedAreaImageWidthPixels=6000 -CroppedAreaImageHeightPixels=1720 -ProjectionType=cylindrical %s',
# 360 h_fov, 86 v_fov
'360, 86':
'exiftool -FullPanoWidthPixels=6000 -FullPanoHeightPixels=3000 -CroppedAreaLeftPixels=0 -CroppedAreaTopPixels=783 -CroppedAreaImageWidthPixels=6000 -CroppedAreaImageHeightPixels=1433 -ProjectionType=cylindrical %s',
# 360 h_fov, 65 v_fov
'360, 65':
'exiftool -FullPanoWidthPixels=6000 -FullPanoHeightPixels=3000 -CroppedAreaLeftPixels=0 -CroppedAreaTopPixels=958 -CroppedAreaImageWidthPixels=6000 -CroppedAreaImageHeightPixels=1083 -ProjectionType=cylindrical %s'}
def pano(fp, hfov=300, vfov=86):
base, ext = osp.splitext(fp)
output_fp = '%s_pano.jpg'%base
if osp.isfile(output_fp):
os.unlink(output_fp)
k = '%s, %s'%(hfov, vfov)
cmd = 'convert -resize %sx%s! -geometry +0+0 %s %s'%(dim[k][0], dim[k][1], fp, output_fp)
print cmd
os.system(cmd)
cmd = cmds[k]%output_fp #'exiftool -FullPanoWidthPixels=7200 -FullPanoHeightPixels=3600 -CroppedAreaLeftPixels=600 -CroppedAreaTopPixels=940 -CroppedAreaImageWidthPixels=6000 -CroppedAreaImageHeightPixels=1720 -ProjectionType=cylindrical %s'%output_fp
print cmd
os.system(cmd)
cmd = 'exiftool %s -Make="RICOH" -Model="RICOH THETA S"'%output_fp
print cmd
os.system(cmd)
if osp.isfile(output_fp):
print 'Generated output', output_fp
def closest_pick(ratio, dim):
mindiff = 1000.0
mink = 0
for k, v in dim.items():
r = v[0]/float(v[1])
diff = abs(r-ratio)
if diff < mindiff:
mindiff = diff
mink = k
return mink
if __name__ == '__main__':
if len(sys.argv) == 1:
raise IOError('Please provide at least the path of an existing file.')
fp = sys.argv[1]
im = Image.open(fp)
width, height = im.size
ratio = width/float(height)
if len(sys.argv) == 4:
hfov, vfov = sys.argv[2:4]
else:
k = closest_pick(ratio, dim)
hfov, vfov = k.split(', ')
print 'closest pick:', k, '(%s, %s)'%(hfov, vfov), ratio, dim[k][0]/float(dim[k][1])
pano(fp, hfov, vfov)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment