Analyzing exif data during the process of uploading a batch of images

My website allows users to upload multiple images simultaneously. I want to check the EXIF rotation tag of each uploaded image in order to manually rotate the images in the browser if needed.

I came across a solution for reading the EXIF rotation value of an image:

While this method works fine for single image uploads, it doesn't function properly for multiple images as fr.onloadend completes after reading all the images.

Currently, I am storing the image names and rotation values in a hash (rotate_images) and plan to apply these rotations later when rendering the images on the page.

Below is the code snippet I have so far:

  $('#file').change(function(){    
    for(var i = 0; i<this.files.length; i++){
        var file = this.files[i];
        var file_path = this.files.item(i).name;
        if(file_path){
            var startIndex = (file_path.indexOf('\\') >= 0 ? file_path.lastIndexOf('\\') : file_path.lastIndexOf('/'));
            var filename = file_path.substring(startIndex);
            if (filename.indexOf('\\') === 0 || filename.indexOf('/') === 0) {
              filename = filename.substring(1);
            }
            console.log('uploading image ' + filename);
        }
        fr = new FileReader;
        fr.onloadend = function(){
          console.log('getting exif');
          var exif = EXIF.readFromBinaryFile(new BinaryFile(this.result));
          var orientation = exif.Orientation;
          console.log(filename +' has orientation ' + orientation);
          if(orientation != 1){
            rotate_images[filename] = orientation;
          }
        }
        fr.readAsBinaryString(file); 
    }
  });

After analyzing the logs, here's what I found:

uploading image camera.JPG 
uploading image robot.JPG 
uploading image snack.jpg 
getting exif 
snack.jpg has orientation 8 
getting exif 
snack.jpg has orientation 8
getting exif 
snack.jpg has orientation 1 

The logs reveal that the script is only reading the last file. How can I delay the loop until each file is read? Is there an alternate method to extract EXIF orientation data from multiple files?

Here are the scripts I'm utilizing to access the EXIF information:

Answer №1

Oops! I jumped the gun, but fortunately, I found the solution in this post:

This is how my code ended up looking:


