public static void Main() { // this will rip through all JPEGs in the current directory foreach (string filename in Directory.GetFiles(".", "*.jpg", SearchOption.TopDirectoryOnly)) { TextWriter console = Console.Out; #if DIAGNOSTICS using (TextWriter output = File.CreateText(filename + ".txt")) #endif { console.WriteLine("Processing " + filename); #if DIAGNOSTICS Console.SetOut(output); try #endif { // extract properties out of JPEG XmpPropertyCollection properties = XmpPropertyCollection.LoadFromImage(filename); // serialize properties to XML using (TextWriter writer = File.CreateText(filename + ".xmp")) { properties.SaveAsXml(writer); } } #if DIAGNOSTICS finally { Console.SetOut(console); } #endif } } // this will rip through all XMPs in the current directory foreach (string filename in Directory.GetFiles(".", "*.xmp", SearchOption.TopDirectoryOnly)) { Console.Out.WriteLine("Processing " + filename); // deserialize properties from XML XmpPropertyCollection properties = XmpPropertyCollection.LoadFromXml(filename); // custom value extractions ImageXmp meta = ImageXmp.Create(properties); meta.Creator = "Changed the creator via XmpProperty"; meta.Copyright = "Copyright changed as well."; meta.Tags = new string[] { "Keyword-1", "Tag-2", "Subject-3" }; // apply values back into properties properties[DublinCoreSchema.Creator] = meta.Creator; properties[DublinCoreSchema.Rights] = meta.Copyright; properties[DublinCoreSchema.Subject] = meta.Tags; // re-serialize properties to new XML using (TextWriter writer = File.CreateText(Path.GetFileNameWithoutExtension(filename) + ".xml")) { properties.SaveAsXml(writer); } } }
/// <summary> /// Factory method /// </summary> /// <param name="properties">EXIF properties from which to populate</param> public static ImageXmp Create(XmpPropertyCollection properties) { if (properties == null) { throw new ArgumentNullException("properties"); } // References: // http://www.media.mit.edu/pia/Research/deepview/exif.html // http://en.wikipedia.org/wiki/APEX_system // http://en.wikipedia.org/wiki/Exposure_value decimal decimalValue; DateTime dateValue; string stringValue; GpsCoordinate gpsValue; IDictionary <string, object> dictionaryValue; ImageXmp xmp = new ImageXmp(); #region Aperture if (properties.TryGetValue(ExifSchema.FNumber, out decimalValue)) { // f/x.x xmp.Aperture = decimalValue; } else if (properties.TryGetValue(ExifSchema.ApertureValue, out decimalValue)) { // f/x.x xmp.Aperture = Decimal.Round((decimal)Math.Pow(2.0, Convert.ToDouble(decimalValue) / 2.0), 1); } #endregion Aperture #region Creator if (properties.TryGetValue(DublinCoreSchema.Creator, out stringValue) || properties.TryGetValue(ExifTiffSchema.Artist, out stringValue) || properties.TryGetValue(ExifSchema.MSAuthor, out stringValue)) { xmp.Creator = stringValue; } #endregion Creator #region Copyright if (properties.TryGetValue(DublinCoreSchema.Rights, out stringValue) || properties.TryGetValue(ExifTiffSchema.Copyright, out stringValue)) { xmp.Copyright = stringValue; } #endregion Copyright #region DateTaken if (properties.TryGetValue(ExifSchema.DateTimeOriginal, out dateValue) || properties.TryGetValue(ExifSchema.DateTimeDigitized, out dateValue) || properties.TryGetValue(ExifTiffSchema.DateTime, out dateValue)) { xmp.DateTaken = dateValue; } #endregion DateTaken #region Description if (properties.TryGetValue(DublinCoreSchema.Description, out stringValue) || properties.TryGetValue(ExifTiffSchema.ImageDescription, out stringValue) || properties.TryGetValue(ExifSchema.MSSubject, out stringValue)) { xmp.Description = stringValue; } #endregion Description #region ExposureBias xmp.ExposureBias = properties.GetValue(ExifSchema.ExposureBiasValue, Rational <int> .Empty); #endregion ExposureBias #region ExposureMode xmp.ExposureMode = properties.GetValue(ExifSchema.ExposureMode, default(ExifTagExposureMode)); #endregion ExposureMode #region ExposureProgram xmp.ExposureProgram = properties.GetValue(ExifSchema.ExposureProgram, default(ExifTagExposureProgram)); #endregion ExposureProgram #region Flash if (properties.TryGetValue(ExifSchema.Flash, out dictionaryValue)) { // decode object into EXIF enum ExifTagFlash flashValue = default(ExifTagFlash); if (dictionaryValue.ContainsKey("Fired") && StringComparer.OrdinalIgnoreCase.Equals(Convert.ToString(dictionaryValue["Fired"]), Boolean.TrueString)) { flashValue |= ExifTagFlash.FlashFired; } if (dictionaryValue.ContainsKey("Function") && StringComparer.OrdinalIgnoreCase.Equals(Convert.ToString(dictionaryValue["Function"]), Boolean.TrueString)) { flashValue |= ExifTagFlash.NoFlashFunction; } if (dictionaryValue.ContainsKey("Mode")) { switch (Convert.ToString(dictionaryValue["Mode"])) { case "1": { flashValue |= ExifTagFlash.ModeOn; break; } case "2": { flashValue |= ExifTagFlash.ModeOff; break; } case "3": { flashValue |= ExifTagFlash.ModeAuto; break; } } } if (dictionaryValue.ContainsKey("RedEyeMode") && StringComparer.OrdinalIgnoreCase.Equals(Convert.ToString(dictionaryValue["RedEyeMode"]), Boolean.TrueString)) { flashValue |= ExifTagFlash.RedEyeReduction; } if (dictionaryValue.ContainsKey("Return")) { switch (Convert.ToString(dictionaryValue["Return"])) { case "2": { flashValue |= ExifTagFlash.ReturnNotDetected; break; } case "3": { flashValue |= ExifTagFlash.ReturnDetected; break; } } } xmp.Flash = flashValue; } #endregion Flash #region FocalLength if (properties.TryGetValue(ExifSchema.FocalLength, out decimalValue) || properties.TryGetValue(ExifSchema.FocalLengthIn35mmFilm, out decimalValue)) { xmp.FocalLength = Decimal.Round(decimalValue, 1); } #endregion FocalLength #region GpsAltitude if (properties.TryGetValue(ExifSchema.GPSAltitude, out decimalValue)) { xmp.GpsAltitude = Decimal.Round(decimalValue, 5); } #endregion GpsAltitude #region GpsLatitude if (properties.TryGetValue(ExifSchema.GPSLatitude, out gpsValue) || properties.TryGetValue(ExifSchema.GPSDestLatitude, out gpsValue)) { xmp.GpsLatitude = gpsValue; } #endregion GpsLatitude #region GpsLongitude if (properties.TryGetValue(ExifSchema.GPSLongitude, out gpsValue) || properties.TryGetValue(ExifSchema.GPSDestLongitude, out gpsValue)) { xmp.GpsLongitude = gpsValue; } #endregion GpsLongitude #region ImageHeight if (properties.TryGetValue(ExifTiffSchema.ImageLength, out decimalValue)) { xmp.ImageHeight = Convert.ToInt32(decimalValue); } #endregion ImageHeight #region ImageWidth if (properties.TryGetValue(ExifTiffSchema.ImageWidth, out decimalValue)) { xmp.ImageWidth = Convert.ToInt32(decimalValue); } #endregion ImageWidth #region ISOSpeed if (properties.TryGetValue(ExifSchema.ISOSpeedRatings, out decimalValue)) { xmp.ISOSpeed = Convert.ToInt32(decimalValue); } #endregion ISOSpeed #region Make if (properties.TryGetValue(ExifTiffSchema.Make, out stringValue)) { xmp.Make = stringValue; } #endregion Make #region Make if (properties.TryGetValue(ExifTiffSchema.Model, out stringValue)) { xmp.Model = stringValue; } #endregion Model #region MeteringMode xmp.MeteringMode = properties.GetValue(ExifSchema.MeteringMode, default(ExifTagMeteringMode)); #endregion MeteringMode #region Orientation xmp.Orientation = properties.GetValue(ExifTiffSchema.Orientation, default(ExifTagOrientation)); #endregion Orientation #region ShutterSpeed xmp.ShutterSpeed = properties.GetValue(ExifSchema.ExposureTime, Rational <uint> .Empty); if (xmp.ShutterSpeed.IsEmpty) { Rational <int> shutterSpeed = properties.GetValue(ExifSchema.ShutterSpeedValue, Rational <int> .Empty); if (!shutterSpeed.IsEmpty) { xmp.ShutterSpeed = Rational <uint> .Approximate((decimal)Math.Pow(2.0, -Convert.ToDouble(shutterSpeed))); } } #endregion ShutterSpeed #region Tags xmp.Tags = properties.GetValue(DublinCoreSchema.Subject, default(IEnumerable <string>)); // TODO: ExifSchema.MSKeywords #endregion Tags #region Title if (properties.TryGetValue(DublinCoreSchema.Title, out stringValue) || properties.TryGetValue(ExifSchema.ImageTitle, out stringValue) || properties.TryGetValue(ExifSchema.MSTitle, out stringValue)) { xmp.Title = stringValue; } #endregion Title #region WhiteBalance xmp.WhiteBalance = properties.GetValue(ExifSchema.WhiteBalance, default(ExifTagWhiteBalance)); #endregion WhiteBalance return(xmp); }