back

update panoramas with lost source files to cube faces and back to equirectangular for html5

If you want more files to train on: "legacy zipped files"

1. circular panorama

I normally use Pano2VR 5 (https://ggnome.com/) on my old Apple computer with Mac OS 10.14.6, (where I still have QuickTime Pro) to convert QTVRs to html5. When that doesn't work, ffmpeg might work.

Extract zipped file
"mh.mov.zip"

Open the QTVR file in ffmpeg:
ffmpeg -i mh.mov

and you get this metadata from the file:

	Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'mh.mov':
  Metadata             :
    creation_time      : 1998-09-21T11:56:24.000000Z
  Duration             : 00:00:01.00, start: 0.000000, bitrate: 1759 kb/s

  Stream #0:0[0x1](eng): Data: none (qtvr / 0x72767471), 0 kb/s (default)
    Metadata           :
      creation_time    : 1998-09-21T11:56:24.000000Z
      handler_name     : QTVR Media Handler

  Stream #0:1[0x2](eng): Data: none, 1 kb/s (default)
    Metadata           :
      creation_time    : 1998-09-21T11:56:24.000000Z
      handler_name     : Panorama Media Handler

  Stream #0:2[0x3](eng): Video: cinepak (cvid / 0x64697663), rgb24, 144x480, 78 kb/s, 1 fps, 1 tbr, 3600 tbn
    Metadata           :
      creation_time    : 1998-09-21T11:56:24.000000Z
      handler_name     : Apple Video Media Handler
      vendor_id        : appl
      encoder          : Cinepak

  Stream #0:3[0x4](eng): Video: mjpeg (Baseline) (jpeg / 0x6765706A), yuvj420p(pc, bt470bg/unknown/unknown), 576x160 [SAR 72:72 DAR 18:5], 1649 kb/s, 12 fps, 12 tbr, 3600 tbn
    Metadata           :
      creation_time    : 1998-09-21T11:56:24.000000Z
      handler_name     : Apple Video Media Handler
      vendor_id        : appl
      encoder          : Photo - JPEG
	
Here you can see that the pano is 1 s at 12 fps 576x160 px.
ffmpeg goes for the highest resolution stream unless you tell it another, using -map
ffmpeg wiki: Map

Extract the tiles into a directory "dir":
ffmpeg -i mh.mov dir/%02d.jpg
and you get 12 tiles, they are rotated -90° (counterclockwise).

"%02d" is a formatting string, filename pattern, or sequence wildcards,
2 shows how many digits the printed number will have: 1-99,
0 before 2 shows that leading spaces should be replaced by zero,
"%02d" takes two digits: 01-99, "%03d" takes three: 001-999 etc.

Here is the first tile:


01.jpg

To rotate tiles 90° clockwise:
ffmpeg transpose filter
"transpose=0" 90° counter-clockwise and vertical flip (default)
"transpose=1" 90° clockwise
"transpose=2" 90° counter-clockwise
"transpose=3" 90° clockwise and vertical flip
"transpose=2,transpose=2" 180°
Flip images horizontally:"hflip"
Flip images vertically:"vflip"

ffmpeg tile filter

You can combine two or more filters, you just need a comma:
ffmpeg -i dir/%02d.jpg -vf "tile=1x12,transpose=1" mh.jpg



mh.jpg

Here the tiles are combined for circular projection, 1920x576 px. Pano2VR or similar can make the HTML5 files.

ffmpeg pad filter
If you need the panorama to be in 2:1 ratio, pad the output, black is default:
1920x576 to 1920x960
ffmpeg -i mh.jpg -vf "pad=1920:960:(ow-iw)/2:(oh-ih)/2" mh_eq1.jpg
ow and oh are output width and height, iw and ih are input width and height
or do 960-576=384 384/2=192
ffmpeg -i mh.jpg -vf "pad=1920:960:1920:192" mh_eq2.jpg
or do
ffmpeg -i mh.jpg -vf "pad=1920:960:0:192" mh_eq3.jpg

Combine this with the preceding commands, which can help against image degradation (jpeg recompression):
ffmpeg -i dir/%02d.jpg -vf "tile=1x12,transpose=1,pad=1920:960:0:192" mh_eq.jpg



mh_eq.jpg Here is the final image in 2:1 ratio.

And then to Pano2VR or similar for the html5 conversion.

back

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

2. update an early spherical QTVR panorama with lost
source files to equirectangular for html5

updated for ffmpeg 7

Download "dac2epFL.mov.zip"
Run: ffmpeg -i dac2epFL.mov
to get metadata on the file:
	Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'dac2epFL.mov':
  Metadata:
    creation_time      : 2002-10-09T21:04:37.000000Z
  Duration: 00:00:02.00, start: 0.000000, bitrate: 12498 kb/s

  Stream #0:0[0x1](eng): Data: none (qtvr / 0x72767471), 0 kb/s (default)
    Metadata:
      creation_time    : 2002-10-09T21:04:37.000000Z
      handler_name     : QTVR Media Handler

  Stream #0:1[0x2](eng): Data: none, 20 kb/s (default)
    Metadata:
      creation_time    : 2002-10-09T21:04:37.000000Z
      handler_name     : QTVR Panorama Media Handler

  Stream #0:2[0x3](eng): Video: mjpeg (Baseline) (jpeg / 0x6765706A), yuvj420p(pc, bt470bg/unknown/unknown), 400x400 [SAR 72:72 DAR 1:1], 11968 kb/s, 75 fps, 75 tbr, 3600 tbn
    Metadata:
      creation_time    : 2002-10-09T21:04:37.000000Z
      handler_name     : Apple Video Media Handler
      vendor_id        : appl
      encoder          : Photo - JPEG

  Stream #0:3[0x4](eng): Video: mjpeg (Baseline) (jpeg / 0x6765706A), yuvj420p(pc, bt470bg/unknown/unknown), 21x21 [SAR 72:72 DAR 1:1], 471 kb/s, 75 fps, 75 tbr, 3600 tbn
    Metadata:
      creation_time    : 2002-10-09T21:04:37.000000Z
      handler_name     : Apple Video Media Handler
      vendor_id        : appl
      encoder          : Photo - JPEG
	
The interesting parts are:
Duration: 00:00:02.00, Video: mjpeg, jpeg, 400x400, 75 fps.
That should give me 150 jpgs @ 400x400 px.
As it's from 2002 it's possible that it is a spherical panorma, (I know it is, as I made it) that was made possible with QuickTime 5 in 2001 (developer beta in late 2000). Camera Nikon D1X. A good guess is that I get 6 cubic faces @ 150/6=25 tiles each (2000x2000 px).

ffmpeg -i dac2epFL.mov dir/%3d.jpg

ffmpeg -i dir/%3d.jpg -hide_banner -vf "tile=5x5,tile=6x1" cm.jpg
I can give this to Pano2VR for a HTML5 panorama as it's in "frblud" cubemap order (Apple, panotools etc.), but here I will go on with v360.

See "mono" for cubemap order. Compare with "Horizontal cross" .



cm.jpg "frblud"

To switch the cubemap faces into default v360 order, do:
ffmpeg -i cm.jpg -vf "v360=c6x1:c6x1:in_forder=frblud" strip.jpg
To complete the commands, here is how to go from a default v360 cubemap to frblud (Apple, panotools etc.).
ffmpeg -i strip.jpg -vf "v360=c6x1:c6x1:out_forder=frblud" frblud.jpg



strip.jpg "rludfb" face names: right 'r', left 'l', up 'u', down 'd', forward 'f', back 'b' (v360 default)

And to make the equirectangular image:
ffmpeg -i strip.jpg -vf "v360=c6x1:e" dacapo.jpg

Skip the last steps, go with this command instead:
ffmpeg -i cm.jpg -vf "v360=c6x1:e:in_forder=frblud" dacapo.jpg



dacapo.jpg (8000x4000 px)

This equirectangular is used in "ball format", "stereographic format" and "equiangular format".

back

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

3. a later spherical panorama

For a different way to reassemble spherical panoramas, see:
An Unexpected Benefit of Multi-Resolution in Pano2VR by Tony Redhead.

In later spherical panos you may find the tiles in six directories.
The tiles in the directories named similar to this:
c0_l0_0_0.jpg, c0_l0_0_1.jpg, c0_l0_0_2.jpg, c0_l0_1_0.jpg, c0_l0_1_1.jpg, c0_l0_1_2.jpg, c0_l0_2_0.jpg, c0_l0_2_1.jpg, c0_l0_2_2.jpg

9 tiles 514x514 px, square and same size, that is good.
But the tiling software may have expanded the tile with one pixel in each direction. In this case scale the tile to 512x512 px, and you get files that are easy to compress (divisible by 2, 4, 8, 16).
To handle them you either rename them to numeric sequential order and use the "%d" string:
ffmpeg -i dir/%d.jpg -vf "scale=w=512:h=512,tile=3x3" 1.png

or you may use the "-pattern_type glob" which uses file names in alphabetic order.
ffmpeg -pattern_type glob -i "dir/*.jpg" -vf "scale=512:512,tile=3x3" 1.png

And you get one cubic face. Then reassemble the other five cube faces, add them together in a strip and convert them into an equirectangular. Using the keyboard up arrow in Shell/Terminal give you back your last command, and if you keep pressing it you will go through your recent command history.

Reassembly the cubemap.
ffmpeg tile filter
v360 filter, cubemap face names: right 'r', left 'l', up 'u', down 'd', forward 'f', back 'b'. Default value is 'rludfb'. Extract each cubemap and rename right to 1.tif, left to 2.tif etc. Then reassemble them.
ffmpeg -i dir/%d.tif -filter_complex "tile=6x1" cubemap.tif

ffmpeg's v360 filter can convert the cubemap back to equirectangular after reassembly:
ffmpeg -i cubemap.tif -vf "v360=c6x1:e" equirectangular.tif
The forward cube face gets placed in the center of the equirectangular file.

back

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

4. more on spherical panoramas

But if the tiles in one of the six directories look like this (with a total of 129 tiles):
c0_l0_0_0.jpg, 514x514 px
c0_l0_0_1.jpg, 514x514 px
c0_l0_0_2.jpg, 514x514 px
c0_l0_0_3.jpg, 377x514 px
c0_l0_1_0.jpg, 514x514 px
c0_l0_1_1.jpg, 514x514 px
c0_l0_1_2.jpg, 514x514 px
c0_l0_1_3.jpg, 377x514 px
c0_l0_2_0.jpg, 514x514 px
c0_l0_2_1.jpg, 514x514 px
c0_l0_2_2.jpg, 514x514 px
c0_l0_2_3.jpg, 377x514 px
c0_l0_3_0.jpg, 514x377 px
c0_l0_3_1.jpg, 514x377 px
c0_l0_3_2.jpg, 514x377 px
c0_l0_3_3.jpg, 377x377 px

next dir:
c1_l0_0_0.jpg, 514x514 px
etc.
exiftool (not ffmpeg!)
I used exiftool to get the list with sizes, "-csv" gives me comma separated values, "dir" is the folder containing the files:
exiftool -ImageSize -csv dir > sizes.txt

I shorten the file names here, adding them together:
0_0.jpg + 0_1.jpg + 0_2.jpg = 0.png 1542x514 (horizontal)
1_0.jpg + 1_1.jpg + 1_2.jpg = 1.png 1542x514
2_0.jpg + 2_1.jpg + 2_2.jpg = 2.png 1542x514

ffmpeg -pattern_type glob -i "dir/*.jpg" -vf "tile=3x1" dir/0.png
or
ffmpeg -i dir/%02d.jpg -filter_complex "tile=3x1" dir/0.png

0.png + 0_3.jpg = 0a.png 1919x514
1.png + 1_3.jpg = 1a.png 1919x514
2.png + 2_3.jpg = 2a.png 1919x514

ffmpeg -i dir/0.png -i dir/0_3.jpg -filter_complex hstack dir/0a.png

You can have more than two sources in hstack and vstack: "hstack=inputs=3"

0a.png + 1a.png + 2a.png = 012.png 1919x1542 vertical

3_0.jpg + 3_1.jpg + 3_2.jpg = 3210.png 1542x377 horizontal

3210.png + 3_3.jpg = 3233.png 1919x377 horizontal

And a final addition and we get the first cubic frame of the panorama at 1919x1919 px.
012.png + 3233.png = frame1919.png 1919x1919 px vertical

Now there is one problem with this. The file is odd sized. This is not good for file compression. Some codecs won't work with odd sized files. Scale to a near even number to keep size divisible by at least 2 (preferably 4, 8 or 16)
ffmpeg -i frame1919.png -vf "scale=1920:1920" frame1.tif
Repeat for the next five directories.
And then combine the cubic frames and convert them to equirectangular as above.

back