做微信wap页项目的时候,遇到小米6拍照上传图片旋转的问题,后来查找资料得到
Orientation,进行判断并运用canvas把图片旋转后再上传解决了问题
exif.js读取图像的元数据https://www.cnblogs.com/niuboren/archive/2016/09/19/5883796.html
<script> EXIF.getData(file, function() { Orientation = EXIF.getTag(this, 'Orientation'); }); var img_url = URL.createObjectURL(file); imgwh = new Image(); imgwh.src = img_url; imgwh.onload = function () { var imgWidth = this.width, imgHeight = this.height; var canvas = document.createElement("canvas"), ctx = canvas.getContext('2d'); canvas.width = imgWidth; canvas.height = imgHeight; if(Orientation && Orientation != 1){ //小米6竖着拍摄旋转问题 switch(Orientation){ case 6: // 旋转90度 canvas.width = imgHeight; canvas.height = imgWidth; ctx.rotate(Math.PI / 2); ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, imgWidth, imgHeight); ctx.drawImage(this, 0, -imgHeight); break; case 3: // 旋转180度 ctx.rotate(Math.PI); ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, imgWidth, imgHeight); ctx.drawImage(this, -imgWidth, -imgHeight); break; case 8: // 旋转-90度 canvas.width = imgHeight; canvas.height = imgWidth; ctx.rotate(3 * Math.PI / 2); ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, imgWidth, imgHeight); ctx.drawImage(this, -imgWidth, 0, imgWidth, imgHeight); break; } } } </script>
exif.js
var EXIF = {}; var TiffTags = EXIF.TiffTags = { 0x0112: "Orientation" }; function imageHasData(img) { return !!(img.exifdata); } function getImageData(img, callback) { function handleBinaryFile(binFile) { var data = findEXIFinJPEG(binFile); img.exifdata = data || {}; if (callback) { callback.call(img); } } if (window.FileReader && (img instanceof window.Blob || img instanceof window.File)) { var fileReader = new FileReader(); fileReader.onload = function (e) { handleBinaryFile(e.target.result); }; fileReader.readAsArrayBuffer(img); } } function findEXIFinJPEG(file) { var dataView = new DataView(file); if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) { return false; // not a valid jpeg } var offset = 2, length = file.byteLength, marker; while (offset < length) { if (dataView.getUint8(offset) != 0xFF) { return false; // not a valid marker, something is wrong } marker = dataView.getUint8(offset + 1); if (marker == 225) { return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2); } else { offset += 2 + dataView.getUint16(offset + 2); } } } function readTags(file, tiffStart, dirStart, strings, bigEnd) { var entries = file.getUint16(dirStart, !bigEnd), tags = {}, entryOffset, tag, i; for (i = 0; i < entries; i++) { entryOffset = dirStart + i * 12 + 2; tag = strings[file.getUint16(entryOffset, !bigEnd)]; tags[tag] = readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd); } return tags; } function readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd) { var type = file.getUint16(entryOffset + 2, !bigEnd), numValues = file.getUint32(entryOffset + 4, !bigEnd), valueOffset = file.getUint32(entryOffset + 8, !bigEnd) + tiffStart, offset, vals, val, n, numerator, denominator; switch (type) { case 1: // byte, 8-bit unsigned int case 7: // undefined, 8-bit byte, value depending on field if (numValues == 1) { return file.getUint8(entryOffset + 8, !bigEnd); } else { offset = numValues > 4 ? valueOffset : (entryOffset + 8); vals = []; for (n = 0; n < numValues; n++) { vals[n] = file.getUint8(offset + n); } return vals; } case 2: // ascii, 8-bit byte offset = numValues > 4 ? valueOffset : (entryOffset + 8); return getStringFromDB(file, offset, numValues - 1); case 3: // short, 16 bit int if (numValues == 1) { return file.getUint16(entryOffset + 8, !bigEnd); } else { offset = numValues > 2 ? valueOffset : (entryOffset + 8); vals = []; for (n = 0; n < numValues; n++) { vals[n] = file.getUint16(offset + 2 * n, !bigEnd); } return vals; } case 4: // long, 32 bit int if (numValues == 1) { return file.getUint32(entryOffset + 8, !bigEnd); } else { vals = []; for (n = 0; n < numValues; n++) { vals[n] = file.getUint32(valueOffset + 4 * n, !bigEnd); } return vals; } case 5: // rational = two long values, first is numerator, second is denominator if (numValues == 1) { numerator = file.getUint32(valueOffset, !bigEnd); denominator = file.getUint32(valueOffset + 4, !bigEnd); val = new Number(numerator / denominator); val.numerator = numerator; val.denominator = denominator; return val; } else { vals = []; for (n = 0; n < numValues; n++) { numerator = file.getUint32(valueOffset + 8 * n, !bigEnd); denominator = file.getUint32(valueOffset + 4 + 8 * n, !bigEnd); vals[n] = new Number(numerator / denominator); vals[n].numerator = numerator; vals[n].denominator = denominator; } return vals; } case 9: // slong, 32 bit signed int if (numValues == 1) { return file.getInt32(entryOffset + 8, !bigEnd); } else { vals = []; for (n = 0; n < numValues; n++) { vals[n] = file.getInt32(valueOffset + 4 * n, !bigEnd); } return vals; } case 10: // signed rational, two slongs, first is numerator, second is denominator if (numValues == 1) { return file.getInt32(valueOffset, !bigEnd) / file.getInt32(valueOffset + 4, !bigEnd); } else { vals = []; for (n = 0; n < numValues; n++) { vals[n] = file.getInt32(valueOffset + 8 * n, !bigEnd) / file.getInt32(valueOffset + 4 + 8 * n, !bigEnd); } return vals; } } } function getStringFromDB(buffer, start, length) { var outstr = ""; for (n = start; n < start + length; n++) { outstr += String.fromCharCode(buffer.getUint8(n)); } return outstr; } function readEXIFData(file, start) { if (getStringFromDB(file, start, 4) != "Exif") { return false; } var bigEnd, tags, tag, exifData, gpsData, tiffOffset = start + 6; // test for TIFF validity and endianness if (file.getUint16(tiffOffset) == 0x4949) { bigEnd = false; } else if (file.getUint16(tiffOffset) == 0x4D4D) { bigEnd = true; } else { return false; } if (file.getUint16(tiffOffset + 2, !bigEnd) != 0x002A) { return false; } var firstIFDOffset = file.getUint32(tiffOffset + 4, !bigEnd); if (firstIFDOffset < 0x00000008) { return false; } tags = readTags(file, tiffOffset, tiffOffset + firstIFDOffset, TiffTags, bigEnd); return tags; } EXIF.getData = function (img, callback) { if ((img instanceof Image || img instanceof HTMLImageElement) && !img.complete) return false; if (!imageHasData(img)) { getImageData(img, callback); } else { if (callback) { callback.call(img); } } return true; } EXIF.getTag = function (img, tag) { if (!imageHasData(img)) return; return img.exifdata[tag]; }