UNPKG

moweex-img-cropper

Version:

image cropper

859 lines 32.7 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 = /** @class */ (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 // Console debug wrapper that makes code looks a little bit cleaner Debug = /** @class */ (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; }()); // Console debug wrapper that makes code looks a little bit cleaner export { Debug }; var Exif = /** @class */ (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,/gim, ""); 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)) { // Data URI var arrayBuffer = Exif.base64ToArrayBuffer(img.src); handleBinaryFile(arrayBuffer); } else { if (/^blob:/i.test(img.src)) { // Object URL 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 // 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 // ascii, 8-bit byte offset = numValues > 4 ? valueOffset : entryOffset + 8; return Exif.getStringFromDB(file, offset, numValues - 1); case 3: // short, 16 bit int // 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 // 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 // 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 // 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 // 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; }; // get rid of this silly issue // get rid of this silly issue Exif.checkImageType = // get rid of this silly issue function (img) { return img instanceof Image || img instanceof HTMLImageElement; }; Exif.getData = function (img, callback) { if (this.checkImageType(img) && !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", // 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 }; 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