DEV Community

Han Zhe
Han Zhe

Posted on

Why Facebook Shows Your 360 Photo Flat: PhotoSphere XMP, Explained and Fixed

Why Facebook Shows Your 360 Photo Flat: PhotoSphere XMP, Explained and Fixed

By Han Zhe

Your render is a perfect sphere on your own screen, and a stretched-out rug on Facebook. The pixels are not the problem. Facebook never got told the file is a sphere.

A 360 photo is an ordinary JPEG with one extra piece of information tucked into its header: a block of PhotoSphere XMP metadata that says "wrap this image around a sphere." If that block is missing — and renders from Blender, AI generators, and Photoshop exports routinely ship without it — Facebook treats the upload as a flat picture. The fix is not re-rendering anything. It is putting the missing tags back in and uploading the file again as a JPEG.

How does Facebook decide a photo is 360?

Facebook does not guess from the shape of the image. A wide rectangle could be a panorama, a banner, or a cropped screenshot; width alone proves nothing. When a JPEG arrives, Facebook reads the XMP packet stored in the JPEG's APP1 header segment and looks for the Google PhotoSphere namespace, GPano. Two fields do most of the work: GPano:ProjectionType must read equirectangular, and GPano:UsePanoramaViewer must read True. When both are present, the viewer wraps the flat rectangle around a sphere and hands you drag-to-look controls. When either is absent, you get the flat rectangle, stretched edge to edge.

This is the same tag set Google documents for Photo Sphere images, and the same one Google Maps, Kuula, and VR viewers read. It is a standard, not a Facebook quirk — which is why a file fixed for Facebook usually starts working everywhere else too.

Why did my photo lose its 360 tags?

In my experience there are four usual suspects, and they cover almost every "it worked from the camera but not from my edit" story:

The render never had them. Blender, Unreal, and most AI image generators output pixels, not PhotoSphere metadata. A render straight out of Cycles or an AI tool is a beautiful equirectangular image with no instruction attached telling any viewer what to do with it.

The editor stripped them. Photoshop and Lightroom rebuild the JPEG container when you export. Unless the export path explicitly preserves XMP, the GPano block is the first thing to go — the pixels survive, the instructions do not. "Save for web" style exports are repeat offenders here.

A compressor or converter rebuilt the file. Anything that decodes the JPEG and re-encodes it — a bulk optimizer, a format converter, a phone gallery's "save a copy" — produces a fresh container. Fresh containers carry no XMP unless the tool deliberately copies it over.

The file is not a JPEG at all. A PNG or WebP can hold the same 2:1 equirectangular pixels, but Facebook's 360 handling keys off the JPEG+XMP combination. Uploading a PNG of a panorama and expecting it to spin is asking the uploader to read a label that was never printed on that format.

One more distinction worth making: a phone's panorama mode is not a 360 photo. It covers a wide strip, not the full sphere, so even with metadata it only pans left and right. If your image is not a full 2:1 equirectangular — twice as wide as it is tall, covering 360 degrees around and 180 top to bottom — no tag will turn it into a sphere.

What exactly does the GPano block contain?

The block is small. Google's Photo Sphere specification defines the fields below; for a standard full panorama, the pixel numbers are just your image's own dimensions.

Field What it says Example for a 4096×2048 image
GPano:ProjectionType How to wrap the image equirectangular (the only value Google products support)
GPano:UsePanoramaViewer Open this in a sphere viewer, not as a flat image True
GPano:FullPanoWidthPixels / FullPanoHeightPixels Size of the complete sphere 4096 / 2048
GPano:CroppedAreaImageWidthPixels / CroppedAreaImageHeightPixels Size of the image actually present 4096 / 2048
GPano:CroppedAreaLeftPixels / CroppedAreaTopPixels Where the image sits inside the full sphere 0 / 0
GPano:PoseHeadingDegrees Compass direction of the image center (needed for Google Maps, optional for Facebook) 0

For an uncropped full panorama, the "full pano" and "cropped area" numbers are identical — that is normal, not an error. The cropped-area fields only differ when the image is a partial panorama cut out of a larger sphere, in which case they also carry the offset so the horizon stays level.

How do I check whether my file already has the tags?

