166 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			166 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const Exif = {};
 | 
						||
 | 
						||
Exif.getData = (img) => new Promise((reslove, reject) => {
 | 
						||
  let obj = {};
 | 
						||
  getImageData(img).then(data => {
 | 
						||
    obj.arrayBuffer = data;
 | 
						||
    try {
 | 
						||
      obj.orientation = getOrientation(data);
 | 
						||
    } catch {
 | 
						||
      obj.orientation = -1;
 | 
						||
    }
 | 
						||
    reslove(obj)
 | 
						||
  }).catch(error => {
 | 
						||
    reject(error)
 | 
						||
  })
 | 
						||
})
 | 
						||
 | 
						||
// 这里的获取exif要将图片转ArrayBuffer对象,这里假设获取了图片的baes64
 | 
						||
// 步骤一
 | 
						||
// base64转ArrayBuffer对象
 | 
						||
function getImageData(img) {
 | 
						||
  let data = null;
 | 
						||
  return new Promise((reslove, reject) => {
 | 
						||
    if (img.src) {
 | 
						||
      if (/^data\:/i.test(img.src)) { // Data URI
 | 
						||
        data = base64ToArrayBuffer(img.src);
 | 
						||
        reslove(data)
 | 
						||
      } else if (/^blob\:/i.test(img.src)) { // Object URL
 | 
						||
        var fileReader = new FileReader();
 | 
						||
        fileReader.onload = function (e) {
 | 
						||
          data = e.target.result;
 | 
						||
          reslove(data)
 | 
						||
        };
 | 
						||
        objectURLToBlob(img.src, function (blob) {
 | 
						||
          fileReader.readAsArrayBuffer(blob);
 | 
						||
        });
 | 
						||
      } else {
 | 
						||
        var http = new XMLHttpRequest();
 | 
						||
        http.onload = function () {
 | 
						||
          if (this.status == 200 || this.status === 0) {
 | 
						||
            data = http.response
 | 
						||
            reslove(data)
 | 
						||
          } else {
 | 
						||
            throw "Could not load image";
 | 
						||
          }
 | 
						||
          http = null;
 | 
						||
        };
 | 
						||
        http.open("GET", img.src, true);
 | 
						||
        http.responseType = "arraybuffer";
 | 
						||
        http.send(null);
 | 
						||
      }
 | 
						||
    } else {
 | 
						||
      reject('img error')
 | 
						||
    }
 | 
						||
  })
 | 
						||
}
 | 
						||
 | 
						||
function objectURLToBlob(url, callback) {
 | 
						||
  var http = new XMLHttpRequest();
 | 
						||
  http.open("GET", url, true);
 | 
						||
  http.responseType = "blob";
 | 
						||
  http.onload = function (e) {
 | 
						||
    if (this.status == 200 || this.status === 0) {
 | 
						||
      callback(this.response);
 | 
						||
    }
 | 
						||
  };
 | 
						||
  http.send();
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
function base64ToArrayBuffer(base64, contentType) {
 | 
						||
  contentType = contentType || base64.match(/^data\:([^\;]+)\;base64,/mi)[1] || ''; // e.g. 'data:image/jpeg;base64,...' => 'image/jpeg'
 | 
						||
  base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, '');
 | 
						||
  var binary = atob(base64);
 | 
						||
  // byte length of Uint16Array should be a multiple of 2
 | 
						||
  var len = binary.length % 2 == 0 ? binary.length : binary.length + 1;
 | 
						||
  var buffer = new ArrayBuffer(len);
 | 
						||
  var view = new Uint16Array(buffer);
 | 
						||
  for (var i = 0; i < len; i++) {
 | 
						||
      view[i] = binary.charCodeAt(i);
 | 
						||
  }
 | 
						||
  return buffer;
 | 
						||
}
 | 
						||
 | 
						||
// 步骤二,Unicode码转字符串
 | 
						||
// ArrayBuffer对象 Unicode码转字符串
 | 
						||
function getStringFromCharCode(dataView, start, length) {
 | 
						||
  var str = '';
 | 
						||
  var i;
 | 
						||
  for (i = start, length += start; i < length; i++) {
 | 
						||
    str += String.fromCharCode(dataView.getUint8(i));
 | 
						||
  }
 | 
						||
  return str;
 | 
						||
}
 | 
						||
 | 
						||
// 步骤三,获取jpg图片的exif的角度(在ios体现最明显)
 | 
						||
function getOrientation(arrayBuffer) {
 | 
						||
  var dataView = new DataView(arrayBuffer);
 | 
						||
  var length = dataView.byteLength;
 | 
						||
  var orientation;
 | 
						||
  var exifIDCode;
 | 
						||
  var tiffOffset;
 | 
						||
  var firstIFDOffset;
 | 
						||
  var littleEndian;
 | 
						||
  var endianness;
 | 
						||
  var app1Start;
 | 
						||
  var ifdStart;
 | 
						||
  var offset;
 | 
						||
  var i;
 | 
						||
  // Only handle JPEG image (start by 0xFFD8)
 | 
						||
  if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
 | 
						||
    offset = 2;
 | 
						||
    while (offset < length) {
 | 
						||
      if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
 | 
						||
        app1Start = offset;
 | 
						||
        break;
 | 
						||
      }
 | 
						||
      offset++;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  if (app1Start) {
 | 
						||
    exifIDCode = app1Start + 4;
 | 
						||
    tiffOffset = app1Start + 10;
 | 
						||
    if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
 | 
						||
      endianness = dataView.getUint16(tiffOffset);
 | 
						||
      littleEndian = endianness === 0x4949;
 | 
						||
 | 
						||
      if (littleEndian || endianness === 0x4D4D /* bigEndian */) {
 | 
						||
        if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
 | 
						||
          firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
 | 
						||
 | 
						||
          if (firstIFDOffset >= 0x00000008) {
 | 
						||
            ifdStart = tiffOffset + firstIFDOffset;
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  if (ifdStart) {
 | 
						||
    length = dataView.getUint16(ifdStart, littleEndian);
 | 
						||
 | 
						||
    for (i = 0; i < length; i++) {
 | 
						||
      offset = ifdStart + i * 12 + 2;
 | 
						||
      if (dataView.getUint16(offset, littleEndian) === 0x0112 /* Orientation */) {
 | 
						||
 | 
						||
        // 8 is the offset of the current tag's value
 | 
						||
        offset += 8;
 | 
						||
 | 
						||
        // Get the original orientation value
 | 
						||
        orientation = dataView.getUint16(offset, littleEndian);
 | 
						||
 | 
						||
        // Override the orientation with its default value for Safari (#120)
 | 
						||
        // if (IS_SAFARI_OR_UIWEBVIEW) {
 | 
						||
        //   dataView.setUint16(offset, 1, littleEndian);
 | 
						||
        // }
 | 
						||
        break;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return orientation;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
export default Exif |