业务背景,苹果手机调用上传接口拍照没有问题但是上传到网页上照片倒转了解决方法利用exif.js读取图片参数并对图片进行元数据修改

  1. window.btoa(str)转码
  1. window.atob(base64)解码
    EXIF.JS API
    1EXIF.getData(img, callback)获取图像的数据,能兼容尚未支持提供 EXIF 数据的浏览器获取到元数据。
  1. 2EXIF.getTag(img, tag)
    获取图像的某个数据
    获取旋转角度
    EXIF.getTag(this,'Orientation')
    orientstion属性说明
    参数1683分别对应旋转角度0deg,顺时针90deg,逆时针90deg180deg
  1.  
  2. 3EXIF.getAllTags(img)
    获取图像的全部数据,值以对象的方式返回
  3.  
  4. 4EXIF.pretty(img)
    获取图像的全部数据,值以字符串的方式返回
  5.  
  6. 上代码html代码如下
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  6. <title>图片上传</title>
  7. <script type="text/javascript" src="js/jquery.min.js"></script>
  8. <script type="text/javascript" src="js/uploadImage.js" ></script>
  9. <script type="text/javascript" src="js/exif.min.js" ></script>
  10. <script>
  11.  
  12. </script>
  13. </head>
  14. <body>
  15. <div style="height: 50px; line-height: 50px;text-align: center;border-bottom: 1px solid #171E28;">
  16. 上传图片:
  17. <input type="file" accept="image/*" id="uploadImage" capture="camera" onchange="selectFileImage(this);" />
  18. </div>
  19. <canvas id="canvas">你的浏览器不支持canvas</canvas>
  20. <div style="margin-top: 10px;">
  21. <img alt="preview" src="" id="myImage"/>
  22. </div>
  23. </body>
  24. </html>

