UNPKG

contra-ngx-img-cropper

Version:
725 lines 28.6 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var Fraction = (function (_super) { __extends(Fraction, _super); function Fraction() { return _super !== null && _super.apply(this, arguments) || this; } return Fraction; }(Number)); export { Fraction }; // Console debug wrapper that makes code looks a little bit cleaner var Debug = (function () { function Debug() { } Debug.log = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (Exif.debug) { console.log(args); } }; return Debug; }()); export { Debug }; var Exif = (function () { function Exif() { } Exif.addEvent = function (element, event, handler) { if (element.addEventListener) { element.addEventListener(event, handler, false); } else { // Hello, IE! if (element.attachEvent) { element.attachEvent('on' + event, handler); } } }; Exif.imageHasData = function (img) { return !!(img.exifdata); }; Exif.base64ToArrayBuffer = function (base64) { 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; }; Exif.objectURLToBlob = function (url, callback) { var http = new XMLHttpRequest(); http.open('GET', url, true); http.responseType = 'blob'; http.onload = function () { if (http.status === 200 || http.status === 0) { callback(http.response); } }; http.send(); }; Exif.getImageData = function (img, callback) { function handleBinaryFile(binFile) { var data = Exif.findEXIFinJPEG(binFile); var iptcdata = Exif.findIPTCinJPEG(binFile); img.exifdata = data || {}; img.iptcdata = iptcdata || {}; if (callback) { callback.call(img); } } if ('src' in img && img.src) { if (/^data:/i.test(img.src)) { var arrayBuffer = Exif.base64ToArrayBuffer(img.src); handleBinaryFile(arrayBuffer); } else { if (/^blob:/i.test(img.src)) { var fileReader_1 = new FileReader(); fileReader_1.onload = function (e) { handleBinaryFile(e.target.result); }; Exif.objectURLToBlob(img.src, function (blob) { fileReader_1.readAsArrayBuffer(blob); }); } else { var http_1 = new XMLHttpRequest(); http_1.onload = function () { if (http_1.status === 200 || http_1.status === 0) { handleBinaryFile(http_1.response); } else { throw 'Could not load image'; } }; http_1.open('GET', img.src, true); http_1.responseType = 'arraybuffer'; http_1.send(null); } } } else { if (FileReader && (img instanceof Blob || img instanceof File)) { var fileReader = new FileReader(); fileReader.onload = function (e) { Debug.log('Got file of length ' + e.target.result.byteLength); handleBinaryFile(e.target.result); }; fileReader.readAsArrayBuffer(img); } } }; Exif.findEXIFinJPEG = function (file) { var dataView = new DataView(file); Debug.log('Got file of length ' + file.byteLength); if ((dataView.getUint8(0) !== 0xFF) || (dataView.getUint8(1) !== 0xD8)) { Debug.log('Not a valid JPEG'); return false; // not a valid jpeg } var offset = 2; var length = file.byteLength; var marker; while (offset < length) { if (dataView.getUint8(offset) !== 0xFF) { Debug.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); Debug.log(marker); // we could implement handling for other markers here, // but we're only looking for 0xFFE1 for EXIF data if (marker === 225) { Debug.log('Found 0xFFE1 marker'); return Exif.readEXIFData(dataView, offset + 4); // , dataView.getUint16(offset + 2) - 2); // offset += 2 + file.getShortAt(offset+2, true); } else { offset += 2 + dataView.getUint16(offset + 2); } } }; Exif.findIPTCinJPEG = function (file) { var dataView = new DataView(file); Debug.log('Got file of length ' + file.byteLength); if ((dataView.getUint8(0) !== 0xFF) || (dataView.getUint8(1) !== 0xD8)) { Debug.log('Not a valid JPEG'); return false; // not a valid jpeg } var offset = 2; var 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 Exif.readIPTCData(file, startOffset, sectionLength); } // Not the marker, continue searching offset++; } }; Exif.readIPTCData = function (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 Exif.IptcFieldMap) { dataSize = dataView.getInt16(segmentStartPos + 3); segmentSize = dataSize + 5; fieldName = Exif.IptcFieldMap[segmentType]; fieldValue = Exif.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; }; Exif.readTags = function (file, tiffStart, dirStart, strings, bigEnd) { var entries = file.getUint16(dirStart, !bigEnd); var tags = {}; var entryOffset; var tag; for (var i = 0; i < entries; i++) { entryOffset = dirStart + i * 12 + 2; tag = strings[file.getUint16(entryOffset, !bigEnd)]; if (!tag) { Debug.log('Unknown tag: ' + file.getUint16(entryOffset, !bigEnd)); } tags[tag] = Exif.readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd); } return tags; }; Exif.readTagValue = function (file, entryOffset, tiffStart, dirStart, bigEnd) { var type = file.getUint16(entryOffset + 2, !bigEnd); var numValues = file.getUint32(entryOffset + 4, !bigEnd); var valueOffset = file.getUint32(entryOffset + 8, !bigEnd) + tiffStart; var offset; var vals, val, n; var numerator; var 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 Exif.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 Fraction(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 Fraction(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; } default: break; } }; Exif.getStringFromDB = function (buffer, start, length) { var outstr = ''; for (var n = start; n < start + length; n++) { outstr += String.fromCharCode(buffer.getUint8(n)); } return outstr; }; Exif.readEXIFData = function (file, start) { if (Exif.getStringFromDB(file, start, 4) !== 'Exif') { Debug.log('Not valid EXIF data! ' + Exif.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 { Debug.log('Not valid TIFF data! (no 0x4949 or 0x4D4D)'); return false; } } if (file.getUint16(tiffOffset + 2, !bigEnd) !== 0x002A) { Debug.log('Not valid TIFF data! (no 0x002A)'); return false; } var firstIFDOffset = file.getUint32(tiffOffset + 4, !bigEnd); if (firstIFDOffset < 0x00000008) { Debug.log('Not valid TIFF data! (First offset less than 8)', file.getUint32(tiffOffset + 4, !bigEnd)); return false; } tags = Exif.readTags(file, tiffOffset, tiffOffset + firstIFDOffset, Exif.TiffTags, bigEnd); if (tags.ExifIFDPointer) { exifData = Exif.readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, Exif.Tags, bigEnd); for (tag in exifData) { if ({}.hasOwnProperty.call(exifData, tag)) { 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] = Exif.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': var compopents = 'Components'; exifData[tag] = Exif.StringValues[compopents][exifData[tag][0]] + Exif.StringValues[compopents][exifData[tag][1]] + Exif.StringValues[compopents][exifData[tag][2]] + Exif.StringValues[compopents][exifData[tag][3]]; break; default: break; } tags[tag] = exifData[tag]; } } } if (tags.GPSInfoIFDPointer) { gpsData = Exif.readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, Exif.GPSTags, bigEnd); for (tag in gpsData) { if ({}.hasOwnProperty.call(gpsData, tag)) { switch (tag) { case 'GPSVersionID': gpsData[tag] = gpsData[tag][0] + '.' + gpsData[tag][1] + '.' + gpsData[tag][2] + '.' + gpsData[tag][3]; break; default: break; } tags[tag] = gpsData[tag]; } } } return tags; }; Exif.getData = function (img, callback) { if ((img instanceof Image || img instanceof HTMLImageElement) && !img.complete) { return false; } if (!Exif.imageHasData(img)) { Exif.getImageData(img, callback); } else { if (callback) { callback.call(img); } } return true; }; Exif.getTag = function (img, tag) { if (!Exif.imageHasData(img)) { return; } return img.exifdata[tag]; }; ; Exif.getAllTags = function (img) { if (!Exif.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 (!Exif.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 Exif.findEXIFinJPEG(file); }; Exif.debug = false; Exif.IptcFieldMap = { 0x78: 'caption', 0x6E: 'credit', 0x19: 'keywords', 0x37: 'dateCreated', 0x50: 'byline', 0x55: 'bylineTitle', 0x7A: 'captionWriter', 0x69: 'headline', 0x74: 'copyright', 0x0F: 'category' }; Exif.Tags = { // version tags 0x9000: 'ExifVersion', 0xA000: 'FlashpixVersion', // colorspace tags 0xA001: 'ColorSpace', // image configuration 0xA002: 'PixelXDimension', 0xA003: 'PixelYDimension', 0x9101: 'ComponentsConfiguration', 0x9102: 'CompressedBitsPerPixel', // user information 0x927C: 'MakerNote', 0x9286: 'UserComment', // related file 0xA004: 'RelatedSoundFile', // date and time 0x9003: 'DateTimeOriginal', 0x9004: 'DateTimeDigitized', 0x9290: 'SubsecTime', 0x9291: 'SubsecTimeOriginal', 0x9292: 'SubsecTimeDigitized', // picture-taking conditions 0x829A: 'ExposureTime', 0x829D: 'FNumber', 0x8822: 'ExposureProgram', 0x8824: 'SpectralSensitivity', 0x8827: 'ISOSpeedRatings', 0x8828: 'OECF', 0x9201: 'ShutterSpeedValue', 0x9202: 'ApertureValue', 0x9203: 'BrightnessValue', 0x9204: 'ExposureBias', 0x9205: 'MaxApertureValue', 0x9206: 'SubjectDistance', 0x9207: 'MeteringMode', 0x9208: 'LightSource', 0x9209: 'Flash', 0x9214: 'SubjectArea', 0x920A: 'FocalLength', 0xA20B: 'FlashEnergy', 0xA20C: 'SpatialFrequencyResponse', 0xA20E: 'FocalPlaneXResolution', 0xA20F: 'FocalPlaneYResolution', 0xA210: 'FocalPlaneResolutionUnit', 0xA214: 'SubjectLocation', 0xA215: 'ExposureIndex', 0xA217: 'SensingMethod', 0xA300: 'FileSource', 0xA301: 'SceneType', 0xA302: 'CFAPattern', 0xA401: 'CustomRendered', 0xA402: 'ExposureMode', 0xA403: 'WhiteBalance', 0xA404: 'DigitalZoomRation', 0xA405: 'FocalLengthIn35mmFilm', 0xA406: 'SceneCaptureType', 0xA407: 'GainControl', 0xA408: 'Contrast', 0xA409: 'Saturation', 0xA40A: 'Sharpness', 0xA40B: 'DeviceSettingDescription', 0xA40C: 'SubjectDistanceRange', // other tags 0xA005: 'InteroperabilityIFDPointer', 0xA420: 'ImageUniqueID' // Identifier assigned uniquely to each image }; 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' }; 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' }; 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' } }; return Exif; }()); export { Exif }; //# sourceMappingURL=exif.js.map