Notes on Making Multi-Angle '3D' Photos

There are three steps:

  1. Get the photos
  2. Process the photos
  3. Display the photos

Also, here are some useful Photoshop scripts

Get the photos

Photos of an object
from multiple angles along an arc This involves taking shots of the subject from multiple angles, ideally from points along an arc a fixed distance from the subject.

Pick a target

Pick a target as the focal point. For the Thumb photos, I picked the top of the Thumb; for the Coyote Gulch photos, I picked the top of the foremost 'toe' of the knob. It is important that each shot be centered on the same target. I used the cross-hairs of my viewfinder.

Shoot level

Processing later will be easier if each shot is level (or at least consistent). It's helpful if there is something in the photo that can be used later as a reference (eg., the horizon); you'll be able to use that later to align the rotation of the images.

Number of shots

(angle between shots) A small angle between shots will make the display smoother (more like a video), but each shot adds to the burden of taking shots, processing them, and download time for viewers. I aimed for about a dozen shots. For The Thumb and Coyote Gulch, which were objects about 300m to 500m distant, I tried to space shots by walking twenty paces along the arc between shots.

Image size

(pixels of resolution) The final display medium will be a computer screen, which doesn't require a lot of pixels. Today's displays are generally at least 1024 pixels wides, so 2048 pixels ought to provide a few years of 'future-proofing'. All the images should be the same size (if not, there will be more processing work later). Moderate JPG compression is probably adequate for displays on a computer screen -- though if camera memory is available, might as well use it; resolution can always be decreased later, but not increased.

Time of day

Low light (morning or evening) is generally best for light on the subject and makes dramatic shadows, but can create problems of high dynamic range if part of the arc ends up shooting into the sun.


I shot each photo of The Thumb and Coyote with automatic exposure, with the idea that the camera would compensate for lighting variations. Alternatively, locking exposure over the series of shots might ensure that the light changes gradually and naturally as you traverse the arc. The Canon Powershot A75 seems to tolerate underexposures better than overexposures (overexposed shots lose information due to clipping, whereas underexposed shots can more often be saved by shifting information from the dark area), so it's best with the A75 to set the camera for the brightest shot and then let the subsequent shots go dark. If the camera will be powered off between shots, a way of locking the exposure would be to use Manual mode, if your camera supports that.

Spare batteries

Shooting an arc of shots is power-consuming because each shot has to be aligned carefully (target and level), and the time between shots (eg., twenty paces) means either leaving the camera on or turning it off and then on soon after. All this is power-consuming (I learned this the hard way).

Process the photos

To get the best display effect, each image must be aligned (position and rotation) and there shouldn't be large differences in exposure between images.

Here's the procedure I used with Photoshop CS (available for 30 days free trial from Adobe):

  • Create a subdirectory (a.k.a folder) on your computer that contains only the images in jpg format from your arc of shots. Name them with a base name followed by a sequence number (for example, I named all the shots of The Thumb with the base name 'thumb_', eg., thumb_1.jpg, thumb_2.jpg, etc). All images should be the same pixel dimensions.
  • Create a Photoshop document with each image loaded as a layer. You can do it manually (tedious), or by using a script I created using Photoshop's javaScript (Photoshop can be controlled by javaScript, visual basic, or appleScript). The script text is included later in this page.
  • An example of reference marks Pick one of your images to be the reference (to which all the other images will be aligned). Create a new layer (named 'reference', say) above your reference image that will act as an alignment guide. Draw markers (eg., crosshairs) on the alignment layer: one set of markers to guide the placement of your focal object, and a horizontal reference line near something in your image that can be used to tell if the photo is level. For example, for The Thumb photos, my focal object was the tip of The Thumb, and my horizontal reference line was drawn near a stratum in the background rocks. I placed the horizontal reference line near the stratum rather than over it, so that it didn't obscure it (note that horizontal references in your images may only be horizontal in all images if they were near camera level).
  • Move your reference layer to the top of the layers palette.
  • Make only the reference layer visible (eg., alt-click the 'eye' on the reference layer), then starting at the bottom, make each layer visible one at a time. You should see each of your layers appear under your reference layer. As you work your way up, notice how well the images align with the reference layer. When you are satisfied that your reference layer is appropriate, go back and start aligning each layer with the reference (using the Move tool and Edit->Transform->Rotate).
  • At this point you should now have all your images aligned. Now crop the document down to whatever is common among all the layers (or do some touch-ups to clone into edges, etc).
  • Do any image adjustments. Image->Adjustments->Match Color might be useful. Image->Adjustments->Shadow & Highlight is usually useful for sunlit photos with shadows. Filter->Sharpen->Unsharp mask is usually useful. If you want to apply the same actions to a number of layers, you can create an Action (record a series of commands) and then use my ApplyActionToVisibleLayers script (see below) to apply it to all visible layers. (Another way to do this is to save all the layers to files, as described below, and then use File->Automate->Batch to apply an action to all files.)
  • Use Image->Image size to set the image size for the document (ie., all layers). The smaller your image, the faster it will download. The trade-off is between size of potential audience (smaller files accomodate lower quality connections) and quality of experience (larger files give a better image). All images need to download before the viewer can see the rotating image, so if you have 10 images each of 20K, that's a 200K download, which takes about 40 seconds on a 56K dial-up link (or you could decide that multi-angle photographs are like video clips -- something really only accessible to people with broadband connections to the internet).
  • Save your PSD file with all the layers. Use the Files->Scripts->Export Layers to Files script to create a set of JPG files in a new directory that will be the source for display in a web browser.

