Proper Image Rotation from Mobile Uploads

21902
8
04-17-2015 05:09 PM
Highlighted
MVP Regular Contributor

Greetings,

We have a couple of apps that allow users to post images that are saved as an attachment to a feature class.  This all works very well until you want to display the image embedded on on another web page.  Depending on how the user took the image, it can be rotated or flipped so that it won't have the proper orientation on your web page by default.  On some browsers, if you view the image directly, it does display in the proper orientation.

This problem is created when devices want to take images very quickly and don't want to take the time to save the image in the proper orientation. Instead they are stored with EXIF information which contains a wide gamut of information pertaining specifically to that image.  GPS information, date and time, device, and many others including orientation.

Using Sebastian Tchaun's JavaScript to interpret this information and makes it possible to orient the image properly.  His repo is on github at: blueimp/JavaScript-Load-Image · GitHub

With some assistance from Randy Bonds Jr.​ some basic code to make this happen:

load the code:

    <script src="js/load-image.js"></script>

    <script src="js/load-image-orientation.js"></script>

    <script src="js/load-image-meta.js"></script>

    <script src="js/load-image-exif.js"></script>

Get the attached image:

featureLayer.queryAttachmentInfos(featureAttributes.OBJECTID, loadAnImage, errorImage);

Load and orient the image:

        function loadAnImage(response) {

            var imgSource = response[0].url + "/" + response[0].name;

            var xhr = new XMLHttpRequest();

            xhr.open('GET', imgSource, true);

            xhr.responseType = 'blob';

            xhr.onload = function(e) {

                var ori = 0;

                if (this.status == 200) {

                    var blob = this.response;

                    loadImage.parseMetaData(blob, function(data) {

                        if (data.exif) {

                            ori = data.exif.get('Orientation');

                        }

                        var loadingImage = loadImage(

                            blob,

                            function(img) {

                                document.body.appendChild(img);

                            }, {

                                maxWidth: 600,

                                canvas: true,

                                orientation: ori

                            }

                        );

                    });

                }

            };

            xhr.send();

        }

I hope this helps someone else going through a similar struggle or if someone has an even better method for accomplishing proper image orientation, I would love to hear from you.

Regards,

Tom

8 Replies
Highlighted
Occasional Contributor

Tom,

This was really helpful (I was trying the same thing and didn't realize I needed an XMLHttpRequest to get the actual image file -- passing the url referencing the image to loadImage does not work).

Now, I'm trying to put the image attachment into an InfoWindow but I'm having trouble using the deferred object implementation of infoTemplate.setContent(myFunction);

Any ideas? I'll post my solution here if and when I figure it out.

Reply
0 Kudos
Highlighted
Occasional Contributor

Here is the code to show to correctly oriented image in an infoWindow:

function contentHandler(graphic) {

  var content = document.createElement('div');

  if (graphic.attributes.Address != null) {

       content.innerHTML = "<b>Address:</b></br>" + graphic.attributes.Address + "</br>";

  }

  var OID = graphic.attributes.OBJECTID;

  var imgSrc = "";

  featureLayer.queryAttachmentInfos(OID, function(info) {

       imgSrc = info[0].url + "/" + info[0].name

       // send GET request to get jpeg file

       var xhr = new XMLHttpRequest();

       xhr.open('GET', imgSrc, true);

       xhr.responseType = 'blob';

       xhr.onload = function(e) {

            var ori = 0;

            if (this.status == 200) {

                 var blob = this.response;

                 loadImage.parseMetaData(blob, function(data) { //read image metadata to get orientation info

                      if (data.exif) {

                           ori = data.exif.get('Orientation');

                      }

                      var loadingImage = loadImage(blob, function(img) {

                      content.appendChild(img); //append correctly oriented image to content

                      }, {

                           maxWidth : 150,

                           canvas : true,

                           orientation : ori

                      });

                 });

            }

           };

       xhr.send();

  });

  return content;

};

infoTemplate.setContent(contentHandler);

Reply
0 Kudos
Highlighted
MVP Regular Contributor

Brandon,

Excellent!  Glad you got it working and thanks for posting the result.

Regards,

Tom

Reply
0 Kudos
Highlighted
New Contributor III

Any python code anywhere on this?

I am having issues with photos orienting correctly in ArcMap (data driven pages)...

Any help would be greatly appreciated!

Cheers,

Jessica

Reply
0 Kudos
Highlighted
MVP Regular Contributor

Jessica,

I have not worked on this issue in python, but I found a package that would allow you to read the EXIF information from the image. You can find the package here:

ExifRead 2.1.2 : Python Package Index

Once you have read the EXIF information and gotten the image orientation information, you could rotate the image in your data driven page.  You may view your images in a dataframe element rather than an picture element.  Dataframes can be rotated.

Regards,

Tom

Reply
0 Kudos
Highlighted
New Contributor II

Thanks for posting this. I assume the application for this script is in a custom web map. I'm not finding any guidance on properly orienting photos in a popup in ArcGIS Online. I've successfully run the Show Attachments in Web Map Popup script on my hosted feature service, and am displaying the photos in my map, as well as providing links to the attachments, in the popup. You'll notice that the orientation of photo in the popup is incorrect while the attachment loads in a new browswer window oriented properly. Could this code be adapted to be used in a custom popup?  

Thanks, 
 -Neil

Highlighted
MVP Regular Contributor

Neil,

Yes, I used the code for a custom web app.  There is also a post above from Brandon Flessner about using the code in an infoWindow (popup).   If you are creating an app to share in the AGOL workspace, their popups don't use the EXIF information to properly orient the image and their isn't a way for you to configure the popup to make use of the EXIF information.  

You would have to save the app you created in AGOL and use Brandon's code to modify the popup for the image to orient properly.  It would be ideal if the AGOL popups would honor the EXIF information.  It might be good to post it as an idea.  If it gets enough votes, they might consider adding functionality to display images with correct orientation.

Regards,

Tom

Highlighted
New Contributor III

Has anyone posted this as an idea on https://ideas.arcgis.com/ ?

I have the same problem, but I don't know how to implement code and would much prefer to have this as an alternative in pop-up konfigurations. I'm ready to vote up the idea!