js代码uploadImagejs如下

  1. function selectFileImage(fileObj) {
  2. //当文件改变的时候,调用该函数
  3. var file = fileObj.files['0'];
  4.  
  5. console.log(file);
  6. //图片方向角 added by lzk
  7. var Orientation = null;
  8.  
  9. if (file) {
  10. console.log("正在上传,请稍后...");
  11. var rFilter = /^(image\/jpeg|image\/png)$/i; // 检查图片格式
  12. if (!rFilter.test(file.type)) {
  13. //showMyTips("请选择jpeg、png格式的图片", false);
  14. return;
  15. }
  16. // var URL = URL || webkitURL;
  17. //获取照片方向角属性,用户旋转控制
  18. EXIF.getData(file, function() {
  19. // alert(EXIF.pretty(this));
  20. EXIF.getAllTags(this);
  21. console.log(EXIF.getAllTags(this))
  22. //alert(EXIF.getTag(this, 'Orientation'));
  23. Orientation = EXIF.getTag(this, 'Orientation');
  24. console.log(Orientation)
  25. //return;
  26. });
  27.  
  28. var oReader = new FileReader();
  29.  
  30. oReader.onload = function(e) {
  31.  
  32. //var blob = URL.createObjectURL(file);
  33. //_compress(blob, file, basePath);
  34. var image = new Image();
  35. // base64码
  36. image.src = e.target.result;
  37.  
  38. image.onload = function() {
  39. // 读取文件自己的宽高
  40. var expectWidth = this.naturalWidth;
  41. var expectHeight = this.naturalHeight;
  42.  
  43. // 判断图片宽大于高,并且宽大于800的话让图片宽度为800,相应等比改变图片高度
  44. if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) {
  45. expectWidth = 800;
  46. expectHeight = expectWidth * this.naturalHeight / this.naturalWidth;
  47.  
  48. } else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) {
  49. // 判断图片高大于宽,并且高大于1200的话让图片高度为1200,相应等比改变图片高度
  50. expectHeight = 1200;
  51. expectWidth = expectHeight * this.naturalWidth / this.naturalHeight;
  52. }
  53. // 获取画布设置画布宽高,把图片放入发布,画布大小为图片大小并从0,0点开始绘制
  54. var canvas = document.getElementById("canvas");
  55. var ctx = canvas.getContext("2d");
  56. canvas.width = expectWidth;
  57. canvas.height = expectHeight;
  58. ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
  59. var base64 = null;
  60. //修复ios ,判断用户是否为iphone
  61. if (navigator.userAgent.match(/iphone/i)) {
  62. console.log('iphone');
  63. //alert(expectWidth + ',' + expectHeight);
  64. //如果方向角不为1,都需要进行旋转 added by lzk
  65. if(Orientation != "" && Orientation != 1){
  66. alert('旋转处理');
  67. switch(Orientation){
  68. case 6://需要顺时针(向左)90度旋转
  69. alert('需要顺时针(向左)90度旋转');
  70. rotateImg(this,'left',canvas);
  71. break;
  72. case 8://需要逆时针(向右)90度旋转
  73. alert('需要顺时针(向右)90度旋转');
  74. rotateImg(this,'right',canvas);
  75. break;
  76. case 3://需要180度旋转
  77. alert('需要180度旋转');
  78. rotateImg(this,'right',canvas);//转两次
  79. rotateImg(this,'right',canvas);
  80. break;
  81. }
  82. }
  83.  
  84. /*var mpImg = new MegaPixImage(image);
  85. mpImg.render(canvas, {
  86. maxWidth: 800,
  87. maxHeight: 1200,
  88. quality: 0.8,
  89. orientation: 8
  90. });*/
  91. base64 = canvas.toDataURL("image/jpeg", 0.8);
  92. }else if (navigator.userAgent.match(/Android/i)) {// 修复android
  93. var encoder = new JPEGEncoder();
  94. base64 = encoder.encode(ctx.getImageData(0, 0, expectWidth, expectHeight), 80);
  95. }else{
  96. //alert(Orientation);
  97. if(Orientation != "" && Orientation != 1){
  98. //alert('旋转处理');
  99.  
  100. switch(Orientation){
  101. case 6://需要顺时针(向左)90度旋转
  102. alert('需要顺时针(向左)90度旋转');
  103. rotateImg(this,'left',canvas);
  104. break;
  105. case 8://需要逆时针(向右)90度旋转
  106. alert('需要顺时针(向右)90度旋转');
  107. rotateImg(this,'right',canvas);
  108. break;
  109. case 3://需要180度旋转
  110. alert('需要180度旋转');
  111. rotateImg(this,'right',canvas);//转两次
  112. rotateImg(this,'right',canvas);
  113. break;
  114. }
  115. }
  116. // 如果需要旋转,旋转后 canvas.todataurl转成base64码
  117. base64 = canvas.toDataURL("image/jpeg", 0.8); //toDataURL(图片类型,图片质量0-1)
  118. }
  119. //uploadImage(base64); ,myimage
  120. $("#myImage").attr("src", base64);
  121. };
  122. };
  123. oReader.readAsDataURL(file);
  124. }
  125. }
  126.  
  127. //对图片旋转处理 added by lzk
  128. function rotateImg(img, direction,canvas) {
  129. //alert(img);
  130. //最小与最大旋转方向,图片旋转4次后回到原方向
  131. var min_step = 0;
  132. var max_step = 3;
  133. //var img = document.getElementById(pid);
  134. if (img == null)return;
  135. //img的高度和宽度不能在img元素隐藏后获取,否则会出错
  136. var height = img.height;
  137. var width = img.width;
  138. //var step = img.getAttribute('step');
  139. var step = 2;
  140. if (step == null) {
  141. step = min_step;
  142. }
  143. if (direction == 'right') {
  144. step++;
  145. //旋转到原位置,即超过最大值
  146. step > max_step && (step = min_step);
  147. } else {
  148. step--;
  149. step < min_step && (step = max_step);
  150. }
  151. //img.setAttribute('step', step);
  152. /*var canvas = document.getElementById('pic_' + pid);
  153. if (canvas == null) {
  154. img.style.display = 'none';
  155. canvas = document.createElement('canvas');
  156. canvas.setAttribute('id', 'pic_' + pid);
  157. img.parentNode.appendChild(canvas);
  158. } */
  159. //旋转角度以弧度值为参数
  160. var degree = step * 90 * Math.PI / 180;
  161. var ctx = canvas.getContext('2d');
  162. switch (step) {
  163. case 0:
  164. canvas.width = width;
  165. canvas.height = height;
  166. ctx.drawImage(img, 0, 0);
  167. break;
  168. case 1:
  169. canvas.width = height;
  170. canvas.height = width;
  171. ctx.rotate(degree);
  172. ctx.drawImage(img, 0, -height);
  173. break;
  174. case 2:
  175. canvas.width = width;
  176. canvas.height = height;
  177. ctx.rotate(degree);
  178. ctx.drawImage(img, -width, -height);
  179. break;
  180. case 3:
  181. canvas.width = height;
  182. canvas.height = width;
  183. ctx.rotate(degree);
  184. ctx.drawImage(img, -width, 0);
  185. break;
  186. }
  187. }

  

  1. exif.min.js
  1. (function(){function e(e){return!!e.exifdata}function t(e,t){t=t||e.match(/^data\:([^\;]+)\;base64,/im)[1]||"",e=e.replace(/^data\:([^\;]+)\;base64,/gim,"");for(var n=atob(e),r=n.length,i=new ArrayBuffer(r),o=new Uint8Array(i),a=0;a<r;a++)o[a]=n.charCodeAt(a);return i}function r(e,t){var n=new XMLHttpRequest;n.open("GET",e,!0),n.responseType="blob",n.onload=function(e){200!=this.status&&0!==this.status||t(this.response)},n.send()}function i(e,n){function i(t){var r=o(t);e.exifdata=r||{};var i=a(t);if(e.iptcdata=i||{},F.isXmpEnabled){var s=m(t);e.xmpdata=s||{}}n&&n.call(e)}if(e.src)if(/^data\:/i.test(e.src))i(t(e.src));else if(/^blob\:/i.test(e.src))(l=new FileReader).onload=function(e){i(e.target.result)},r(e.src,function(e){l.readAsArrayBuffer(e)});else{var s=new XMLHttpRequest;s.onload=function(){if(200!=this.status&&0!==this.status)throw"Could not load image";i(s.response),s=null},s.open("GET",e.src,!0),s.responseType="arraybuffer",s.send(null)}else if(self.FileReader&&(e instanceof self.Blob||e instanceof self.File)){var l=new FileReader;l.onload=function(e){S&&console.log("Got file of length "+e.target.result.byteLength),i(e.target.result)},l.readAsArrayBuffer(e)}}function o(e){var t=new DataView(e);if(S&&console.log("Got file of length "+e.byteLength),255!=t.getUint8(0)||216!=t.getUint8(1))return S&&console.log("Not a valid JPEG"),!1;for(var n,r=2,i=e.byteLength;r<i;){if(255!=t.getUint8(r))return S&&console.log("Not a valid marker at offset "+r+", found: "+t.getUint8(r)),!1;if(n=t.getUint8(r+1),S&&console.log(n),225==n)return S&&console.log("Found 0xFFE1 marker"),g(t,r+4,t.getUint16(r+2));r+=2+t.getUint16(r+2)}}function a(e){var t=new DataView(e);if(S&&console.log("Got file of length "+e.byteLength),255!=t.getUint8(0)||216!=t.getUint8(1))return S&&console.log("Not a valid JPEG"),!1;for(var n=2,r=e.byteLength;n<r;){if(function(e,t){return ===e.getUint8(t)&&66===e.getUint8(t+1)&&73===e.getUint8(t+2)&&77===e.getUint8(t+3)&&4===e.getUint8(t+4)&&4===e.getUint8(t+5)}(t,n)){var i=t.getUint8(n+7);return i%2!=0&&(i+=1),0===i&&(i=4),s(e,n+8+i,t.getUint16(n+6+i))}n++}}function s(e,t,n){for(var r,i,o,a,s=new DataView(e),l={},u=t;u<t+n;)28===s.getUint8(u)&&2===s.getUint8(u+1)&&(a=s.getUint8(u+2))in v&&((o=s.getInt16(u+3))+5,i=v[a],r=f(s,u+5,o),l.hasOwnProperty(i)?l[i]instanceof Array?l[i].push(r):l[i]=[l[i],r]:l[i]=r),u++;return l}function l(e,t,n,r,i){var o,a,s,l=e.getUint16(n,!i),c={};for(s=0;s<l;s++)o=n+12*s+2,!(a=r[e.getUint16(o,!i)])&&S&&console.log("Unknown tag: "+e.getUint16(o,!i)),c[a]=u(e,o,t,n,i);return c}function u(e,t,n,r,i){var o,a,s,l,u,c,d=e.getUint16(t+2,!i),g=e.getUint32(t+4,!i),m=e.getUint32(t+8,!i)+n;switch(d){case 1:case 7:if(1==g)return e.getUint8(t+8,!i);for(o=g>4?m:t+8,a=[],l=0;l<g;l++)a[l]=e.getUint8(o+l);return a;case 2:return o=g>4?m:t+8,f(e,o,g-1);case 3:if(1==g)return e.getUint16(t+8,!i);for(o=g>2?m:t+8,a=[],l=0;l<g;l++)a[l]=e.getUint16(o+2*l,!i);return a;case 4:if(1==g)return e.getUint32(t+8,!i);for(a=[],l=0;l<g;l++)a[l]=e.getUint32(m+4*l,!i);return a;case 5:if(1==g)return u=e.getUint32(m,!i),c=e.getUint32(m+4,!i),s=new Number(u/c),s.numerator=u,s.denominator=c,s;for(a=[],l=0;l<g;l++)u=e.getUint32(m+8*l,!i),c=e.getUint32(m+4+8*l,!i),a[l]=new Number(u/c),a[l].numerator=u,a[l].denominator=c;return a;case 9:if(1==g)return e.getInt32(t+8,!i);for(a=[],l=0;l<g;l++)a[l]=e.getInt32(m+4*l,!i);return a;case 10:if(1==g)return e.getInt32(m,!i)/e.getInt32(m+4,!i);for(a=[],l=0;l<g;l++)a[l]=e.getInt32(m+8*l,!i)/e.getInt32(m+4+8*l,!i);return a}}function c(e,t,n){var r=e.getUint16(t,!n);return e.getUint32(t+2+12*r,!n)}function d(e,t,n,r){var i=c(e,t+n,r);if(!i)return{};if(i>e.byteLength)return{};var o=l(e,t,t+i,C,r);if(o.Compression)switch(o.Compression){case 6:if(o.JpegIFOffset&&o.JpegIFByteCount){var a=t+o.JpegIFOffset,s=o.JpegIFByteCount;o.blob=new Blob([new Uint8Array(e.buffer,a,s)],{type:"image/jpeg"})}break;case 1:console.log("Thumbnail image format is TIFF, which is not implemented.");break;default:console.log("Unknown thumbnail image format '%s'",o.Compression)}else 2==o.PhotometricInterpretation&&console.log("Thumbnail image format is RGB, which is not implemented.");return o}function f(e,t,r){var i="";for(n=t;n<t+r;n++)i+=String.fromCharCode(e.getUint8(n));return i}function g(e,t){if("Exif"!=f(e,t,4))return S&&console.log("Not valid EXIF data! "+f(e,t,4)),!1;var n,r,i,o,a,s=t+6;if(18761==e.getUint16(s))n=!1;else{if(19789!=e.getUint16(s))return S&&console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)"),!1;n=!0}if(42!=e.getUint16(s+2,!n))return S&&console.log("Not valid TIFF data! (no 0x002A)"),!1;var u=e.getUint32(s+4,!n);if(u<8)return S&&console.log("Not valid TIFF data! (First offset less than 8)",e.getUint32(s+4,!n)),!1;if((r=l(e,s,s+u,b,n)).ExifIFDPointer){o=l(e,s,s+r.ExifIFDPointer,y,n);for(i in o){switch(i){case"LightSource":case"Flash":case"MeteringMode":case"ExposureProgram":case"SensingMethod":case"SceneCaptureType":case"SceneType":case"CustomRendered":case"WhiteBalance":case"GainControl":case"Contrast":case"Saturation":case"Sharpness":case"SubjectDistanceRange":case"FileSource":o[i]=I[i][o[i]];break;case"ExifVersion":case"FlashpixVersion":o[i]=String.fromCharCode(o[i][0],o[i][1],o[i][2],o[i][3]);break;case"ComponentsConfiguration":o[i]=I.Components[o[i][0]]+I.Components[o[i][1]]+I.Components[o[i][2]]+I.Components[o[i][3]]}r[i]=o[i]}}if(r.GPSInfoIFDPointer){a=l(e,s,s+r.GPSInfoIFDPointer,x,n);for(i in a){switch(i){case"GPSVersionID":a[i]=a[i][0]+"."+a[i][1]+"."+a[i][2]+"."+a[i][3]}r[i]=a[i]}}return r.thumbnail=d(e,s,u,n),r}function m(e){if("DOMParser"in self){var t=new DataView(e);if(S&&console.log("Got file of length "+e.byteLength),255!=t.getUint8(0)||216!=t.getUint8(1))return S&&console.log("Not a valid JPEG"),!1;for(var n=2,r=e.byteLength,i=new DOMParser;n<r-4;){if("http"==f(t,n,4)){var o=f(t,n-1,t.getUint16(n-2)-1),a=o.indexOf("xmpmeta>")+8,s=(o=o.substring(o.indexOf("<x:xmpmeta"),a)).indexOf("x:xmpmeta")+10;return o=o.slice(0,s)+'xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tiff="http://ns.adobe.com/tiff/1.0/" xmlns:plus="http://schemas.android.com/apk/lib/com.google.android.gms.plus" xmlns:ext="http://www.gettyimages.com/xsltExtension/1.0" xmlns:exif="http://ns.adobe.com/exif/1.0/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:crs="http://ns.adobe.com/camera-raw-settings/1.0/" xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/" xmlns:Iptc4xmpExt="http://iptc.org/std/Iptc4xmpExt/2008-02-29/" '+o.slice(s),h(i.parseFromString(o,"text/xml"))}n++}}}function p(e){var t={};if(1==e.nodeType){if(e.attributes.length>0){t["@attributes"]={};for(var n=0;n<e.attributes.length;n++){var r=e.attributes.item(n);t["@attributes"][r.nodeName]=r.nodeValue}}}else if(3==e.nodeType)return e.nodeValue;if(e.hasChildNodes())for(var i=0;i<e.childNodes.length;i++){var o=e.childNodes.item(i),a=o.nodeName;if(null==t[a])t[a]=p(o);else{if(null==t[a].push){var s=t[a];t[a]=[],t[a].push(s)}t[a].push(p(o))}}return t}function h(e){try{var t={};if(e.children.length>0)for(var n=0;n<e.children.length;n++){var r=e.children.item(n),i=r.attributes;for(var o in i){var a=i[o],s=a.nodeName,l=a.nodeValue;void 0!==s&&(t[s]=l)}var u=r.nodeName;if(void ===t[u])t[u]=p(r);else{if(void ===t[u].push){var c=t[u];t[u]=[],t[u].push(c)}t[u].push(p(r))}}else t=e.textContent;return t}catch(e){console.log(e.message)}}var S=!1,P=this,F=function(e){return e instanceof F?e:this instanceof F?void(this.EXIFwrapped=e):new F(e)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=F),exports.EXIF=F):P.EXIF=F;var y=F.Tags={36864:"ExifVersion",40960:"FlashpixVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",37121:"ComponentsConfiguration",37122:"CompressedBitsPerPixel",37500:"MakerNote",37510:"UserComment",40964:"RelatedSoundFile",36867:"DateTimeOriginal",36868:"DateTimeDigitized",37520:"SubsecTime",37521:"SubsecTimeOriginal",37522:"SubsecTimeDigitized",33434:"ExposureTime",33437:"FNumber",34850:"ExposureProgram",34852:"SpectralSensitivity",34855:"ISOSpeedRatings",34856:"OECF",37377:"ShutterSpeedValue",37378:"ApertureValue",37379:"BrightnessValue",37380:"ExposureBias",37381:"MaxApertureValue",37382:"SubjectDistance",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37396:"SubjectArea",37386:"FocalLength",41483:"FlashEnergy",41484:"SpatialFrequencyResponse",41486:"FocalPlaneXResolution",41487:"FocalPlaneYResolution",41488:"FocalPlaneResolutionUnit",41492:"SubjectLocation",41493:"ExposureIndex",41495:"SensingMethod",41728:"FileSource",41729:"SceneType",41730:"CFAPattern",41985:"CustomRendered",41986:"ExposureMode",41987:"WhiteBalance",41988:"DigitalZoomRation",41989:"FocalLengthIn35mmFilm",41990:"SceneCaptureType",41991:"GainControl",41992:"Contrast",41993:"Saturation",41994:"Sharpness",41995:"DeviceSettingDescription",41996:"SubjectDistanceRange",40965:"InteroperabilityIFDPointer",42016:"ImageUniqueID"},b=F.TiffTags={256:"ImageWidth",257:"ImageHeight",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer",40965:"InteroperabilityIFDPointer",258:"BitsPerSample",259:"Compression",262:"PhotometricInterpretation",274:"Orientation",277:"SamplesPerPixel",284:"PlanarConfiguration",530:"YCbCrSubSampling",531:"YCbCrPositioning",282:"XResolution",283:"YResolution",296:"ResolutionUnit",273:"StripOffsets",278:"RowsPerStrip",279:"StripByteCounts",513:"JPEGInterchangeFormat",514:"JPEGInterchangeFormatLength",301:"TransferFunction",318:"WhitePoint",319:"PrimaryChromaticities",529:"YCbCrCoefficients",532:"ReferenceBlackWhite",306:"DateTime",270:"ImageDescription",271:"Make",272:"Model",305:"Software",315:"Artist",33432:"Copyright"},x=F.GPSTags={0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude",5:"GPSAltitudeRef",6:"GPSAltitude",7:"GPSTimeStamp",8:"GPSSatellites",9:"GPSStatus",10:"GPSMeasureMode",11:"GPSDOP",12:"GPSSpeedRef",13:"GPSSpeed",14:"GPSTrackRef",15:"GPSTrack",16:"GPSImgDirectionRef",17:"GPSImgDirection",18:"GPSMapDatum",19:"GPSDestLatitudeRef",20:"GPSDestLatitude",21:"GPSDestLongitudeRef",22:"GPSDestLongitude",23:"GPSDestBearingRef",24:"GPSDestBearing",25:"GPSDestDistanceRef",26:"GPSDestDistance",27:"GPSProcessingMethod",28:"GPSAreaInformation",29:"GPSDateStamp",30:"GPSDifferential"},C=F.IFD1Tags={256:"ImageWidth",257:"ImageHeight",258:"BitsPerSample",259:"Compression",262:"PhotometricInterpretation",273:"StripOffsets",274:"Orientation",277:"SamplesPerPixel",278:"RowsPerStrip",279:"StripByteCounts",282:"XResolution",283:"YResolution",284:"PlanarConfiguration",296:"ResolutionUnit",513:"JpegIFOffset",514:"JpegIFByteCount",529:"YCbCrCoefficients",530:"YCbCrSubSampling",531:"YCbCrPositioning",532:"ReferenceBlackWhite"},I=F.StringValues={ExposureProgram:{0:"Not defined",1:"Manual",2:"Normal program",3:"Aperture priority",4:"Shutter priority",5:"Creative program",6:"Action program",7:"Portrait mode",8:"Landscape mode"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{0:"Unknown",1:"Daylight",2:"Fluorescent",3:"Tungsten (incandescent light)",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 - 5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire",1:"Flash fired",5:"Strobe return light not detected",7:"Strobe return light detected",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},SensingMethod:{1:"Not defined",2:"One-chip color area sensor",3:"Two-chip color area sensor",4:"Three-chip color area sensor",5:"Color sequential area sensor",7:"Trilinear sensor",8:"Color sequential linear sensor"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},SceneType:{1:"Directly photographed"},CustomRendered:{0:"Normal process",1:"Custom process"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},GainControl:{0:"None",1:"Low gain up",2:"High gain up",3:"Low gain down",4:"High gain down"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},SubjectDistanceRange:{0:"Unknown",1:"Macro",2:"Close view",3:"Distant view"},FileSource:{3:"DSC"},Components:{0:"",1:"Y",2:"Cb",3:"Cr",4:"R",5:"G",6:"B"}},v={120:"caption",110:"credit",25:"keywords",55:"dateCreated",80:"byline",85:"bylineTitle",122:"captionWriter",105:"headline",116:"copyright",15:"category"};F.enableXmp=function(){F.isXmpEnabled=!0},F.disableXmp=function(){F.isXmpEnabled=!1},F.getData=function(t,n){return!((self.Image&&t instanceof self.Image||self.HTMLImageElement&&t instanceof self.HTMLImageElement)&&!t.complete)&&(e(t)?n&&n.call(t):i(t,n),!0)},F.getTag=function(t,n){if(e(t))return t.exifdata[n]},F.getIptcTag=function(t,n){if(e(t))return t.iptcdata[n]},F.getAllTags=function(t){if(!e(t))return{};var n,r=t.exifdata,i={};for(n in r)r.hasOwnProperty(n)&&(i[n]=r[n]);return i},F.getAllIptcTags=function(t){if(!e(t))return{};var n,r=t.iptcdata,i={};for(n in r)r.hasOwnProperty(n)&&(i[n]=r[n]);return i},F.pretty=function(t){if(!e(t))return"";var n,r=t.exifdata,i="";for(n in r)r.hasOwnProperty(n)&&("object"==typeof r[n]?r[n]instanceof Number?i+=n+" : "+r[n]+" ["+r[n].numerator+"/"+r[n].denominator+"]\r\n":i+=n+" : ["+r[n].length+" values]\r\n":i+=n+" : "+r[n]+"\r\n");return i},F.readFromBinaryFile=function(e){return o(e)},"function"==typeof define&&define.amd&&define("exif-js",[],function(){return F})}).call(this);

exif.min.js下载地址

  1. https://www.bootcdn.cn/exif-js/

  

  1.  

详解exif.js,应用于canvas照片倒转(海报H5)的更多相关文章

  1. HTML滚动字幕代码参数详解及Js间隔滚动代码

    html文字滚动代码 <marquee style="WIDTH: 388px; HEIGHT: 200px" scrollamount="2" dire ...

  2. 详解Vue.js 技术

    本文主要从8个章节详解vue技术揭秘,小编觉得挺有用的,分享给大家. 为了把 Vue.js 的源码讲明白,课程设计成由浅入深,分为核心.编译.扩展.生态四个方面去讲,并拆成了八个章节,如下: 准备工作 ...

  3. Day04 dom详解及js事件

    day04 dom详解 DOM的基础 Document对象 Element对象 Node对象 innerHTML 事件处理 表单验证   上次课内容回顾: JS中ECMAScript用法: JS定义变 ...

  4. JQ的offset().top与JS的getBoundingClientRect区别详解,JS获取元素距离视窗顶部可变距离

     壹 ❀ 引 我在 JQ的offset().top与js的offsetTop区别详解 这篇博客中详细分析了JQ方法offset().top与JS属性offsetTop的区别,并得出了一条offset( ...

  5. javascript数组详解(js数组深度解析)【forEach(),every(),map(),filter(),reduce()】

    Array 对象是一个复合类型,用于在单个的变量中存储多个值,每个值类型可以不同. 创建数组对象的方法: new Array(); new Array(size); new Array(element ...

  6. JavaScript语法详解:JS简介&变量

    本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. JavaScript简介 Web前端有三层: HTML:从语义的角度,描 ...

  7. 详解tween.js 中文使用指南

    补间(动画)是一个概念,允许你以平滑的方式更改对象的属性.你只需告诉它哪些属性要更改,当补间结束运行时它们应该具有哪些最终值,以及这需要多长时间,补间引擎将负责计算从起始点到结束点的值. 例如,pos ...

  8. es6常用功能与异步详解(JS高级面试题)

    callback hell方法的使用 可读性不友好 function loadImg(src,callback,fail){ var img = document.createElement('img ...

  9. 区别和详解:js中call()和apply()的用法

    1.关于call()和apply()的疑点: apply和call的区别在哪里 什么情况下用apply,什么情况下用call apply的其他巧妙用法(一般在什么情况下可以使用apply) 2.语法和 ...

随机推荐

  1. Kubernetes (1.6) 中的存储类及其动态供给

    原文地址:http://blog.fleeto.us/translation/dynamic-provisioning-and-storage-classes-kubernetes-0?utm_sou ...

  2. C# 时间戳的生成

    /**        * 生成时间戳,标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数         * @return 时间戳        */        publi ...

  3. (转)通过扩展让ASP.NET Web API支持JSONP

    原文地址:http://www.cnblogs.com/artech/p/3460544.html 同源策略(Same Origin Policy)的存在导致了“源”自A的脚本只能操作“同源”页面的D ...

  4. 获取host信息

    QT如果要进行网络编程首先需要在.pro”中添加如下代码: QT += network 在头文件中包含相关头文件: #include <QHostInfo> #include <QN ...

  5. Android性能分析Systrace工具

    一.概述 保证系统流畅度,也就是保证系统能连续不间断地提供每秒60帧的运行状态.当出现掉帧时(也可称为Jank),需要知道当前整个系统所处的状态,systrace便是最佳的选择,它能手机检测Andro ...

  6. Subsequence——POJ3061

    题目:http://poj.org/problem?id=3061 尺取法解题 import java.util.Scanner;; public class Main { public static ...

  7. Gulp资料大全:入门、插件、脚手架、包清单

    awesome-gulp中文版 一份gulp的资源,插件和使用实例清单, 致力于打造更好的前端工程构建流程. 被老外的awesome 清单刺激到,觉得有必要翻译一份,为国产的程序员们做点事情,本清单将 ...

  8. dede上传文件乱码问题解决

    修改下列两个文件: /include/dialog/select_soft_post.php/include/dialog/select_soft.php 改: select_soft.php文件第1 ...

  9. java-02 JDK安装与环境变量配置&安装编程IDE

    1.JDK下载安装与环境变量的配置 1.1 官方JDK 下载地址 大家可以到Oracle中国官方网站下载JDK,也可已 通过这个链接下载 (推荐大家下载1.8版本,这个版本是当前比较流行的版本) 也可 ...

  10. Django_Restframwork_APIVIEW视图_源码分析

    Django _VIEW视图_源码分析