读取图片的exif相关信息并且将其调整顺序

来源:互联网 发布:小米max怎么备份数据 编辑:程序博客网 时间:2024/06/05 22:38

在看这个之前请看看

                            context.translate(Options.transX,Options.transY);                            context.rotate(0.25 * Math.PI);

与:

                            context.rotate(0.25 * Math.PI);                            context.translate(Options.transX,Options.transY);

前者以(150,150)为旋转点,后者以(0,0)为旋转点。

请注意顺序。

卡在这里很久了。


代码:

<%--  Created by IntelliJ IDEA.  User: Administrator  Date: 14-6-30  Time: 下午4:45  To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head>    <title></title>    <script type="text/javascript" src="/static/mobile/lib/zepto.min.js"></script></head><body><div class="operate_Bar1 clearfix">    <div class="btn_back_l" id="goBack" onclick="location.href=document.referrer+'&t='+(+new Date())"><a class="btn_back"><span></span><nav>返回</nav></a></div>    <div class="text">个人相片</div>    <div class="btn_r"><a class="btn_manage " style="display:none;" id="btn_save" >保存</a></div></div><div class="module">    <div><img id="originImg"/></div>    <div id="panel_file_input"><div></div></div>    <div id="panel_loading" class="loading hide">加载中</div>    <div id="panel_view_result" class="avatar_view hide ">        <div class="pic">            <img src="" alt="" style="width:150px; height:200px;" id="img_preview">            <input type="file" style="" id="uploadImage" class="upload_image" accept="image/*" />            <i class="camera_icon"></i>        </div>           </div>    <div class="avatar_edit hide" id="panel_edit">        <div>            <canvas id="tmp_canvas" width="300" height="300"></canvas>        </div>        <div class="component_box">            <div class="main_cutter">                <div class="cut_box" style="display:none;"></div>                <canvas id="canvas" width=300 height=300 style="position:absolute;left:0;"></canvas>                <canvas id="canvas_cutter" width=300 height=300 style="position:absolute;left:0;"></canvas>            </div>        </div>        <div class="slider clearfix" id="processBar" >            <div class="s_left" id="decreasePercent"><i></i></div>            <div class="s_main" ><i class="circular" style="left:50%"></i><i class="line" style="width:50%"></i></div>            <div class="s_right"  id="increasePercent"><i></i></div>        </div>    </div></div><div id="tips" style="color:green;"></div></body></html><script>    //--获取EXIF信息。    //--读取文件。    var __EXIF = (function() {        var debug = false;        var ExifTags = {            // 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 = {            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 = {            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 = {            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 instanceof Image || img instanceof HTMLImageElement) {                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 (http.status == "200") {                            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;        }        function getData(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;        }        function getTag(img, tag) {            if (!imageHasData(img)) return;            return img.exifdata[tag];        }        function getAllTags(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;        }        function pretty(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;        }        function readFromBinaryFile(file) {            return findEXIFinJPEG(file);        }        return {            readFromBinaryFile : readFromBinaryFile,            pretty : pretty,            getTag : getTag,            getAllTags : getAllTags,            getData : getData,            Tags : ExifTags,            TiffTags : TiffTags,            GPSTags : GPSTags,            StringValues : StringValues        };    })();</script><script>    //---修正ios压扁问题。    //--修正ios下面canvas图片压缩的情况。    /**     * Detecting vertical squash in loaded image.     * Fixes a bug which squash image vertically while drawing into canvas for some images.     * This is a bug in iOS6 devices. This function from https://github.com/stomita/ios-imagefile-megapixel     *     */    function detectVerticalSquash(img) {        var iw = img.naturalWidth, ih = img.naturalHeight;        var canvas = document.createElement('canvas');        canvas.width = 1;        canvas.height = ih;        var ctx = canvas.getContext('2d');        ctx.drawImage(img, 0, 0);        var data = ctx.getImageData(0, 0, 1, ih).data;        // search image edge pixel position in case it is squashed vertically.        var sy = 0;        var ey = ih;        var py = ih;        while (py > sy) {            var alpha = data[(py - 1) * 4 + 3];            if (alpha === 0) {                ey = py;            } else {                sy = py;            }            py = (ey + sy) >> 1;        }        var ratio = (py / ih);        return (ratio===0)?1:ratio;    }    /**     * A replacement for context.drawImage     * (args are for source and destination).     */    function drawImageIOSFix(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {        var vertSquashRatio = detectVerticalSquash(img);        // Works only if whole image is displayed:        // ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio);        // The following works correct also when only a part of the image is displayed:        ctx.drawImage(img, sx * vertSquashRatio, sy * vertSquashRatio,                sw * vertSquashRatio, sh * vertSquashRatio,                dx, dy, dw, dh );    }</script><script>    //--变量及常用状态,方法。    var Panel_loading=$("#panel_loading");    var Panel_view_result=$("#panel_view_result");    var Panel_edit=$("#panel_edit");    var BtnSave=$("#btn_save");    var imgPreview=document.getElementById("img_preview");    var jel_tips=$("#tips");    var tmpCanvas=document.getElementById("tmp_canvas");    var tmpContext=tmpCanvas.getContext("2d");    var canvas = document.getElementById('canvas');    var context = canvas.getContext('2d');    var originImg=document.getElementById("originImg");//原始图片    var oFReader = new FileReader(), rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;    //--四个,loading,result,file,edit    function changePanel(panelName){        Panel_edit.addClass("hide");        Panel_loading.addClass("hide");        Panel_view_result.addClass("hide");        if(panelName=="loading"){            Panel_loading.removeClass("hide");            BtnSave.css("display","none");            return;        }        if(panelName=="result"){            Panel_view_result.removeClass("hide");            BtnSave.css("display","none");            return;        }        if(panelName=="edit"){            Panel_edit.removeClass("hide");            BtnSave.css("display","");            return;        }    }    changePanel("result");</script><script>    //变量    var Options={        width:300,        height:300,        cutWidth:150,        cutHeight:200,        cutMinSize:50,//裁剪框最小尺寸,即最小可以缩放到这个size,width及height任意一个都无法小于这个值。        //--系统自带,运行时自动运算,请不要修改。        cropViewWidth:0,//在画布里面显示的最大宽度        cropViewHeight:0,//在画布里面显示的最大高度        cropLeft:0,        cropTop:0,        //--裁剪框        cutViewWidth:0,   //当前宽度,        cutViewHeight:0,//当前高度        cutMaxWidth:0,   //裁剪框最大宽度。        cutMaxHeight:0,//裁剪框最大高度。        //--四象限。用于判断距离。        cutBoxLimitX1:0,        cutBoxLimitX2:0,        cutBoxLimitY1:0,        cutBoxLimitY2:0,        cutLeft:0,//裁剪框绝对定位,左侧距离。        cutTop:0,//裁剪框绝对定位,离顶部距离。        initStatus:false,//当前组件是否已经初始化了。        Orientation:1,//当前图片的颠倒状态,通过exif读取。1表示正常,3表示上下颠倒,8表示要顺时针旋转90度。6表示逆时针旋转90度。        transX:0,//需要按照该起始点进行旋转        transY:0,        XDimension:0,        YDimension:0    };    var Options_image={        width:0,        height:0,        scaleWidth:0,//图片缩放后大小        scaleHeight:0,//图片缩放后大小        imgData:""    };    //--添加缩放功能。    var Options_zoom={        beginX1:0,        beginY1:0,        beginX2:0,        beginY2:0,        endX1:0,        endY1:0,        endX2:0,        endY2:0    };    //--添加裁剪框移动功能    var Options_move={        isInCutter:false,        beginX1:0,        beginY1:0,        endX1:0,        endY1:0    };    function drawImageAllFixed(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {        var vertSquashRatio = detectVerticalSquash(img);        // Works only if whole image is displayed:        // ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio);        // The following works correct also when only a part of the image is displayed:        ctx.drawImage(img, sx * vertSquashRatio, sy * vertSquashRatio,                sw * vertSquashRatio, sh * vertSquashRatio,                dx, dy, dw, dh );    }</script><script>    //--逻辑方法定义    $("#uploadImage").change(function(){        changePanel("loading");        if (document.getElementById("uploadImage").files.length === 0) { return; }        var oFile = document.getElementById("uploadImage").files[0];        //if (!rFilter.test(oFile.type)) { alert("You must select a valid image file!"); return; }        oFReader.readAsDataURL(oFile);    });    oFReader.onload = function (oFREvent) {        //document.getElementById("uploadPreview").src = oFREvent.target.result;        var image=new Image();        image.src = oFREvent.target.result;        originImg.src=oFREvent.target.result;        image.onload = function () {            //--修正ios6 7 颠倒,压扁问题。            __EXIF.getData(this, function() {                var make = __EXIF.getTag(this, "Make");                jel_tips.text("相关图片信息:"+__EXIF.pretty(this));                Options.Orientation= __EXIF.getTag(this, "Orientation");                if(Options.Orientation==undefined){                    Options.Orientation=1;                }                var _realWidth=0;                var _realHeight=0;                //--计算是否需要旋转。                if(Options.Orientation!=1){                    Options.transX=parseInt(Options.width/2);                    Options.transY=parseInt(Options.height/2);                }                else{                    Options.transX=0;                    Options.transY=0;                    _realWidth=image.width;                    _realHeight=image.height;                }                var XDimension= __EXIF.getTag(this,"PixelXDimension");                var YDimension=__EXIF.getTag(this,"PixelYDimension");                Options.XDimension=XDimension;                Options.YDimension=YDimension;                caculateOptions(image.width,image.height);                //--放入临时画布。                tmpContext.clearRect(0,0,tmpCanvas.width,tmpCanvas.height);                //context.clearRect(0,0,canvas.width,canvas.height);                //context.drawImage(image, 0, 0, image.width, image.height, Options.cropLeft, Options.cropTop, Options_image.scaleWidth, Options_image.scaleHeight);                // context.drawImage(image, 0, 0, image.width, image.height, Options.cropLeft, Options.cropTop, canvas.width, canvas.height);                drawImageIOSFix(tmpContext,image, 0, 0, image.width, image.height, Options.cropLeft, Options.cropTop, Options_image.scaleWidth, Options_image.scaleHeight);                context.clearRect(0,0,canvas.width,canvas.height);                //生成一个可以用的缩略图。                    switch(Options.Orientation){                        case 8:                            // 90 rotate left     --需要90度向左旋转。。那么,这个 PixelYDimension就是宽度了,PixelXDimension就是高度了。                            context.translate(Options.transX,Options.transY);                            context.rotate(-0.5 * Math.PI);                            _realWidth=YDimension;                            _realHeight=XDimension;                            break;                        case 3:                            //180向左旋转                            context.translate(Options.transX,Options.transY);                            context.rotate(Math.PI);                            _realWidth=XDimension;                            _realHeight=YDimension;                            break;                        case 6:                            //90 rotate right 需要向右旋转90度,PixelYDimension就是宽度了,PixelXDimension就是高度了。                            _realWidth=YDimension;                            _realHeight=XDimension;                            context.translate(Options.transX,Options.transY);                            context.rotate(0.5 * Math.PI);                            break;                        case 1:                            break;                    }                caculateOptions(_realWidth,_realHeight);                context.drawImage(tmpCanvas,0,0,tmpCanvas.width,tmpCanvas.height,0-Options.transX,0-Options.transY,tmpCanvas.width,tmpCanvas.height);                //--计算比例,将其放到canvas里面。                //context.drawImage(tmpCanvas,0,0,tmpCanvas.width,tmpCanvas.height,0-Options.transX,0-Options.transY,tmpCanvas.width,tmpCanvas.height);                //context.drawImage(tmpCanvas,0,0,tmpCanvas.width,tmpCanvas.height,0,0,tmpCanvas.width,tmpCanvas.height);                changePanel("edit");            });            return;        }        jel_tips.text("");    };    //--通过宽度及高度计算各种尺寸。    function caculateOptions(_width,_height){        Options_image.width=_width;        Options_image.height=_height;        var scale = Math.max(Options_image.width/Options.width,Options_image.height/Options.height);        if(scale>1){            Options.cropViewWidth=parseInt(Math.floor(Options_image.width/scale));            Options.cropViewHeight=parseInt(Math.floor(Options_image.height/scale));        }        else{            Options.cropViewWidth=Options_image.width;            Options.cropViewHeight=Options_image.height;        }        Options_image.scaleWidth=Options.cropViewWidth;        Options_image.scaleHeight=Options.cropViewHeight;        //--计算比例,将其放到canvas里面。        Options.cropViewWidth=Options_image.scaleWidth;        Options.cropViewHeight=Options_image.scaleHeight;        //--计算画布里面的图像的位置。        Options.cropLeft=parseInt((Options.width-Options.cropViewWidth)/2);        Options.cropTop=parseInt((Options.height-Options.cropViewHeight)/2);        //--计算裁剪框实际大小及实际位置。        //计算裁剪框的位置。        var scale_2=Math.max(Options.cutWidth/Options.cropViewWidth,Options.cutHeight/Options.cropViewHeight);        if(scale_2>1){            Options.cutViewWidth=parseInt(Math.floor(Options.cutWidth/scale_2));            Options.cutViewHeight=parseInt(Math.floor(Options.cutHeight/scale_2));        }        else{            //两个大于cutWidth及cutHeight,那么就按照相关步骤得出最大值。            Options.cutViewHeight=parseInt(Options.cutHeight/scale_2);            Options.cutViewWidth=parseInt(Options.cutWidth/scale_2);        }        Options.cutMaxWidth=Options.cutViewWidth;        Options.cutMaxHeight=Options.cutViewHeight;        Options.cutLeft=parseInt(Math.floor((Options.width-Options.cutViewWidth))/2);        Options.cutTop=parseInt(Math.floor((Options.height-Options.cutViewHeight))/2);        //-四象限。        Options.cutBoxLimitX1=parseInt((Options.width-Options_image.scaleWidth)/2);        Options.cutBoxLimitX2=Options.cutBoxLimitX1+Options_image.scaleWidth;        Options.cutBoxLimitY1=parseInt((Options.height-Options_image.scaleHeight)/2);        Options.cutBoxLimitY2=Options.cutBoxLimitY1+Options_image.scaleHeight;    }</script>


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 消毒柜开孔尺寸高度太高了怎么办 苏宁易购买的东西比专卖店贵怎么办 手机打字键盘上没有语音功能怎么办 网贷催收发语音侮辱人怎么办 康力无机房电梯到楼层不关门怎么办 档案工龄少算了工资领开了怎么办 别人骚扰我打电话报警人走了怎么办 因外借医保卡被香港保险拒保怎么办 医保和社保断了一个月怎么办 苹果8呼叫受限请勿越权使用怎么办 药物储存2~8度没冰箱怎么办 利仁分体电饼铛做饼熟的慢怎么办 闲鱼买的东西自提有问题怎么办 老板油烟机的表层的膜掉了怎么办 给老板打工老板跑路了怎么办 公司要业务员承担客户的欠款怎么办 从自己公司出去抢自己客户怎么办? 在苏宁买东西买贵了怎么办 苏宁购物小票不见了未提货怎么办 结痂的地方扣掉了颜色不一样怎么办 实体店买手机不给发票怎么办 小孩学英语字母怎么都记不住怎么办 聊客老是提示网络连接失败怎么办? 天猫购物漏发客服不理怎么办 京东二维码被骗怎么办联系客服号码 京东客服打电话来让自己退款怎么办 淘宝上买到的衣服是坏的怎么办 淘宝上买到的产品是坏的怎么办? 在淘宝买到东西是坏的怎么办 冰箱冷冻室门生锈变形关不严怎么办 诲信电冰箱电脑板坏了怎么办 冰箱里放了热水后就不制冷了怎么办 双温冰柜冷藏矿泉水不冰怎么办 美的电饭煲e一传感器也没坏怎么办 美的电饭煲不工作显示C3怎么办 美的电饭煲啪一声响不工作了怎么办 误给宝宝吃了坏的饭怎么办 鼠标没反应键盘指示灯不亮怎么办 新买变频冰箱风机声音大怎么办 三星手机玩王者荣耀一直闪退怎么办 刚申请的阿里大宝卡不想要了怎么办