A VR photo is a stereoscopic panorama with sound. Cardboard Camera stores elements of a VR photo as metadata in a JPEG file. The container image acts as the left eye image, while the right eye and an (optional) audio file are stored as base64-encoded binary blobs in the image’s metadata. This allows the photo to be backwards-compatible with ordinary image viewers, which recognize the container (left eye) image and display it as a 2D panoramic photo. Metadata is stored using Adobe’s XMP standard, and is further described in their specification.
Metadata Tags
GPano
GPano is used to describe the imaging model of the photo, and stored in the standard section of XMP. Using GPano ensures backwards compatibility with the PhotoSphere metadata standard.
Name | Type | Required | Default value (viewer assumed) |
Property description | Action required if image is modified |
---|---|---|---|---|---|
GPano:UsePanoramaViewer | Boolean | No | True |
Whether to show this image in a photo sphere viewer rather than as a normal flat image. This may be specified based on user preferences or by the stitching software. The application displaying or ingesting the image may choose to ignore this. | scale/crop: No change. An application may decide to switch this to False if the field of view falls below a
certain value. |
GPano:CaptureSoftware | String | No | n/a | If capture was done using an application on a mobile device, such as an Android phone, the name of the application that was used (such as “Photo Sphere”). This should be left blank if source images were captured manually, such as by using a DSLR on a tripod. | n/a |
GPano:StitchingSoftware | String | No | n/a | The software that was used to create the final photo sphere. This may sometimes be the same value as that of GPano:CaptureSoftware. | n/a |
GPano:ProjectionType | Open Choice of Text | Yes |
|
Projection type used in the image file. Google products currently support the value equirectangular. | scale/crop: No change. |
GPano:PoseHeadingDegrees | Real | No, but is required for display on Google Maps | n/a | Compass heading, measured in degrees, for the center the image. Value must be >= 0 and < 360. | scale/crop: No change. |
GPano:PosePitchDegrees | Real | No | 0 |
Pitch, measured in degrees, for the center in the image. Value must be >= -90 and <= 90. | scale/crop: No change. |
GPano:PoseRollDegrees | Real | No | 0 |
Roll, measured in degrees, of the image where level with the horizon is 0. Value must be > -180 and <= 180. | scale/crop: No change. |
GPano:InitialViewHeadingDegrees | Integer | No | 0 |
The heading angle of the initial view in degrees. | scale/crop: No change. |
GPano:InitialViewPitchDegrees | Integer | No | 0 |
The pitch angle of the initial view in degrees. | scale/crop: No change. |
GPano:InitialViewRollDegrees | Integer | No | 0 |
The roll angle of the initial view in degrees. | scale/crop: No change. |
GPano:InitialHorizontalFOVDegrees | Real | No | n/a | The initial horizontal field of view that the viewer should display (in degrees). This is similar to a zoom level. | n/a |
GPano:FirstPhotoDate | Date | No | n/a | Date and time for the first image created in the photo sphere. | scale/crop: No change. |
GPano:LastPhotoDate | Date | No | n/a | Date and time for the last image created in the photo sphere. | scale/crop: No change. |
GPano:SourcePhotosCount | Integer | No | n/a | Number of source images used to create the photo sphere. | scale/crop: No change. |
GPano:ExposureLockUsed | Boolean | No | n/a | When individual source photographs were captured, whether or not the camera’s exposure setting was locked. | n/a |
GPano:CroppedAreaImageWidthPixels | Integer | Yes | n/a | Original width in pixels of the image (equal to the actual image’s width for unedited images). | scale/crop: This property needs to be updated to reflect the new size of the image. |
GPano:CroppedAreaImageHeightPixels | Integer | Yes | n/a | Original height in pixels of the image (equal to the actual image’s height for unedited images). | scale/crop: This property needs to be updated to reflect the new size of the image. |
GPano:FullPanoWidthPixels | Integer | Yes | n/a | Original full width from which the image was cropped. If only a partial photo sphere was captured, this specifies the width of what the full photo sphere would have been. | crop: No change. scale: This properly needs to be scaled accordingly. |
GPano:FullPanoHeightPixels | Integer | Yes | n/a | Original full height from which the image was cropped. If only a partial photo sphere was captured, this specifies the height of what the full photo sphere would have been. | crop: No change. scale: This properly needs to be scaled accordingly. |
GPano:CroppedAreaLeftPixels | Integer | Yes | n/a | Column where the left edge of the image was cropped from the full sized photo sphere. | crop: If the left crop of the image is changed, this value must
be updated. scale: This properly needs to be scaled accordingly. |
GPano:CroppedAreaTopPixels | Integer | Yes | n/a | Row where the top edge of the image was cropped from the full sized photo sphere. | crop: If the top crop of the image is changed, this value must
be updated. scale: This properly needs to be scaled accordingly. |
GPano:InitialCameraDolly | Real | No | 0 |
This optional parameter moves the virtual camera position along
the line of sight, away from the center of the photo sphere. A rear
surface position is represented by the value -1.0 ,
while a front surface position is represented by 1.0 .
For normal viewing, this parameter should be set to 0 . |
n/a |
GAudio
The audio MIME type is written in the standard section, and the base64-encoded data in the extended section. Storing the MIME type in the standard section allows image readers to quickly determine whether the photo contains audio or not.
Name | Type | Required | Default value (viewer assumed) |
Property description | Action required if image is modified |
---|---|---|---|---|---|
Mime | String | Yes | N/A | The MIME type for the base64 string containing the audio content , e.g., "audio/mp4" or "audio/mpeg3". | Scale/crop: No change. |
Data | String | Yes | N/A | The base64-encoded audio data. | No change. |
GImage
Similar to GAudio, the MIME type of the right eye image resides in the standard section, with the base64-encoded data in the extended section.
Name | Type | Required | Default value (viewer assumed) |
Property description | Action required if image is modified |
---|---|---|---|---|---|
Mime | String | Yes | N/A | The MIME type for the base64 string containing the image content, e.g., "image/jpeg" or "image/png". | Scale/crop: No change. |
Data | String | Yes | N/A | The base64-encoded image. | Scale/crop: The data needs to be decoded into an image, then scaled/cropped, then re-encoded again. |
File Extension
Cardboard Camera currently writes VR photos to a file with the extension .vr.jpg. This extension does not affect the file metadata contents, but it makes it easier to distinguish them from conventional photos. Otherwise, this distinction would require parsing the header of each file, which slows down performance.
Example
Below is an example of the photo format as it would appear in a JPEG file. The XMP metadata of an actual VR photo is viewable by opening it in a text editor.
Standard section
<x:xmpmeta xmlns:x="adobe:ns:meta/" xmptk="Adobe XMP">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description
xmlns:GImage="http://ns.google.com/photos/1.0/image/"
xmlns:GPano="http://ns.google.com/photos/1.0/panorama/"
xmlns:GAudio="http://ns.google.com/photos/1.0/audio/"
xmlns:xmpNote="http://ns.adobe.com/xmp/note/"
GImage:Mime="image/jpeg"
GPano:CroppedAreaLeftPixels="7530"
GPano:CroppedAreaTopPixels="1809"
GPano:CroppedAreaImageWidthPixels="1046"
GPano:CroppedAreaImageHeightPixels="1746"
GPano:FullPanoWidthPixels="10740"
GPano:FullPanoHeightPixels="5370"
GPano:InitialViewHeadingDegrees="269"
GAudio:Mime="audio/mp4"
xmpNote:HasExtendedXMP="fe3edd169aebc146ca7aceb5cd15294d" />
</rdf:RDF>
</x:xmpmeta>
Extended section
<x:xmpmeta xmlns:x="adobe:ns:meta/" xmptk="Adobe XMP">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description
xmlns:GImage="http://ns.google.com/photos/1.0/image/"
xmlns:GAudio="http://ns.google.com/photos/1.0/audio/"
GImage:Data="Base64EncodedImageData"
GAudio:Data="Base64EncodedAudioData" />
</rdf:RDF>
</x:xmpmeta>