How to draw photo with correct orientation in canvas after capture photo by using input[type='file'] in mobile web browser?

后端 未结 5 1470
青春惊慌失措
青春惊慌失措 2020-12-07 08:33

I am making a simple web app in mobile which allow visitor to capture photo by using html5 input[type=file] element. Then I will display it on the web for preview, and then

相关标签:
5条回答
  • 2020-12-07 09:15

    If you just want the Orientation tag, using exif.js:

    EXIF.getData(file, function () {
        alert(this.exifdata.Orientation);
    });
    

    In my tests, iOS camera only returns 1,3,6 or 8.

    0 讨论(0)
  • 2020-12-07 09:16

    Based on your answers, I created a function to auto rotate iphone photo to right direction.
    Just pass in an input.files[0] and an optional max width or height, it'll output a blob used for form submit.
    https://github.com/gonnavis/iphone_photo_rotation_adjust

    0 讨论(0)
  • 2020-12-07 09:18

    You'll need to read the exif data and check if exif.Orientation is one of the following:

    fileReader.onloadend = function() {
    
        var exif = EXIF.readFromBinaryFile(new BinaryFile(this.result));
    
        switch(exif.Orientation){
    
           case 8:
               ctx.rotate(90*Math.PI/180);
               break;
           case 3:
               ctx.rotate(180*Math.PI/180);
               break;
           case 6:
               ctx.rotate(-90*Math.PI/180);
               break;
    
    
        }
    };
    
    0 讨论(0)
  • 2020-12-07 09:18

    add exif.js to your project, then:

    EXIF.getData(file,function() {
      var orientation = EXIF.getTag(this,"Orientation");
      var can = document.createElement("canvas");
      var ctx = can.getContext('2d');
      var thisImage = new Image;
      thisImage.onload = function() {
        can.width  = thisImage.width;
        can.height = thisImage.height;
        ctx.save();
        var width  = can.width;  var styleWidth  = can.style.width;
        var height = can.height; var styleHeight = can.style.height;
        if (orientation) {
          if (orientation > 4) {
            can.width  = height; can.style.width  = styleHeight;
            can.height = width;  can.style.height = styleWidth;
          }
          switch (orientation) {
          case 2: ctx.translate(width, 0);     ctx.scale(-1,1); break;
          case 3: ctx.translate(width,height); ctx.rotate(Math.PI); break;
          case 4: ctx.translate(0,height);     ctx.scale(1,-1); break;
          case 5: ctx.rotate(0.5 * Math.PI);   ctx.scale(1,-1); break;
          case 6: ctx.rotate(0.5 * Math.PI);   ctx.translate(0,-height); break;
          case 7: ctx.rotate(0.5 * Math.PI);   ctx.translate(width,-height); ctx.scale(-1,1); break;
          case 8: ctx.rotate(-0.5 * Math.PI);  ctx.translate(-width,0); break;
          }
        }
    
        ctx.drawImage(thisImage,0,0);
        ctx.restore();
        var dataURL = can.toDataURL();
    
        // at this point you can save the image away to your back-end using 'dataURL'
      }
    
      // now trigger the onload function by setting the src to your HTML5 file object (called 'file' here)
      thisImage.src = URL.createObjectURL(file);
    
    });
    

    The orientation block (using translate and rotate) is copied from https://github.com/blueimp/JavaScript-Load-Image/blob/master/js/load-image-orientation.js and so I consider it well proven. It certainly worked perfectly for me, whereas other approaches didn't.

    0 讨论(0)
  • 2020-12-07 09:22

    Ben's great answer pointed me in the right direction but as far as I can tell the actual rotations are incorrect (at least they were for me) and don't cover all possible cases. The solution below worked for me. It is based on the one found in the JavaScript-Load-Image library (which I found via this great SO question). Note that I also had to translate the Canvas context to the center as it originates from the top left corner when rotating).

    fileReader.onloadend = function() {
    
        var exif = EXIF.readFromBinaryFile(new BinaryFile(this.result));
    
        switch(exif.Orientation){
    
            case 2:
                // horizontal flip
                ctx.translate(canvas.width, 0);
                ctx.scale(-1, 1);
                break;
            case 3:
                // 180° rotate left
                ctx.translate(canvas.width, canvas.height);
                ctx.rotate(Math.PI);
                break;
            case 4:
                // vertical flip
                ctx.translate(0, canvas.height);
                ctx.scale(1, -1);
                break;
            case 5:
                // vertical flip + 90 rotate right
                ctx.rotate(0.5 * Math.PI);
                ctx.scale(1, -1);
                break;
            case 6:
                // 90° rotate right
                ctx.rotate(0.5 * Math.PI);
                ctx.translate(0, -canvas.height);
                break;
            case 7:
                // horizontal flip + 90 rotate right
                ctx.rotate(0.5 * Math.PI);
                ctx.translate(canvas.width, -canvas.height);
                ctx.scale(-1, 1);
                break;
            case 8:
                // 90° rotate left
                ctx.rotate(-0.5 * Math.PI);
                ctx.translate(-canvas.width, 0);
                break;
    
    
        }
    };
    
    0 讨论(0)
提交回复
热议问题