$('#file').change(function(){    
  for(var i = 0; i<this.files.length; i++){
    (function(file){
      var file = file;
      var file_path = file.name;
      if(file_path){
          var startIndex = (file_path.indexOf('\\') >= 0 ? file_path.lastIndexOf('\\') : file_path.lastIndexOf('/'));
          var filename = file_path.substring(startIndex);
          if (filename.indexOf('\\') === 0 || filename.indexOf('/') === 0) {
            filename = filename.substring(1);
          }
          console.log('uploading image ' + filename);
      }
      fr = new FileReader;
      fr.onloadend = function(e){
        console.log('getting exif');
        var exif = EXIF.readFromBinaryFile(new BinaryFile(e.target.result));
        var orientation = exif.Orientation;
        console.log(filename +' has orientation ' + orientation);
        if(orientation != 1){
          rotate_images[filename] = orientation;
        }
      }
      fr.readAsBinaryString(file); 
    })(this.files[i]);
  }
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Updating the value property of an object within a loop dynamically in React

At the moment, I am utilizing an array of objects called "mainArr" as shown below, I have implemented a loop inside a function to filter object properties, but I want to dynamically replace obj.name with obj."param" based on the parameter passed. Both nam ...

I'm curious about how I can selectively utilize vuex-persistedstate with Nuxt for certain stores only

Check out this library: https://github.com/robinvdvleuten/vuex-persistedstate. I have customized the provided plugin file for Nuxt. import createPersistedState from 'vuex-persistedstate' export default ({ store }) => { createPersistedState ...

Encountering an Error while Setting Up NextJS on Vercel

Hello, I'm a newcomer to the world of web development. My current goal is to deploy my first NextJS app on Vercel, but I keep encountering an error. Error: SyntaxError: Unexpected token T in JSON at position 0 at JSON.parse (<anonymous>) ...

Utilizing AngularJS to Extract JSON Data from Gzipped Files Stored Locally via Ajax

Currently, I am attempting to retrieve and read a JSON file that is stored in data.gz using AngularJS's $http service. However, when I make the request, all I get back are strange symbols and characters as the response. My application is being run loc ...

Attempting to save the result of a fetch call into a variable for the purpose of rendering it as a list in a

I'm attempting to fetch the top 5 NFT collections based on volume and display them in a table format. However, I'm facing an issue where the data is not being mapped correctly and when I click the "get" button, all content on the webpage disappea ...

Enhance filtering capabilities in ng-repeat by adding controls

After utilizing ng-repeat to display some JSON data, I have incorporated form controls to filter output data from another JSON file. Here is a simplified example: First JSON data: var technologies = [ {"id":"5", "slug":"mysql", "label":"MyS ...

Jasmine examination fails to progress to the subsequent segment of the promise

I want to test a specific function: function initializeView() { var deferred = $q.defer(); if(this.momentArray) { core.listMoments(constants.BEST_MOMENT_PREFIX, '').then(function(moments) { //Ommit ...

Eliminating any spaces in the password prior to finalizing the form submission

After submitting the Form, I am trying to remove all spaces from the Password field. This is my current code: $(document).on("submit", "form#user-login", function(e){ e.preventDefault(); var emailAdd = $("#edit-pass").val().replace(/ / ...

Differentiating between ng-show and ng-if in AngularJS

ng-if and ng-show appear to function in a similar manner. <img src="spinner.gif" ng-if="showSpinner"> <img src="spinner.gif" ng-show="showSpinner"> Are there any distinctions between the two? Is there an impact on performance? How can one d ...

Troubleshooting: PHP AJAX Image Upload Issue - Images Not Being Uploaded

I am having an issue with my code. Although it doesn't show any errors in the console, clicking the upload button does not trigger any action. Following a tutorial, I tried to send a post request to itself, but the image is neither uploaded to the des ...

Achieve identical outcomes with PHP's `strlen` function and jQuery's `val().length` method

Currently, I am utilizing jQuery to dynamically count the value of a textarea: function count_chars () { count_chars=$('#text_textarea').val().length; } Upon submission, I serialize the form and send the textarea text via AJAX to a PHP file ...

Utilize pivot to manage user roles and permissions in ExpressJS application using Mongoose

My user schema is structured as shown below const userSchema = mongoose.Schema({ username: { type: String, required: true, }, first_name: { type: String, required: true, }, last_name: { type: Stri ...

extracting the HTML content from JavaScript and saving it into a standalone file

update When I click a link, a popup opens and I see all this HTML. The smile method is called when I click the link, and we append HTML in that method so that we can see it when the popup is opened. I moved it to a separate file something.component.html, ...

Tips for setting up npm dependencies in a subfolder

Within the main directory, I have a package.json file that contains this command: "install": "cd packages/my-package && yarn". Every time I execute yarn run install, my intention is for it to enter into the specified package, set up the node modul ...

Utilizing JavaScript and its scope to include text within an HTML document

I am currently working on a program that receives input from the user twice, specifically a risk carrier and a sum (although it is just a placeholder for now), groups these two values together, and then repeats the contents in a loop. You can see the progr ...

Utilizing Express REST API with Postgres through the HTTP method

I am currently working on implementing REST APIs with Express and Postgres. I have a scenario where I need to delete all instances from a table based on the user_id foreign key, and then insert new instances with the same user_id. I'm unsure which HTT ...

Using multiple where clauses in Firebase for advanced querying

Let me explain the scenario. Within my database, there is a Users collection. Some users have a property called userType, while others do not. The values for userType can either be person or company. I want to retrieve only the users that have the userTyp ...

Numerous Axios GET calls made by various components

I am facing an issue where I have two different components rendering on the main screen. Both of them make multiple axios.get requests to fetch data. However, upon initial page load, only the last component successfully retrieves the data while the first c ...

Issue encountered during creation of a polyline in Cesium

When attempting to create a polyline in my ReactJs app using the code below, I encountered an error message stating "DeveloperError: Expected value to be greater than or equal to 0.0125, the actual value was 0." Can someone shed some light on why this er ...

Gatsby: A guide on inserting unadulterated HTML within the head section

Is it possible to insert raw HTML into the <head></head> section of every page in a Gatsby.js project? I need to add a string of HTML for tracking purposes, including inline and external script tags, link tags, and meta tags. For example, here ...