diff --git a/doc/image_orientations.gif b/doc/image_orientations.gif
new file mode 100755
index 0000000000000000000000000000000000000000..89c4c3ea1444de6b32e1cecc2d2825e430c833e8
Binary files /dev/null and b/doc/image_orientations.gif differ
diff --git a/src/components/offset-relative-to.js b/src/components/offset-relative-to.js
index e00acd4e57a1842e5b8116c5448a3c2088443eab..877cfcf8a118a13eb94200925d1ac53053d9faa1 100644
--- a/src/components/offset-relative-to.js
+++ b/src/components/offset-relative-to.js
@@ -13,6 +13,9 @@ AFRAME.registerComponent("offset-relative-to", {
     on: {
       type: "string"
     },
+    orientation: {
+      default: 1 // see doc/image_orientations.gif
+    },
     selfDestruct: {
       default: false
     }
@@ -27,6 +30,9 @@ AFRAME.registerComponent("offset-relative-to", {
   },
 
   updateOffset: (function() {
+    const y = new THREE.Vector3(0, 1, 0);
+    const z = new THREE.Vector3(0, 0, -1);
+    const QUARTER_CIRCLE = Math.PI / 2;
     const offsetVector = new THREE.Vector3();
     return function() {
       const obj = this.el.object3D;
@@ -40,6 +46,38 @@ AFRAME.registerComponent("offset-relative-to", {
       this.el.body && this.el.body.position.copy(obj.position);
       target.getWorldQuaternion(obj.quaternion);
       this.el.body && this.el.body.quaternion.copy(obj.quaternion);
+
+      // See doc/image_orientations.gif
+      switch (this.data.orientation) {
+        case 8:
+          obj.rotateOnAxis(z, 3 * QUARTER_CIRCLE);
+          break;
+        case 7:
+          obj.rotateOnAxis(z, 3 * QUARTER_CIRCLE);
+          obj.rotateOnAxis(y, 2 * QUARTER_CIRCLE);
+          break;
+        case 6:
+          obj.rotateOnAxis(z, QUARTER_CIRCLE);
+          break;
+        case 5:
+          obj.rotateOnAxis(z, QUARTER_CIRCLE);
+          obj.rotateOnAxis(y, 2 * QUARTER_CIRCLE);
+          break;
+        case 4:
+          obj.rotateOnAxis(z, 2 * QUARTER_CIRCLE);
+          obj.rotateOnAxis(y, 2 * QUARTER_CIRCLE);
+          break;
+        case 3:
+          obj.rotateOnAxis(z, 2 * QUARTER_CIRCLE);
+          break;
+        case 2:
+          obj.rotateOnAxis(y, 2 * QUARTER_CIRCLE);
+          break;
+        case 1:
+        default:
+          break;
+      }
+
       if (this.data.selfDestruct) {
         if (this.data.on) {
           this.el.sceneEl.removeEventListener(this.data.on, this.updateOffset);
diff --git a/src/components/super-spawner.js b/src/components/super-spawner.js
index f760a29e25cc1fb680b55a0b504a42202948f0da..0c69e82da5cfe8c62e4aabafd2506fcf11613e3d 100644
--- a/src/components/super-spawner.js
+++ b/src/components/super-spawner.js
@@ -84,7 +84,7 @@ AFRAME.registerComponent("super-spawner", {
     const thisGrabId = nextGrabId++;
     this.heldEntities.set(hand, thisGrabId);
 
-    const entity = addMedia(this.data.src, ObjectContentOrigins.SPAWNER);
+    const entity = addMedia(this.data.src, ObjectContentOrigins.SPAWNER).entity;
     entity.object3D.position.copy(
       this.data.useCustomSpawnPosition ? this.data.spawnPosition : this.el.object3D.position
     );
diff --git a/src/hub.js b/src/hub.js
index 8db01eaddef8c92fa5dd4a8da040fa2473615b56..5e347527cfd99e822cb0d6adf6c9cb3d0c7bca77 100644
--- a/src/hub.js
+++ b/src/hub.js
@@ -306,11 +306,14 @@ const onReady = async () => {
 
     const offset = { x: 0, y: 0, z: -1.5 };
     const spawnMediaInfrontOfPlayer = (src, contentOrigin) => {
-      const entity = addMedia(src, contentOrigin, true);
+      const { entity, orientation } = addMedia(src, contentOrigin, true);
 
-      entity.setAttribute("offset-relative-to", {
-        target: "#player-camera",
-        offset
+      orientation.then(or => {
+        entity.setAttribute("offset-relative-to", {
+          target: "#player-camera",
+          offset,
+          orientation: or
+        });
       });
     };
 
diff --git a/src/react-components/2d-hud.js b/src/react-components/2d-hud.js
index effa07f2983ee8752e01c0f2a6892d0e99a6bbb0..e50d295987189b5eb00827d6333e6312fa156acd 100644
--- a/src/react-components/2d-hud.js
+++ b/src/react-components/2d-hud.js
@@ -75,6 +75,7 @@ const BottomHUD = ({ onCreateObject, showImageOnlyButton, onMediaPicked }) => (
 
 BottomHUD.propTypes = {
   onCreateObject: PropTypes.func,
+  showImageOnlyButton: PropTypes.bool,
   onMediaPicked: PropTypes.func
 };
 
diff --git a/src/utils/media-utils.js b/src/utils/media-utils.js
index 83a5f788ea841c1f3343c2068293b97bf9f53f3e..825865dcac289bc2afa1f8f3ed878b485e682ee1 100644
--- a/src/utils/media-utils.js
+++ b/src/utils/media-utils.js
@@ -51,6 +51,45 @@ export const upload = file => {
   }).then(r => r.json());
 };
 
+// https://stackoverflow.com/questions/7584794/accessing-jpeg-exif-rotation-data-in-javascript-on-the-client-side/32490603#32490603
+function getOrientation(file, callback) {
+  const reader = new FileReader();
+  reader.onload = function(e) {
+    const view = new DataView(e.target.result);
+    if (view.getUint16(0, false) != 0xffd8) {
+      return callback(-2);
+    }
+    const length = view.byteLength;
+    let offset = 2;
+    while (offset < length) {
+      if (view.getUint16(offset + 2, false) <= 8) return callback(-1);
+      const marker = view.getUint16(offset, false);
+      offset += 2;
+      if (marker == 0xffe1) {
+        if (view.getUint32((offset += 2), false) != 0x45786966) {
+          return callback(-1);
+        }
+
+        const little = view.getUint16((offset += 6), false) == 0x4949;
+        offset += view.getUint32(offset + 4, little);
+        const tags = view.getUint16(offset, little);
+        offset += 2;
+        for (let i = 0; i < tags; i++) {
+          if (view.getUint16(offset + i * 12, little) == 0x0112) {
+            return callback(view.getUint16(offset + i * 12 + 8, little));
+          }
+        }
+      } else if ((marker & 0xff00) != 0xff00) {
+        break;
+      } else {
+        offset += view.getUint16(offset, false);
+      }
+    }
+    return callback(-1);
+  };
+  reader.readAsArrayBuffer(file);
+}
+
 let interactableId = 0;
 export const addMedia = (src, contentOrigin, resize = false) => {
   const scene = AFRAME.scenes[0];
@@ -61,6 +100,15 @@ export const addMedia = (src, contentOrigin, resize = false) => {
   entity.setAttribute("media-loader", { resize, src: typeof src === "string" ? src : "" });
   scene.appendChild(entity);
 
+  const orientation = new Promise(function(resolve) {
+    if (src instanceof File) {
+      getOrientation(src, x => {
+        resolve(x);
+      });
+    } else {
+      resolve(1);
+    }
+  });
   if (src instanceof File) {
     upload(src)
       .then(response => {
@@ -78,5 +126,5 @@ export const addMedia = (src, contentOrigin, resize = false) => {
     scene.emit("object_spawned", { objectType });
   });
 
-  return entity;
+  return { entity, orientation };
 };