7

I am using this jQuery function do display the image before uploading. The images are uploaded from mobile devices and have problems with the exif orientation. This function just change the src of the preview image with the base64 code of the actual file image.

On server side (php) i am using a function to correct the exif rotation on upload.

Can i make something similar in jQuery to my PHP code? So that i can display the image before uploading with the right rotation?

Javascript

function readURL(input) {

    if (input.files && input.files[0]) {
        var reader = new FileReader();

        reader.onload = function (e) {
            $('#blah').attr('src', e.target.result);
        }

        reader.readAsDataURL(input.files[0]);
    }
}

$("#imgInp").change(function(){
    readURL(this);
});

PHP

function image_fix_orientation($filename) {
    $exif = exif_read_data($filename);
    if (!empty($exif['Orientation'])) {
        $image = imagecreatefromjpeg($filename);
        switch ($exif['Orientation']) {
            case 3:
                $image = imagerotate($image, 180, 0);
                break;

            case 6:
                $image = imagerotate($image, -90, 0);
                break;

            case 8:
                $image = imagerotate($image, 90, 0);
                break;
        }

        imagejpeg($image, $filename, 100);
    }
}
Alex
  • 1,033
  • 4
  • 23
  • 43

3 Answers3

16

Yes, sure. To preview image you are using FileReader API that right. But also you have to check EXIF flags and fix orientation. You can use https://raw.githubusercontent.com/jseidelin/exif-js/master/exif.js

And check flags like this:

function fixExifOrientation($img) {
    $img.on('load', function() {
        EXIF.getData($img[0], function() {
            console.log('Exif=', EXIF.getTag(this, "Orientation"));
            switch(parseInt(EXIF.getTag(this, "Orientation"))) {
                case 2:
                    $img.addClass('flip'); break;
                case 3:
                    $img.addClass('rotate-180'); break;
                case 4:
                    $img.addClass('flip-and-rotate-180'); break;
                case 5:
                    $img.addClass('flip-and-rotate-270'); break;
                case 6:
                    $img.addClass('rotate-90'); break;
                case 7:
                    $img.addClass('flip-and-rotate-90'); break;
                case 8:
                    $img.addClass('rotate-270'); break;
            }
        });
    });
}

I prefer to rotate images with CSS transform. Here is implementation:

.rotate-90 {
  -moz-transform: rotate(90deg);
  -webkit-transform: rotate(90deg);
  -o-transform: rotate(90deg);
  transform: rotate(90deg);
}

.rotate-180 {
  -moz-transform: rotate(180deg);
  -webkit-transform: rotate(180deg);
  -o-transform: rotate(180deg);
  transform: rotate(180deg);
}

.rotate-270 {
  -moz-transform: rotate(270deg);
  -webkit-transform: rotate(270deg);
  -o-transform: rotate(270deg);
  transform: rotate(270deg);
}

.flip {
  -moz-transform: scaleX(-1);
  -webkit-transform: scaleX(-1);
  -o-transform: scaleX(-1);
  transform: scaleX(-1);
}

.flip-and-rotate-90 {
  -moz-transform: rotate(90deg) scaleX(-1);
  -webkit-transform: rotate(90deg) scaleX(-1);
  -o-transform: rotate(90deg) scaleX(-1);
  transform: rotate(90deg) scaleX(-1);
}

.flip-and-rotate-180 {
  -moz-transform: rotate(180deg) scaleX(-1);
  -webkit-transform: rotate(180deg) scaleX(-1);
  -o-transform: rotate(180deg) scaleX(-1);
  transform: rotate(180deg) scaleX(-1);
}

.flip-and-rotate-270 {
  -moz-transform: rotate(270deg) scaleX(-1);
  -webkit-transform: rotate(270deg) scaleX(-1);
  -o-transform: rotate(270deg) scaleX(-1);
  transform: rotate(270deg) scaleX(-1);
}
0