Display the photos (in a browser)

Here's what I did:

  1. Create a new directory to hold common files, and a subdirectory for each of your image sets (presuming you'll eventually have more than one). Copy your images into the subdirectory.
  2. Get a copy of the javascript that displays the images. The script can be downloaded to your computer by clicking on the following link:

    A Java Applet can be used to display the images instead of javascript. The Space Science and Engineering Center at University of Wisconsin developed the AniS applet to display images from weather satellites; it can also be used to display the images of multi-angle photographs. The applet has many things going for it, but viewers of this web page have indicated a preference for javascript. Nevertheless, if you prefer applets, check out the link above.

    multiAngleImage.jsx (ready to use)

    When you see 'Open or Save', click 'Save' to store the script on your disk in the directory created in step 1 above.

  3. Copy one of my multi-angle photo web pages as a starting point. To do that, display one of my pages, eg., The Thumb, and then view the source of the web page (IE6: View->Source). Save the web page HTML as 'index.html' in the subdirectory that contains your images.
  4. Edit that index.html file using a text editor. You need to modify it to suit your circumstances. Specifically, change the script parameters to point to your images. My 'Thumb' image files are named 'thumb_0.jpg', 'thumb_1.jpg', etc and there are 10 of them. Detailed instructions for using the multiAngleImage javascript are in the multiAngleImage.jsx file you downloaded -- just open it with a text editor to read the notes.
  5. Double-click on the index.html file. Your browser should display your images.

To put your stuff on the web, just upload the directory created in step 1, including the subdirectory with your images.

You're done! If you've got a good result, I'd like to see it.

Jim Elder, Oct 2004
Ottawa, Canada

Photoshop Scripts

Photoshop CS 'Actions' (recorded Photoshop commands) differ from Photoshop 'Scripts' in that scripts are programming languages such javaScript, visual basic, and appleScript that permit conditional execution ('if' statements) and access to internal Photoshop objects.

The two scripts below are useful for preparing images for multi-angle display but are not necessary. The scripts can be uploaded to your computer by clicking on either of the following links:

manyFilesIntoOne.jsx (ready to use)
applyActionToVisibleLayers.jsx (see comments below about customizing this one to your system)

When you see 'Open or Save', just click 'Save' to store the script anywhere on your disk. Then use File->Scripts->Browse within Photoshop CS to execute a script.

Note that the applyActionToVisibleLayers script needs to be edited to work on your system. Use any text editor to open the file and make the simple changes indicated by comments within the file.

Here are copies of the two scripts (but download from the links above in case these copies are out of date):

// Photoshop CS script: manyFilesIntoOne // // Given a subdirectory containing many JPG files, this script creates a new // Photoshop document with many layers, each of which is from one of the // subdirectory JPG files. The size of the new doc is set to the size of the // first image file read. // // To use this script, store it anywhere on your disk, then start Photoshop and // use File->Scripts->Browse... to select and execute this script. If you'd // like this script to appear in the list of scripts at File->Scripts, just // store this script in \Program Files\Adobe\Photoshop CS\Presets\Scripts // // References: // \Program Files\Adobe\Photoshop CS\Scripting Guide\Photoshop Scripting Guide.pdf // \Program Files\Adobe\Photoshop CS\Scripting Guide\JavaScript Reference Guide.pdf // // (based on examples from the JavaScript Reference Guide; developed on Windows XP, // not tested on other platforms) // // Jim Elder, Ottawa, Oct 2004 // Save the current preferences var startRulerUnits = app.preferences.rulerUnits; var startTypeUnits = app.preferences.typeUnits; var startDisplayDialogs = app.displayDialogs; // Set Photoshop to use pixels and display no dialogs app.preferences.rulerUnits = Units.PIXELS; app.preferences.typeUnits = TypeUnits.PIXELS; app.displayDialogs = DialogModes.NO; // ask the user to identify the input subdirectory (folder) var inputFilesFolder = Folder.selectDialog( "Select a folder that contains JPG images to be read into one " + "new Photoshop doc as layers", Folder("~")); // the setting of default dir doesn't seem to work for other than ~ // Start the script debugger // uncomment the line below to cause Photoshop to start its debugger at this point // $.level = 1; debugger; // see if the user gave us a folder if (inputFilesFolder != null) { // close all the open documents while (app.documents.length) app.activeDocument.close(); // get all the jpg files in the specified folder var fileList = inputFilesFolder.getFiles("*.jpg"); // open one of them to get its size for (var i = 0; i < fileList.length; i++) { if (fileList[i] instanceof File) { var firstDoc = open(fileList[i]); break; } } // if there was a first doc... if (typeof(firstDoc) != 'undefined') { // create a new document to contain the merged images var mergedDoc = app.documents.add(firstDoc.width, firstDoc.height, firstDoc.resolution, "Merged", NewDocumentMode.RGB, DocumentFill.TRANSPARENT, 1); // close that first doc firstDoc.close(SaveOptions.DONOTSAVECHANGES); // open each file and add it as a layer to the 'merged' doc for (var i = 0; i < fileList.length; i++) { // open only files if (fileList[i] instanceof File) { open (fileList[i]); // save the document name for the layer name in the merged document var docName =; // flatten the document so we get everything and then copy app.activeDocument.flatten(); app.activeDocument.selection.selectAll(); app.activeDocument.selection.copy(); // close file; don't save anything we did app.activeDocument.close(SaveOptions.DONOTSAVECHANGES); // merge this image into the mergedDoc as a new layer mergedDoc.paste(); = docName; } } // sort the layers by name for (var x = 0; x < app.activeDocument.layers.length; x++) { for (var y = 0; y < app.activeDocument.layers.length - 1 - x; y++) { var doc1 = app.activeDocument.layers[y].name; var doc2 = app.activeDocument.layers[y + 1].name; // compare layer names in a non-case sensitive way if (doc1.toUpperCase() > doc2.toUpperCase()) { app.activeDocument.layers[y].move(app.activeDocument.layers[y+1], ElementPlacement.PLACEAFTER); } } } } } // Reset the application preferences app.preferences.rulerUnits = startRulerUnits; app.preferences.typeUnits = startTypeUnits; app.displayDialogs = startDisplayDialogs;
// Photoshop CS script: applyActionToVisibleLayers // // The action hard-coded in this script is performed upon all visible layers. // // It'd be much cooler if the script would display a list of the existing actions and // let the user choose, but I didn't see an easy way of doing that. So for now, just // edit this script. // // References: // \Program Files\Adobe\Photoshop CS\Scripting Guide\Photoshop Scripting Guide.pdf // \Program Files\Adobe\Photoshop CS\Scripting Guide\JavaScript Reference Guide.pdf // // Jim Elder, Ottawa, Oct 2004 // Start the script debugger // uncomment the line below to cause Photoshop to start its debugger at this point // $.level = 1; debugger; for (var i = 0; i < app.activeDocument.layers.length; i++) if (app.activeDocument.layers[i].visible) app.doAction("applyToVisibleLayers", "Jim's actions.atn"); // ******************************************************************************* // * To customize this script to your needs, edit the line above to suit your // * system. The first parameter ('applyToVisibleLayers') is the name of the // * Action that will be executed (change it to one or your actions, or create // * an action with that name). The second parameter ('Jim's actions.atn') is // * the name given by Photoshop to your custom actions (change it to whatever // * yours is called). // *******************************************************************************

Documentation for Photoshop scripts is located in the install area for Photoshop (Windows: \Program Files\Adobe\Photoshop CS\Scripting Guide\). The PDF documents there have enough examples that I was able to glue together the scripts above. To try a script, create it in a text file and then tell Photoshop to execute it using File->Scripts->Browse. Put this:

$.level = 1; debugger;

at the start of a script to tell Photoshop to open its script debugger, then single step through the script for feedback on problems.

As mentioned in the comments of applyActionToVisibleLayers.jsx, I'd appreciate hearing if you know a way to display a menu of user actions (to eliminate the hard-coding in that script).