首页 > 编程 > JavaScript > 正文

Vue2.0实现调用摄像头进行拍照功能 exif.js实现图片上传功能

2019-11-19 13:56:37
字体:
来源:转载
供稿:网友

本文实例为大家分享了Vue2.0实现调用摄像头进行拍照功能的具体代码,以及图片上传功能引用exif.js,供大家参考,具体内容如下

可以在github 上下载demo链接

vue组件代码

<template> <div>  <div style="padding:20px;">   <div class="show">    <div class="picture" :style="'backgroundImage:url('+headerImage+')'"></div>   </div>   <div style="margin-top:20px;">    <input type="file" id="upload" accept="image/jpg" @change="upload">    <label for="upload"></label>   </div>  </div> </div></template><script>import {Exif} from './exif.js'export default { data () {  return {   headerImage:'',picValue:''  } }, mounted () { }, methods: {  upload (e) {   let files = e.target.files || e.dataTransfer.files;   if (!files.length) return;   this.picValue = files[0];   this.imgPreview(this.picValue);   console.log(this.picValue)  },  imgPreview (file) {   let self = this;   let Orientation;   //去获取拍照时的信息,解决拍出来的照片旋转问题    Exif.getData(file, function(){      Orientation = Exif.getTag(this, 'Orientation');    });   // 看支持不支持FileReader    if (!file || !window.FileReader) return;   if (/^image/.test(file.type)) {     // 创建一个reader     let reader = new FileReader();     // 将图片2将转成 base64 格式     reader.readAsDataURL(file);     // 读取成功后的回调     reader.onloadend = function () {      let result = this.result;      let img = new Image();      img.src = result;      //判断图片是否大于100K,是就直接上传,反之压缩图片      if (this.result.length <= (100 * 1024)) {       self.headerImage = this.result;       self.postImg();      }else {       img.onload = function () {        let data = self.compress(img,Orientation);        self.headerImage = data;        self.postImg();       }      }     }    }   },   postImg () {    //这里写接口   },   rotateImg (img, direction,canvas) {    //最小与最大旋转方向,图片旋转4次后回到原方向    const min_step = 0;    const max_step = 3;    if (img == null)return;    //img的高度和宽度不能在img元素隐藏后获取,否则会出错    let height = img.height;    let width = img.width;    let step = 2;    if (step == null) {      step = min_step;    }    if (direction == 'right') {      step++;      //旋转到原位置,即超过最大值      step > max_step && (step = min_step);    } else {      step--;      step < min_step && (step = max_step);    }    //旋转角度以弧度值为参数    let degree = step * 90 * Math.PI / 180;    let ctx = canvas.getContext('2d');    switch (step) {     case 0:       canvas.width = width;       canvas.height = height;       ctx.drawImage(img, 0, 0);       break;     case 1:       canvas.width = height;       canvas.height = width;       ctx.rotate(degree);       ctx.drawImage(img, 0, -height);       break;     case 2:       canvas.width = width;       canvas.height = height;       ctx.rotate(degree);       ctx.drawImage(img, -width, -height);       break;     case 3:       canvas.width = height;       canvas.height = width;       ctx.rotate(degree);       ctx.drawImage(img, -width, 0);       break;    }  },  compress(img,Orientation) {   let canvas = document.createElement("canvas");   let ctx = canvas.getContext('2d');    //瓦片canvas   let tCanvas = document.createElement("canvas");   let tctx = tCanvas.getContext("2d");   let initSize = img.src.length;   let width = img.width;   let height = img.height;   //如果图片大于四百万像素,计算压缩比并将大小压至400万以下   let ratio;   if ((ratio = width * height / 4000000) > 1) {    console.log("大于400万像素")    ratio = Math.sqrt(ratio);    width /= ratio;    height /= ratio;   } else {    ratio = 1;   }   canvas.width = width;   canvas.height = height; //    铺底色   ctx.fillStyle = "#fff";   ctx.fillRect(0, 0, canvas.width, canvas.height);   //如果图片像素大于100万则使用瓦片绘制   let count;   if ((count = width * height / 1000000) > 1) {    console.log("超过100W像素");    count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片 //      计算每块瓦片的宽和高    let nw = ~~(width / count);    let nh = ~~(height / count);    tCanvas.width = nw;    tCanvas.height = nh;    for (let i = 0; i < count; i++) {     for (let j = 0; j < count; j++) {      tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);      ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);     }    }   } else {    ctx.drawImage(img, 0, 0, width, height);   }   //修复ios上传图片的时候 被旋转的问题   if(Orientation != "" && Orientation != 1){    switch(Orientation){     case 6://需要顺时针(向左)90度旋转       this.rotateImg(img,'left',canvas);       break;     case 8://需要逆时针(向右)90度旋转       this.rotateImg(img,'right',canvas);       break;     case 3://需要180度旋转       this.rotateImg(img,'right',canvas);//转两次       this.rotateImg(img,'right',canvas);       break;    }   }   //进行最小压缩   let ndata = canvas.toDataURL('image/jpeg', 0.1);   console.log('压缩前:' + initSize);   console.log('压缩后:' + ndata.length);   console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%");   tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;   return ndata;  }, }}</script><style>*{ margin: 0; padding: 0;}.show { width: 100px; height: 100px; overflow: hidden; position: relative; border-radius: 50%; border: 1px solid #d5d5d5;}.picture { width: 100%; height: 100%; overflow: hidden; background-position: center center; background-repeat: no-repeat; background-size: cover;}</style>

引用的exif.js代码

(function() {  var debug = false;  var root = this;  var EXIF = function(obj) {    if (obj instanceof EXIF) return obj;    if (!(this instanceof EXIF)) return new EXIF(obj);    this.EXIFwrapped = obj;  };  if (typeof exports !== 'undefined') {    if (typeof module !== 'undefined' && module.exports) {      exports = module.exports = EXIF;    }    exports.EXIF = EXIF;  } else {    root.EXIF = EXIF;  }  var ExifTags = EXIF.Tags = {    // version tags    0x9000 : "ExifVersion",       // EXIF version    0xA000 : "FlashpixVersion",     // Flashpix format version    // colorspace tags    0xA001 : "ColorSpace",       // Color space information tag    // image configuration    0xA002 : "PixelXDimension",     // Valid width of meaningful image    0xA003 : "PixelYDimension",     // Valid height of meaningful image    0x9101 : "ComponentsConfiguration", // Information about channels    0x9102 : "CompressedBitsPerPixel", // Compressed bits per pixel    // user information    0x927C : "MakerNote",        // Any desired information written by the manufacturer    0x9286 : "UserComment",       // Comments by user    // related file    0xA004 : "RelatedSoundFile",    // Name of related sound file    // date and time    0x9003 : "DateTimeOriginal",    // Date and time when the original image was generated    0x9004 : "DateTimeDigitized",    // Date and time when the image was stored digitally    0x9290 : "SubsecTime",       // Fractions of seconds for DateTime    0x9291 : "SubsecTimeOriginal",   // Fractions of seconds for DateTimeOriginal    0x9292 : "SubsecTimeDigitized",   // Fractions of seconds for DateTimeDigitized    // picture-taking conditions    0x829A : "ExposureTime",      // Exposure time (in seconds)    0x829D : "FNumber",         // F number    0x8822 : "ExposureProgram",     // Exposure program    0x8824 : "SpectralSensitivity",   // Spectral sensitivity    0x8827 : "ISOSpeedRatings",     // ISO speed rating    0x8828 : "OECF",          // Optoelectric conversion factor    0x9201 : "ShutterSpeedValue",    // Shutter speed    0x9202 : "ApertureValue",      // Lens aperture    0x9203 : "BrightnessValue",     // Value of brightness    0x9204 : "ExposureBias",      // Exposure bias    0x9205 : "MaxApertureValue",    // Smallest F number of lens    0x9206 : "SubjectDistance",     // Distance to subject in meters    0x9207 : "MeteringMode",      // Metering mode    0x9208 : "LightSource",       // Kind of light source    0x9209 : "Flash",          // Flash status    0x9214 : "SubjectArea",       // Location and area of main subject    0x920A : "FocalLength",       // Focal length of the lens in mm    0xA20B : "FlashEnergy",       // Strobe energy in BCPS    0xA20C : "SpatialFrequencyResponse",  //    0xA20E : "FocalPlaneXResolution",  // Number of pixels in width direction per FocalPlaneResolutionUnit    0xA20F : "FocalPlaneYResolution",  // Number of pixels in height direction per FocalPlaneResolutionUnit    0xA210 : "FocalPlaneResolutionUnit",  // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution    0xA214 : "SubjectLocation",     // Location of subject in image    0xA215 : "ExposureIndex",      // Exposure index selected on camera    0xA217 : "SensingMethod",      // Image sensor type    0xA300 : "FileSource",       // Image source (3 == DSC)    0xA301 : "SceneType",        // Scene type (1 == directly photographed)    0xA302 : "CFAPattern",       // Color filter array geometric pattern    0xA401 : "CustomRendered",     // Special processing    0xA402 : "ExposureMode",      // Exposure mode    0xA403 : "WhiteBalance",      // 1 = auto white balance, 2 = manual    0xA404 : "DigitalZoomRation",    // Digital zoom ratio    0xA405 : "FocalLengthIn35mmFilm",  // Equivalent foacl length assuming 35mm film camera (in mm)    0xA406 : "SceneCaptureType",    // Type of scene    0xA407 : "GainControl",       // Degree of overall image gain adjustment    0xA408 : "Contrast",        // Direction of contrast processing applied by camera    0xA409 : "Saturation",       // Direction of saturation processing applied by camera    0xA40A : "Sharpness",        // Direction of sharpness processing applied by camera    0xA40B : "DeviceSettingDescription",  //    0xA40C : "SubjectDistanceRange",  // Distance to subject    // other tags    0xA005 : "InteroperabilityIFDPointer",    0xA420 : "ImageUniqueID"      // Identifier assigned uniquely to each image  };  var TiffTags = EXIF.TiffTags = {    0x0100 : "ImageWidth",    0x0101 : "ImageHeight",    0x8769 : "ExifIFDPointer",    0x8825 : "GPSInfoIFDPointer",    0xA005 : "InteroperabilityIFDPointer",    0x0102 : "BitsPerSample",    0x0103 : "Compression",    0x0106 : "PhotometricInterpretation",    0x0112 : "Orientation",    0x0115 : "SamplesPerPixel",    0x011C : "PlanarConfiguration",    0x0212 : "YCbCrSubSampling",    0x0213 : "YCbCrPositioning",    0x011A : "XResolution",    0x011B : "YResolution",    0x0128 : "ResolutionUnit",    0x0111 : "StripOffsets",    0x0116 : "RowsPerStrip",    0x0117 : "StripByteCounts",    0x0201 : "JPEGInterchangeFormat",    0x0202 : "JPEGInterchangeFormatLength",    0x012D : "TransferFunction",    0x013E : "WhitePoint",    0x013F : "PrimaryChromaticities",    0x0211 : "YCbCrCoefficients",    0x0214 : "ReferenceBlackWhite",    0x0132 : "DateTime",    0x010E : "ImageDescription",    0x010F : "Make",    0x0110 : "Model",    0x0131 : "Software",    0x013B : "Artist",    0x8298 : "Copyright"  };  var GPSTags = EXIF.GPSTags = {    0x0000 : "GPSVersionID",    0x0001 : "GPSLatitudeRef",    0x0002 : "GPSLatitude",    0x0003 : "GPSLongitudeRef",    0x0004 : "GPSLongitude",    0x0005 : "GPSAltitudeRef",    0x0006 : "GPSAltitude",    0x0007 : "GPSTimeStamp",    0x0008 : "GPSSatellites",    0x0009 : "GPSStatus",    0x000A : "GPSMeasureMode",    0x000B : "GPSDOP",    0x000C : "GPSSpeedRef",    0x000D : "GPSSpeed",    0x000E : "GPSTrackRef",    0x000F : "GPSTrack",    0x0010 : "GPSImgDirectionRef",    0x0011 : "GPSImgDirection",    0x0012 : "GPSMapDatum",    0x0013 : "GPSDestLatitudeRef",    0x0014 : "GPSDestLatitude",    0x0015 : "GPSDestLongitudeRef",    0x0016 : "GPSDestLongitude",    0x0017 : "GPSDestBearingRef",    0x0018 : "GPSDestBearing",    0x0019 : "GPSDestDistanceRef",    0x001A : "GPSDestDistance",    0x001B : "GPSProcessingMethod",    0x001C : "GPSAreaInformation",    0x001D : "GPSDateStamp",    0x001E : "GPSDifferential"  };  var StringValues = EXIF.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 : {      0x0000 : "Flash did not fire",      0x0001 : "Flash fired",      0x0005 : "Strobe return light not detected",      0x0007 : "Strobe return light detected",      0x0009 : "Flash fired, compulsory flash mode",      0x000D : "Flash fired, compulsory flash mode, return light not detected",      0x000F : "Flash fired, compulsory flash mode, return light detected",      0x0010 : "Flash did not fire, compulsory flash mode",      0x0018 : "Flash did not fire, auto mode",      0x0019 : "Flash fired, auto mode",      0x001D : "Flash fired, auto mode, return light not detected",      0x001F : "Flash fired, auto mode, return light detected",      0x0020 : "No flash function",      0x0041 : "Flash fired, red-eye reduction mode",      0x0045 : "Flash fired, red-eye reduction mode, return light not detected",      0x0047 : "Flash fired, red-eye reduction mode, return light detected",      0x0049 : "Flash fired, compulsory flash mode, red-eye reduction mode",      0x004D : "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",      0x004F : "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",      0x0059 : "Flash fired, auto mode, red-eye reduction mode",      0x005D : "Flash fired, auto mode, return light not detected, red-eye reduction mode",      0x005F : "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"    }  };  function addEvent(element, event, handler) {    if (element.addEventListener) {      element.addEventListener(event, handler, false);    } else if (element.attachEvent) {      element.attachEvent("on" + event, handler);    }  }  function imageHasData(img) {    return !!(img.exifdata);  }  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);    var len = binary.length;    var buffer = new ArrayBuffer(len);    var view = new Uint8Array(buffer);    for (var i = 0; i < len; i++) {      view[i] = binary.charCodeAt(i);    }    return buffer;  }  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 getImageData(img, callback) {    function handleBinaryFile(binFile) {      var data = findEXIFinJPEG(binFile);      var iptcdata = findIPTCinJPEG(binFile);      img.exifdata = data || {};      img.iptcdata = iptcdata || {};      if (callback) {        callback.call(img);      }    }    if (img.src) {      if (/^data/:/i.test(img.src)) { // Data URI        var arrayBuffer = base64ToArrayBuffer(img.src);        handleBinaryFile(arrayBuffer);      } else if (/^blob/:/i.test(img.src)) { // Object URL        var fileReader = new FileReader();        fileReader.onload = function(e) {          handleBinaryFile(e.target.result);        };        objectURLToBlob(img.src, function (blob) {          fileReader.readAsArrayBuffer(blob);        });      } else {        var http = new XMLHttpRequest();        http.onload = function() {          if (this.status == 200 || this.status === 0) {            handleBinaryFile(http.response);          } else {            throw "Could not load image";          }          http = null;        };        http.open("GET", img.src, true);        http.responseType = "arraybuffer";        http.send(null);      }    } else if (window.FileReader && (img instanceof window.Blob || img instanceof window.File)) {      var fileReader = new FileReader();      fileReader.onload = function(e) {        if (debug) console.log("Got file of length " + e.target.result.byteLength);        handleBinaryFile(e.target.result);      };      fileReader.readAsArrayBuffer(img);    }  }  function findEXIFinJPEG(file) {    var dataView = new DataView(file);    if (debug) console.log("Got file of length " + file.byteLength);    if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {      if (debug) console.log("Not a valid JPEG");      return false; // not a valid jpeg    }    var offset = 2,      length = file.byteLength,      marker;    while (offset < length) {      if (dataView.getUint8(offset) != 0xFF) {        if (debug) console.log("Not a valid marker at offset " + offset + ", found: " + dataView.getUint8(offset));        return false; // not a valid marker, something is wrong      }      marker = dataView.getUint8(offset + 1);      if (debug) console.log(marker);      // we could implement handling for other markers here,      // but we're only looking for 0xFFE1 for EXIF data      if (marker == 225) {        if (debug) console.log("Found 0xFFE1 marker");        return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2);        // offset += 2 + file.getShortAt(offset+2, true);      } else {        offset += 2 + dataView.getUint16(offset+2);      }    }  }  function findIPTCinJPEG(file) {    var dataView = new DataView(file);    if (debug) console.log("Got file of length " + file.byteLength);    if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {      if (debug) console.log("Not a valid JPEG");      return false; // not a valid jpeg    }    var offset = 2,      length = file.byteLength;    var isFieldSegmentStart = function(dataView, offset){      return (        dataView.getUint8(offset) === 0x38 &&        dataView.getUint8(offset+1) === 0x42 &&        dataView.getUint8(offset+2) === 0x49 &&        dataView.getUint8(offset+3) === 0x4D &&        dataView.getUint8(offset+4) === 0x04 &&        dataView.getUint8(offset+5) === 0x04      );    };    while (offset < length) {      if ( isFieldSegmentStart(dataView, offset )){        // Get the length of the name header (which is padded to an even number of bytes)        var nameHeaderLength = dataView.getUint8(offset+7);        if(nameHeaderLength % 2 !== 0) nameHeaderLength += 1;        // Check for pre photoshop 6 format        if(nameHeaderLength === 0) {          // Always 4          nameHeaderLength = 4;        }        var startOffset = offset + 8 + nameHeaderLength;        var sectionLength = dataView.getUint16(offset + 6 + nameHeaderLength);        return readIPTCData(file, startOffset, sectionLength);        break;      }      // Not the marker, continue searching      offset++;    }  }  var IptcFieldMap = {    0x78 : 'caption',    0x6E : 'credit',    0x19 : 'keywords',    0x37 : 'dateCreated',    0x50 : 'byline',    0x55 : 'bylineTitle',    0x7A : 'captionWriter',    0x69 : 'headline',    0x74 : 'copyright',    0x0F : 'category'  };  function readIPTCData(file, startOffset, sectionLength){    var dataView = new DataView(file);    var data = {};    var fieldValue, fieldName, dataSize, segmentType, segmentSize;    var segmentStartPos = startOffset;    while(segmentStartPos < startOffset+sectionLength) {      if(dataView.getUint8(segmentStartPos) === 0x1C && dataView.getUint8(segmentStartPos+1) === 0x02){        segmentType = dataView.getUint8(segmentStartPos+2);        if(segmentType in IptcFieldMap) {          dataSize = dataView.getInt16(segmentStartPos+3);          segmentSize = dataSize + 5;          fieldName = IptcFieldMap[segmentType];          fieldValue = getStringFromDB(dataView, segmentStartPos+5, dataSize);          // Check if we already stored a value with this name          if(data.hasOwnProperty(fieldName)) {            // Value already stored with this name, create multivalue field            if(data[fieldName] instanceof Array) {              data[fieldName].push(fieldValue);            }            else {              data[fieldName] = [data[fieldName], fieldValue];            }          }          else {            data[fieldName] = fieldValue;          }        }      }      segmentStartPos++;    }    return data;  }  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)];      if (!tag && debug) console.log("Unknown tag: " + 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") {      if (debug) console.log("Not valid EXIF data! " + getStringFromDB(file, start, 4));      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 {      if (debug) console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)");      return false;    }    if (file.getUint16(tiffOffset+2, !bigEnd) != 0x002A) {      if (debug) console.log("Not valid TIFF data! (no 0x002A)");      return false;    }    var firstIFDOffset = file.getUint32(tiffOffset+4, !bigEnd);    if (firstIFDOffset < 0x00000008) {      if (debug) console.log("Not valid TIFF data! (First offset less than 8)", file.getUint32(tiffOffset+4, !bigEnd));      return false;    }    tags = readTags(file, tiffOffset, tiffOffset + firstIFDOffset, TiffTags, bigEnd);    if (tags.ExifIFDPointer) {      exifData = readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, ExifTags, bigEnd);      for (tag in exifData) {        switch (tag) {          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" :            exifData[tag] = StringValues[tag][exifData[tag]];            break;          case "ExifVersion" :          case "FlashpixVersion" :            exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2], exifData[tag][3]);            break;          case "ComponentsConfiguration" :            exifData[tag] =              StringValues.Components[exifData[tag][0]] +              StringValues.Components[exifData[tag][1]] +              StringValues.Components[exifData[tag][2]] +              StringValues.Components[exifData[tag][3]];            break;        }        tags[tag] = exifData[tag];      }    }    if (tags.GPSInfoIFDPointer) {      gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd);      for (tag in gpsData) {        switch (tag) {          case "GPSVersionID" :            gpsData[tag] = gpsData[tag][0] +              "." + gpsData[tag][1] +              "." + gpsData[tag][2] +              "." + gpsData[tag][3];            break;        }        tags[tag] = gpsData[tag];      }    }    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];  }  EXIF.getAllTags = function(img) {    if (!imageHasData(img)) return {};    var a,      data = img.exifdata,      tags = {};    for (a in data) {      if (data.hasOwnProperty(a)) {        tags[a] = data[a];      }    }    return tags;  }  EXIF.pretty = function(img) {    if (!imageHasData(img)) return "";    var a,      data = img.exifdata,      strPretty = "";    for (a in data) {      if (data.hasOwnProperty(a)) {        if (typeof data[a] == "object") {          if (data[a] instanceof Number) {            strPretty += a + " : " + data[a] + " [" + data[a].numerator + "/" + data[a].denominator + "]/r/n";          } else {            strPretty += a + " : [" + data[a].length + " values]/r/n";          }        } else {          strPretty += a + " : " + data[a] + "/r/n";        }      }    }    return strPretty;  }  EXIF.readFromBinaryFile = function(file) {    return findEXIFinJPEG(file);  }  if (typeof define === 'function' && define.amd) {    define('exif-js', [], function() {      return EXIF;    });  }}.call(this));

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表