Before fixing anything, check. Guessing wastes a re-upload.

If you have ExifTool installed, one command tells you the truth:

exiftool -XMP-GPano:ProjectionType -XMP-GPano:UsePanoramaViewer -XMP-GPano:FullPanoWidthPixels yourphoto.jpg
Enter fullscreen mode Exit fullscreen mode

If ProjectionType comes back equirectangular and the pixel fields match your image size, the file is fine and your problem is elsewhere — most likely the upload itself, or the file was converted to PNG somewhere along the way. If the fields come back empty, you have found your culprit.

No command line? Open the file in any 360 viewer that reads metadata — a browser-based viewer will either wrap it into a sphere or show it flat, which is the same test with less typing.

How do I fix it without re-rendering?

You have two honest options, and neither touches a single pixel.

Option 1: ExifTool. This is the free, no-upload route for people comfortable with a terminal. Set the projection, the viewer flag, and the pixel dimensions to match your actual image:

exiftool -XMP-GPano:ProjectionType="equirectangular" -XMP-GPano:UsePanoramaViewer="True" -XMP-GPano:FullPanoWidthPixels=4096 -XMP-GPano:FullPanoHeightPixels=2048 -XMP-GPano:CroppedAreaImageWidthPixels=4096 -XMP-GPano:CroppedAreaImageHeightPixels=2048 yourphoto.jpg
Enter fullscreen mode Exit fullscreen mode

Change the numbers to your image's real width and height. Wrong numbers here are worse than missing tags — a viewer that trusts bad dimensions will wrap the sphere with a visible pinch at the poles. Then upload the tagged JPEG to Facebook as a new post.

Option 2: a browser injector. Disclosure: I built one of these — the metadata injector in 360 Panorama Viewer (360panoramaviewer.com), which writes the same GPano block into the JPEG header in your browser without uploading the file. Drop in a 2:1 equirectangular JPEG, download the tagged copy, post that. The reason I mention it second is simple: ExifTool does the same job and costs nothing, and if you already have it installed, use it. The injector exists for the people who do not want a terminal involved in posting a photo.

Either way, the workflow after tagging is the same: upload the tagged JPEG as a new Facebook post, and check the preview before publishing. A recognized file shows drag-to-look controls in the preview. If the preview is still flat, do not publish and hope — the file that goes up is the file people see.

What if it still shows flat after the fix?

Run this checklist in order, because the failure is almost always one of these:

  1. Is the uploaded file actually the tagged copy? The classic mistake is tagging photo-fixed.jpg and then uploading the original photo.jpg from the downloads folder out of habit.
  2. Is it a JPEG? A tagged PNG is still a PNG. Convert to JPEG first, then tag, then upload — in that order, since converting after tagging strips the tags again.
  3. Is it really 2:1? Divide width by height. A 6000×3000 render is fine; a 6000×2800 crop is not a full sphere, and no metadata will make Facebook treat it as one.
  4. Did anything compress it after tagging? Messaging the file to yourself, or running it through an optimizer, can rebuild the container. Tag last, upload next, nothing in between.
  5. Did you test the preview? If the preview drags, the post will too. If it does not, the file is still wrong — go back to the ExifTool check rather than re-uploading the same file and hoping for a different result.

That last point is the one I see people skip most. Re-uploading an unchanged file is not troubleshooting; it is the same test with the same answer.

The one-sentence version

Facebook shows your 360 photo flat because the JPEG is missing its PhotoSphere XMP tags — inject GPano:ProjectionType=equirectangular and the matching pixel fields, keep the file a JPEG, and upload the tagged copy as a new post.

If you want to check a file before you post it, the injector page linked above reads the same fields it writes. And if you would rather not trust any tool, the ExifTool commands in this article are the whole fix — no account, no upload, no re-render.


Disclosure: I'm the developer of 360 Panorama Viewer (360panoramaviewer.com), a free browser-based 360 studio. The fix in this article works with any tool that writes standard PhotoSphere XMP, including ExifTool — the tags are Google's open specification, not anything proprietary to my site.

Sources: Google's Photo Sphere XMP metadata specification (developers.google.com); the 360 metadata injector reference at 360panoramaviewer.com/360-metadata-injector/

Top comments (0)