background

Different browsers handle the rendering of image exif rotation information differently. For example: when taking an image in portrait mode from iPhone and uploading the image to my app, it rotates the display. However, I checked the EXIF meta info images for each of my devices and found that both images have the same value in the orientation attribute

model Phenomenon
IOS 13.3.1 version (old)image.png
IOS 13.4.1 (new)image.png

root of the problem

Webkit browsers will rotate images before you upload them based on EXIF data, only supported in newer versions of Chrome (81) and IOS 13.4.1 Mobile Safari. As a result, if the application itself rotates according to the exif information, there will be a problem with rendering one more time.

Related bug link https://bugs.chromium.org/p/chromium/issues/detail?id=1074354

Solution

Create an image with a width and height of 2x3, render it with the img tag, check whether it is rotated, and then hand it over to the canvas to manually rotate it.

Key parts of relevant code

 // Code adapted from
  // https://github.com/blueimp/JavaScript-Load-Image/blob/24eda0f970b69f681dd76f4ed04e3e041a9bc1fa/js/load-image-orientation.js#L67-L103

  function imageOrientationTest($, cb) {
    // black+white 3x2 JPEG, with the following meta information set:
    // - EXIF Orientation: 6 (Rotated 90° CCW)
    // Image data layout (B=black, F=white):
    // BFF
    // BBB
    var testImageURL =
      'data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAA' +
      'AAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA' +
      'QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE' +
      'BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAIAAwMBEQACEQEDEQH/x' +
      'ABRAAEAAAAAAAAAAAAAAAAAAAAKEAEBAQADAQEAAAAAAAAAAAAGBQQDCAkCBwEBAAAAAAA' +
      'AAAAAAAAAAAAAABEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AG8T9NfSMEVMhQ' +
      'voP3fFiRZ+MTHDifa/95OFSZU5OzRzxkyejv8ciEfhSceSXGjS8eSdLnZc2HDm4M3BxcXw' +
      'H/9k='
    var img = document.createElement('img')
    img.onload = function () {
      // Check if the browser supports automatic image orientation:
      $.orientation = img.width === 2 && img.height === 3
      if ($.orientation) {
        var canvas = document.createElement('canvas')
        canvas.width = canvas.height = 1
        var ctx = canvas.getContext('2d')
        ctx.drawImage(img, 1, 1, 1, 1, 0, 0, 1, 1)
        // Check if the source image coordinates (sX, sY, sWidth, sHeight) are
        // correctly applied to the auto-orientated image, which should result
        // in a white opaque pixel (e.g. in Safari).
        // Browsers that show a transparent pixel (e.g. Chromium) fail to crop
        // auto-oriented images correctly and require a workaround, e.g.
        // drawing the complete source image to an intermediate canvas first.
        // See https://bugs.chromium.org/p/chromium/issues/detail?id=1074354
        $.orientationCropBug =
          ctx.getImageData(0, 0, 1, 1).data.toString() !== '255,255,255,255'
      }
      if (cb) cb($, img, canvas)
    }
    img.src = testImageURL
  }

Relevant fix code source
https://github.com/blueimp/JavaScript-Load-Image/issues/101


seasonley
607 声望693 粉丝

一切皆数据