UNPKG

image-classifier-ts

Version:

Command line tool to auto-classify images, renaming them with appropriate labels. Uses Node and Google Vision API.

146 lines 5.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ExifUtils = exports.ExifTagSet = exports.ExifTag = void 0; var fs = require("fs"); var path = require("path"); var Verbosity_1 = require("./output/Verbosity"); var SimpleDate_1 = require("./SimpleDate"); // To solve warning from exifreader global.DOMParser = require("xmldom").DOMParser; var exifReader = require("exifreader"); // Interesting subset of exif tags var ExifTag; (function (ExifTag) { ExifTag["ApertureValue"] = "ApertureValue"; ExifTag["ColorSpace"] = "ColorSpace"; ExifTag["DateTime"] = "DateTime"; ExifTag["FocalLength"] = "FocalLength"; ExifTag["GPSAltitude"] = "GPSAltitude"; ExifTag["GPSAltitudeRef"] = "GPSAltitudeRef"; ExifTag["GPSDateStamp"] = "GPSDateStamp"; ExifTag["GPSLatitude"] = "GPSLatitude"; ExifTag["GPSLatitudeRef"] = "GPSLatitudeRef"; ExifTag["GPSLongitude"] = "GPSLongitude"; ExifTag["GPSLongitudeRef"] = "GPSLongitudeRef"; ExifTag["ISOSpeedRatings"] = "ISOSpeedRatings"; ExifTag["Orientation"] = "Orientation"; ExifTag["ShutterSpeedValue"] = "ShutterSpeedValue"; })(ExifTag = exports.ExifTag || (exports.ExifTag = {})); var KNOWN_LATITUDE_FORMAT = "North latitude"; var KNOWN_LONGITUDE_FORMAT = "East longitude"; var DUMP_INDENT = " "; var ExifTagSet = /** @class */ (function () { function ExifTagSet() { this.map = new Map(); } ExifTagSet.fromTags = function (tags, outputter) { var interestingTags = Object.keys(ExifTag); var tagSet = new ExifTagSet(); interestingTags.forEach(function (tag) { var value = tags[tag] ? tags[tag].description : null; if (value) { tagSet.map.set(tag, value); } }); if (outputter.verbosity === Verbosity_1.Verbosity.High) { tagSet.dump(outputter); } return tagSet; }; ExifTagSet.prototype.dump = function (outputter) { var _this = this; this.map.forEach(function (value, key) { _this.dumpTag(key, value, outputter); }); outputter.infoMediumVerbose("".concat(DUMP_INDENT, "lat/longs"), this.isLatLongOk() ? "[ok]" : "[unknown format]"); }; ExifTagSet.prototype.dumpTag = function (tag, value, outputter) { outputter.infoMediumVerbose("".concat(DUMP_INDENT).concat(tag, " = ").concat(value)); }; ExifTagSet.prototype.get = function (tag) { if (!this.map.has(tag)) { return null; } return this.map.get(tag); }; ExifTagSet.prototype.getDateStamp = function () { // issue: some images have valid DateTime, but GPSDateStamp is in the future! // so, parse both and try to pick the best one: var dates = this.getAvailableDateStamps(); var now = new Date(); var nowSimple = SimpleDate_1.SimpleDate.fromDate(now); var validDates = dates.filter(function (d) { return d.year <= nowSimple.year && d.year > 1970; }); return validDates[0] || null; }; ExifTagSet.prototype.getAvailableDateStamps = function () { return [ this.tryGetExifDateStamp(ExifTag.GPSDateStamp), this.tryGetExifDateStamp(ExifTag.DateTime), ].filter(function (d) { return !!d; }); }; ExifTagSet.prototype.tryGetExifDateStamp = function (tag) { var dateValueYMD = this.tryGet(tag); if (!dateValueYMD) { return null; } // 'Y:M:D' OR 'Y:M:D H:M:S' return SimpleDate_1.SimpleDate.parseFromExifDate(dateValueYMD); }; ExifTagSet.prototype.tryGet = function (tag) { if (this.map.has(tag)) { return this.get(tag); } return null; }; ExifTagSet.prototype.isLatLongOk = function () { var lat = this.get(ExifTag.GPSLatitude); var long = this.get(ExifTag.GPSLongitude); return (lat !== null && long !== null && this.get(ExifTag.GPSLatitudeRef) === KNOWN_LATITUDE_FORMAT && this.get(ExifTag.GPSLongitudeRef) === KNOWN_LONGITUDE_FORMAT); }; return ExifTagSet; }()); exports.ExifTagSet = ExifTagSet; var ExifUtils; (function (ExifUtils) { function readFile(filepath, outputter) { if (!hasFileExif(filepath)) { return null; } var buffer = fs.readFileSync(filepath); try { var tags = exifReader.load(buffer.buffer); deleteUnusedTags(tags); return ExifTagSet.fromTags(tags, outputter); } catch (error) { if (error.name === "MetadataMissingError") { return null; } outputter.error("exif error", filepath, error); throw error; } } ExifUtils.readFile = readFile; var DELETED = {}; function deleteUnusedTags(tags) { // The MakerNote tag can be really large. Remove it to lower memory // usage if you're parsing a lot of files and saving the tags. tags["MakerNote"] = DELETED; // also delete any props that start with 'undefined- Object.keys(tags) .filter(function (t) { return t.startsWith("undefined"); }) .forEach(function (t) { tags[t] = DELETED; }); } function hasFileExif(filepath) { var extension = path.extname(filepath).toLowerCase(); // ExifReader supports JPEG. // note: some PNG files can have some EXIF data but it's not yet standard. return [".jpg", ".jpeg"].includes(extension); } })(ExifUtils = exports.ExifUtils || (exports.ExifUtils = {})); //# sourceMappingURL=ExifUtils.js.map