after spending lots of time on it i edit many things and got this working result. it may help you guys

  function readURLimg(input) {
      if (input.files && input.files[0]) {
          var reader = new FileReader();
          reader.onload = function(e) {
           /* Check Exif and fix orientation of image */


           EXIF.getData(input.files[0], function() {
             //document.write('Exif=', EXIF.getTag(this, "Orientation"));
            // return;
          switch(parseInt(EXIF.getTag(this, "Orientation"))) {

                  case 2:
                      $("#img-file").attr('class','flip'); break;
                  case 3:
                      $("#img-file").attr('class','rotate-180'); break;
                  case 4:
                      $("#img-file").attr('class','flip-and-rotate-180'); break;
                  case 5:
                      $("#img-file").attr('class','rotate-90'); break;
                  case 6:
                      $("#img-file").attr('class','flip-rotate-90'); break;
                  case 7:
                      $("#img-file").attr('class','rotate-270'); break;
                  case 8:
                      $("#img-file").attr('class','flip-and-rotate-270'); break;
              }

              $("#m").text('Exif='+EXIF.getTag(this, "Orientation"));
              $('#img-file').attr('src', e.target.result).width('50%').height('auto');


      });
    };
      reader.readAsDataURL(input.files[0]);
  }
}
<style>

.rotate-90 {
  -moz-transform: rotate(90deg);
  -webkit-transform: rotate(90deg);
  -o-transform: rotate(90deg);
  transform: rotate(90deg);
}

.rotate-180 {
  -moz-transform: rotate(180deg);
  -webkit-transform: rotate(180deg);
  -o-transform: rotate(180deg);
  transform: rotate(180deg);
}

.rotate-270 {
  -moz-transform: rotate(270deg);
  -webkit-transform: rotate(270deg);
  -o-transform: rotate(270deg);
  transform: rotate(270deg);
}

.flip {
  -moz-transform: scaleX(-1);
  -webkit-transform: scaleX(-1);
  -o-transform: scaleX(-1);
  transform: scaleX(-1);
}

.flip-and-rotate-90 {
  -moz-transform: rotate(90deg) scaleX(-1);
  -webkit-transform: rotate(90deg) scaleX(-1);
  -o-transform: rotate(90deg) scaleX(-1);
  transform: rotate(90deg) scaleX(-1);
}

.flip-and-rotate-180 {
  -moz-transform: rotate(180deg) scaleX(-1);
  -webkit-transform: rotate(180deg) scaleX(-1);
  -o-transform: rotate(180deg) scaleX(-1);
  transform: rotate(180deg) scaleX(-1);
}

.flip-and-rotate-270 {
  -moz-transform: rotate(270deg) scaleX(-1);
  -webkit-transform: rotate(270deg) scaleX(-1);
  -o-transform: rotate(270deg) scaleX(-1);
  transform: rotate(270deg) scaleX(-1);
}
</style>
<script src="https://cdn.jsdelivr.net/npm/exif-js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    
    <div id="m"></div>
    
    <input id="choose-img" accept="image/*" name="image" type="file" onchange="readURLimg(this);">
<img class="img-uploaded" id="img-file">
  • Welcome to Stack Overflow. Code-only answers are discouraged on Stack Overflow because they don't explain how it solves the problem. Please edit your answer to explain what this code does and how it answers the question, so that it is useful to the OP as well as other users also with similar issues. – FluffyKitten Aug 03 '20 at 20:06
-1
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<input id="inp" type='file'>
<p id="b64"></p>
<img id="img" width="300px" height="300px">
</body>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js">
</script>
<script type="text/javascript">
function readFile() {
if (this.files && this.files[0])
{
  var FR= new FileReader();
  FR.onload = function(e)
  {
    document.getElementById("img").src=e.target.result;
    document.getElementById("b64").innerHTML=e.target.result;
  };
FR.readAsDataURL( this.files[0] );
}
else
{
  alert("in else");
}
}
document.getElementById("inp").addEventListener("change", readFile, false);
</script>
</html>