Skip to content

How to Turn 360 Panoramic Images Into 360 Spin Sets

A panoramic 360 image is a very wide image format that can be used to display a 360 degree view as seen from a single point. Some 360 panoramic images are created by special 360 cameras that can take a single image of the entire panorama, while others can be created by stitching together a series of images that overlap each other into a single image. These images may be used in different verticals such as showing off real estate, for showing the inside and outside of a property, and travel, for showing panoramic views of tourist destinations, cities, islands, mountain views, etc.

360 spin sets, on the other hand, are normally used to showcase individual products as seen from different viewpoints, allowing the user to rotate the object in question about a central axis.

But another use for the 360 spin set is for displaying 360 panoramic images that can also be rotated by a user, giving the effect to the user of turning in place while seeing the 360 view.

The Cloudinary Product Gallery has built-in support for displaying spin sets by automatically fetching all images with a particular tag and combining them into a single spin set, where each image is included as a single frame of the resulting 360 spin set. This makes it super easy to automate the process of creating spin sets with Cloudinary transformations.

The following script takes a panoramic 360 image and generates a 360 spin set that can be easily viewed using Cloudinary’s Product Gallery. The script creates and then uploads all the individual images that will be needed to display it as a single spin set. The script is written in Java, but uses very simple code and can be easily adapted to work with any of the Cloudinary SDKs.


String folder = "panoramic/";
String public_id = "clouds_pan";
double width = 0.4;  
int frames = 50; 

String panPic = folder + public_id;
double newWidth = width / (1 + width);

String frameNumber;
String frameUrl;
String newId;
Map uploadParams;
double xOffset;

for (double i = frames; i >= 0; i--) {
  xOffset = (1 - newWidth) - ((i / frames) * (1 - newWidth));
  frameUrl = cloudinary.url()
          .transformation(new Transformation()
                  .overlay(new Layer()
                          .publicId(panPic)).chain()
                  .width(width)
                  .height(1.0)
                  .crop("crop")
                  .gravity("west").chain()
                  .flags("layer_apply")
                  .gravity("east")
                  .x(-panWidth).chain()
                  .crop("crop")
                  .width(newWidth)
                  .height(1.0)
                  .gravity("west")
                  .x(xOffset)
                  .y(0))
          .generate(panPic);
  frameNumber = String.valueOf(frames - i);
  if (frames - i < 10){frameNumber = "0" + frameNumber;}
  newId = public_id + "_" + frames + "f_" + width + "w";
  uploadParams = ObjectUtils.asMap(
      "public_id", "spinsets/" + newId + frameNumber,
      "tags", newId
  );
  cloudinary.uploader().upload(frameUrl, uploadParams);
}

Code language: JavaScript (javascript)

The script uses the public_id of an uploaded panoramic 360 image. It generates all the images needed and uploads them to your Cloudinary account. Every sequential image is identified with a combination of the public_id and a sequential number, so that the order of the images will be preserved when displaying them in the Product Gallery. All the assets are also given the same tag when uploaded to enable the Product Gallery to fetch them all to display as a spin set. The script needs to be updated with the correct folder and public_id of your uploaded panoramic 360 image, but it can also be customized by selecting new values for the width and frames.

The width of the generated 360 spin set images is defined by the width parameter in the script, and is given as a real number relative to the original panoramic image. So to create a spin set where the individual images are 40% of the width of the original uploaded 360 panoramic image, set the width parameter to 0.4.

The following gallery shows examples of 3 different spin sets created from the same panoramic image, the first with a width of 30% of the original, then 50% and lastly with 80%.

The frames parameter in the script determines the number of individual images to be created by the script for the generated spin set. Selecting a higher number of frames will result in smaller changes between the individual images and a smoother scrolling experience when rotating the spin set.

The following gallery shows examples of 3 different spin sets created from the same panoramic image, the first with 20 frames, then 50 frames, and lastly with 90 frames:

Of course, the more images that are generated, the larger the bandwidth required to deliver all the images to the end user.

Another consideration is that the Product Gallery widget is also fully responsive to the available width, and requests images from Cloudinary that fit the width needed. This saves bandwidth by only delivering scaled down images depending on the user’s view port (browser or mobile device). This may result in a large number of generated image files when displaying the spin sets in multiple view ports. So, if you want to limit the number of generated images, you can add the imageBreakpoint parameter to the code for displaying the Product Gallery, and select a larger value than every 100 pixels (the default).

All the Product Gallery needs in order to display spin sets is the tag that they all have in common. The Product Gallery then fetches all images with a that tag and combines them into a single entity, where each image is included as a single frame of the resulting 360 spin set, and sorted alphanumerically by their Public ID, which is why the script adds in the frame number to the public_id of the individual frames. The following code will render the Product Gallery and display the spin set of all images tagged with “room360”:

const cloudName = "demo"; 
const myGallery = cloudinary.galleryWidget({
container: "#my-gallery",
cloudName: cloudName,
mediaAssets: [
  { tag: "room360", mediaType: "spin" } ],
});

myGallery.render();
Code language: JavaScript (javascript)

See the Product Gallery documentation for more information on the Product Gallery and all the ways the gallery can be customized.

Displaying panoramic 360 images as interactive spin sets is a novel and engaging experience for your users. The beauty of 360 panoramic images is they can be broken up in a way that seamlessly joins the beginning of the image to the end, allowing the user to experience continuously turning in place. All widget, image transformation and delivery features discussed here are available with no extra charge for all Cloudinary’s plans, including the free plan.

Back to top