Last active
June 1, 2022 12:32
Convert 2D panoramas from left and right vr360 cameras to VR.JPG files for cardboard and photos.google.com
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SetLocal EnableExtensions EnableDelayedExpansion | |
:forfiles | |
if "%~1"=="nul" ( | |
call :doit "%~2" | |
goto :EOF | |
) | |
:main | |
if "%~1"=="" ( | |
if not exist "%UserProfile%\SendTo\%~n0.lnk" ( | |
if defined ChocolateyInstall ( | |
"%ChocolateyInstall%\tools\shimgen.exe" -o "%UserProfile%\SendTo\%~n0.exe" -p "%~f0" | |
) else ( | |
copy /b "%~f0" "%UserProfile%\SendTo\%~nx0" | |
) | |
echo "%~f0" is placed in "%UserProfile%\SendTo" | |
) | |
) | |
echo Run "JPG2VR.bat" without parameters to place it in "%UserProfile%\SendTo" | |
echo Place dual fisheye files: | |
echo from right vr360 cam to "c:\d\R\df.jpg" "c:\d\R" | |
echo from left vr360 cam to "c:\d\df.jpg" "c:\d" | |
echo Or place equirectangular panorama files: | |
echo from right vr360 cam to "c:\d\R\vr360.jpg" "c:\d\R" | |
echo from left vr360 cam to "c:\d\vr360.jpg" "c:\d" | |
echo Send files or dirs: "c:\d\df.jpg" "c:\d\vr360.jpg" "c:\d" "c:\d\R" ... to "JPG2VR" | |
echo or drop it to "JPG2VR.bat" then look at: | |
echo "c:\VR\dfF.vr.jpg" - front view vr180 3D panorama | |
echo "c:\VR\dfB.vr.jpg" - back view vr180 3D panorama | |
echo "c:\VR\vr360F.vr.jpg" - front view vr180 3D panorama | |
echo "c:\VR\vr360B.vr.jpg" - back view vr180 3D panorama | |
echo "c:\VR\vr360.vr.jpg" - vr360 3D panorama | |
set cmd="cmd /c "%~f0" nul "@path"" | |
:loop | |
if "%~1"=="" ( | |
pause | |
goto :EOF | |
) | |
forfiles /s /p "%~1" /m *.jpg /c %cmd% 2>nul||call :doit "%~1" | |
shift | |
goto :loop | |
:doit | |
if not exist "%~f1" goto :EOF | |
if /i not ".jpg"=="%~x1" goto :EOF | |
set pair="%~dp1R\%~nx1" | |
set suff=F | |
set vr=..\VR | |
set crop=0 | |
if exist %pair% goto :out | |
set pair="%~dp1..\%~nx1" | |
set suff=B | |
set vr=..\..\VR | |
set crop=iw/2 | |
if not exist %pair% goto :EOF | |
:out | |
set out="%~dp1%vr%\%~n1%suff%.vr.jpg" | |
if exist %out% goto :EOF | |
set FOV=205 | |
set interp=gauss | |
set vf=crop=iw/2:ih:%crop%,v360=fisheye:equirect:ih_fov=%FOV%:iv_fov=%FOV%:interp=%interp%,crop=iw/2 | |
for /f "tokens=1,2,3 usebackq delims=: " %%i in (`exiftool -s2 -ImageWidth -ImageHeight -ProjectionType -InitialHorizontalFOVDegrees -YCbCrPositioning -MakerNoteUnknown "%~f1"`) do set %%i=%%j | |
if not defined ImageWidth goto :EOF | |
if not defined ImageHeight goto :EOF | |
set /a TrueVrWidth=%ImageHeight%*2 | |
if not "%ImageWidth%"=="%TrueVrWidth%" goto :EOF | |
set ImageWidth=%ImageHeight% | |
if not defined InitialHorizontalFOVDegrees set InitialHorizontalFOVDegrees=75 | |
if defined ProjectionType ( | |
set vf=[0]crop=iw/4:ih:0[r];[0]crop=iw/4:ih:iw*3/4[l];[l][r]hstack | |
if "%suff%"=="F" set vf=crop=iw/2 | |
) | |
set tags="%temp%\%~n1.jpg" | |
set L="%temp%\%~n1L.jpg" | |
set R=%temp%\%~n1R.jpg | |
call :end | |
if defined MakerNoteUnknown set makernotes=-makernotes:all= | |
exiftool -ThumbnailImage= -ifd1:all= -PreviewImage= -FlashPix:all= -FlashpixVersion= -mpf:all= -trailer:all= %makernotes% "%~f1" -o %tags% | |
if not exist %tags% goto :EOF | |
set xmp="%temp%\%ImageWidth%x%InitialHorizontalFOVDegrees%.xmp" | |
if exist %xmp% goto :vr180 | |
:xmp | |
set /a FullPanoWidthPixels=%ImageWidth%*2 | |
set /a CroppedAreaImageWidthPixels=%ImageWidth% | |
set /a CroppedAreaLeftPixels=(%FullPanoWidthPixels%-%CroppedAreaImageWidthPixels%)/2 | |
set /a FullPanoHeightPixels=%ImageHeight% | |
set /a CroppedAreaImageHeightPixels=%ImageHeight% | |
set /a CroppedAreaTopPixels=(%FullPanoHeightPixels%-%CroppedAreaImageHeightPixels%)/2 | |
echo 1|exiftool -tagsfromfile - -XMP-GPano:all^ | |
-XMP-GPano:UsePanoramaViewer="True"^ | |
-XMP-GPano:CroppedAreaLeftPixels="%CroppedAreaLeftPixels%"^ | |
-XMP-GPano:CroppedAreaTopPixels="%CroppedAreaTopPixels%"^ | |
-XMP-GPano:CroppedAreaImageWidthPixels="%CroppedAreaImageWidthPixels%"^ | |
-XMP-GPano:CroppedAreaImageHeightPixels="%CroppedAreaImageHeightPixels%"^ | |
-XMP-GPano:FullPanoWidthPixels="%FullPanoWidthPixels%"^ | |
-XMP-GPano:FullPanoHeightPixels="%FullPanoHeightPixels%"^ | |
-XMP-GPano:InitialViewHeadingDegrees="180"^ | |
-XMP-GPano:ProjectionType="equirectangular"^ | |
-XMP-GPano:InitialHorizontalFOVDegrees="%InitialHorizontalFOVDegrees%"^ | |
%xmp% | |
if not exist %xmp% goto :end | |
:vr180 | |
ffmpeg -hide_banner -i "%~f1" -bsf:v mjpeg2jpeg -filter_complex %vf% -qmin 1 -q:v 1 -map_metadata -1 -y %L%|| del %L% | |
if not exist %L% goto :end | |
ffmpeg -hide_banner -i %pair% -bsf:v mjpeg2jpeg -filter_complex %vf% -qmin 1 -q:v 1 -map_metadata -1 -y "%R%"|| del "%R%" | |
if not exist "%R%" goto :end | |
if not exist "%~dp1%vr%" md "%~dp1%vr%" | |
if defined YCbCrPositioning set YCbCrP=-YCbCrPositioning="%YCbCrPositioning%" | |
set tail=-XMP-exif:all= -XMP-tiff:all= -JFIF:all= -FlashpixVersion= %YCbCrP% "-XMP-GImage:ImageMimeType=image/jpeg" "-XMP-GImage:ImageData<=%R%" | |
exiftool -tagsFromFile %tags% -ExifIFD:ExifImageWidth="%ImageWidth%" -tagsFromFile %xmp% %L% -o %out% %tail% | |
if not exist %out% goto :end | |
call :date | |
:vr360 | |
if not defined ProjectionType goto :end | |
if "%suff%"=="B" goto :end | |
set out="%~dp1%vr%\%~n1.vr.jpg" | |
if exist "%out%" goto :end | |
:tag | |
del "%R%" | |
exiftool -all= -o "%R%" %pair% | |
if not exist "%R%" goto :end | |
exiftool %tags% -o %out% %tail% | |
if not exist %out% goto :end | |
call :date | |
:end | |
del %tags% %L% "%R%" | |
goto :EOF | |
:date | |
rem Any of -api Compact= or use -z or do not use -z breaks compatibility with https://arvr.google.com/vr180/apps/ | |
exiv2 -M"set Xmp.GPano.InitialHorizontalFOVDegrees %InitialHorizontalFOVDegrees%" %out% | |
exiftool "-FileCreateDate<CreateDate" "-FileModifyDate<ModifyDate" %out% | |
:exiftool -X %out% -w! .xml |
Can you please provide some examples of usage? I cannot understand which parameters I must pass to the script.
Send files or dirs: "c:\d\df.jpg" "c:\d\vr360.jpg" "c:\d" "c:\d\R" ... to "JPG2VR"
or drop it to "JPG2VR.bat" then look at:
same as:
JPG2VR.bat "c:\d\df.jpg"
JPG2VR.bat "c:\d\vr360.jpg"
JPG2VR.bat "c:\d"
JPG2VR.bat "c:\d\R"
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Run "JPG2VR.bat" without parameters to place it in "%UserProfile%\SendTo"
Place dual fisheye files:
from right vr360 cam to "c:\d\R\df.jpg" "c:\d\R"
from left vr360 cam to "c:\d\df.jpg" "c:\d"
Or place equirectangular panorama files:
from right vr360 cam to "c:\d\R\vr360.jpg" "c:\d\R"
from left vr360 cam to "c:\d\vr360.jpg" "c:\d"
Send files or dirs: "c:\d\df.jpg" "c:\d\vr360.jpg" "c:\d" "c:\d\R" ... to "JPG2VR"
or drop it to "JPG2VR.bat" then look at:
"c:\VR\dfF.vr.jpg" - front view vr180 3D panorama
"c:\VR\dfB.vr.jpg" - back view vr180 3D panorama
"c:\VR\vr360F.vr.jpg" - front view vr180 3D panorama
"c:\VR\vr360B.vr.jpg" - back view vr180 3D panorama
"c:\VR\vr360.vr.jpg" - vr360 3D panorama
Thanks:
https://developers.google.com/vr/reference/cardboard-camera-vr-photo-format
https://chocolatey.org/
https://exiftool.org/ choco install exiftool
https://ffmpeg.org/ choco install ffmpeg
https://www.msys2.org/ choco install msys2
https://www.exiv2.org/ pacman -S $MINGW_PACKAGE_PREFIX-exiv2