Beispiel #1
0
        private static string GetColorClassString(Directory exifItem)
        {
            var colorClassSting = string.Empty;
            var ratingCounts    = exifItem.Tags.Count(p => p.DirectoryName == "IPTC" && p.Name.Contains("0x02dd"));

            if (ratingCounts >= 1)
            {
                var prefsTag = exifItem.Tags.FirstOrDefault(p =>
                                                            p.DirectoryName == "IPTC" && p.Name.Contains("0x02dd"))?.Description;

                // Results for example
                //     0:1:0:-00001
                //     ~~~~~~
                //     0:8:0:-00001

                if (!string.IsNullOrWhiteSpace(prefsTag))
                {
                    var prefsTagSplit = prefsTag.Split(":".ToCharArray());
                    colorClassSting = prefsTagSplit[1];
                }
                return(colorClassSting);
            }

            // Xmp readings
            colorClassSting = GetXmpData(exifItem, "photomechanic:ColorClass");
            return(colorClassSting);
        }
Beispiel #2
0
        /// <summary>
        /// [Exif SubIFD] Shutter Speed Value = 1/2403 sec
        /// </summary>
        /// <param name="exifItem">item to look in</param>
        /// <returns>value</returns>
        private static string GetShutterSpeedValue(Directory exifItem)
        {
            var shutterSpeedString = exifItem.Tags.FirstOrDefault(p =>
                                                                  p.DirectoryName == "Exif SubIFD" && p.Name == "Shutter Speed Value")?.Description;

            if (string.IsNullOrEmpty(shutterSpeedString))
            {
                shutterSpeedString = exifItem.Tags.FirstOrDefault(p =>
                                                                  p.DirectoryName == "Exif SubIFD" && p.Name == "Exposure Time")?.Description;
            }

            // XMP,http://ns.adobe.com/exif/1.0/,exif:ExposureTime,1/20
            var exposureTimeXmp = GetXmpData(exifItem, "exif:ExposureTime");

            if (string.IsNullOrEmpty(shutterSpeedString) && !string.IsNullOrEmpty(exposureTimeXmp) && exposureTimeXmp.Length <= 20)
            {
                return(exposureTimeXmp);
            }

            if (shutterSpeedString == null)
            {
                return(string.Empty);
            }
            // the database has a 20 char limit
            if (shutterSpeedString.Length >= 20)
            {
                return(string.Empty);
            }

            // in xmp there is only a field with for example: 1/33
            shutterSpeedString = shutterSpeedString.Replace(" sec", string.Empty);
            return(shutterSpeedString);
        }
Beispiel #3
0
        /// <summary>
        /// [Exif SubIFD] Focal Length
        /// </summary>
        /// <returns></returns>
        private static double GetFocalLength(Directory exifItem)
        {
            var focalLengthString = exifItem.Tags.FirstOrDefault(
                p => p.DirectoryName == "Exif SubIFD" &&
                p.Name == "Focal Length")?.Description;

            // XMP,http://ns.adobe.com/exif/1.0/,exif:FocalLength,11/1
            var focalLengthXmp = GetXmpData(exifItem, "exif:FocalLength");

            if (string.IsNullOrEmpty(focalLengthString) && !string.IsNullOrEmpty(focalLengthXmp))
            {
                return(Math.Round(MathFraction.Fraction(focalLengthXmp), 5));
            }

            if (string.IsNullOrWhiteSpace(focalLengthString))
            {
                return(0d);
            }

            focalLengthString = focalLengthString.Replace(" mm", string.Empty);

            // Note: focalLengthString: (Dutch) 2,2 or (English) 2.2 based CultureInfo.CurrentCulture
            float.TryParse(focalLengthString, NumberStyles.Number, CultureInfo.CurrentCulture, out var focalLength);

            return(Math.Round(focalLength, 5));
        }
Beispiel #4
0
        private static double GetAperture(Directory exifItem)
        {
            var apertureString = exifItem.Tags.FirstOrDefault(p =>
                                                              p.DirectoryName == "Exif SubIFD" && p.Name == "Aperture Value")?.Description;

            if (string.IsNullOrEmpty(apertureString))
            {
                apertureString = exifItem.Tags.FirstOrDefault(p =>
                                                              p.DirectoryName == "Exif SubIFD" && p.Name == "F-Number")?.Description;
            }

            // XMP,http://ns.adobe.com/exif/1.0/,exif:FNumber,9/1
            var fNumberXmp = GetXmpData(exifItem, "exif:FNumber");

            if (string.IsNullOrEmpty(apertureString) && !string.IsNullOrEmpty(fNumberXmp))
            {
                return(MathFraction.Fraction(fNumberXmp));
            }

            if (apertureString == null)
            {
                return(0d);
            }

            apertureString = apertureString.Replace("f/", string.Empty);
            // Note: apertureString: (Dutch) 2,2 or (English) 2.2 based CultureInfo.CurrentCulture
            float.TryParse(apertureString, NumberStyles.Number, CultureInfo.CurrentCulture, out var aperture);

            return(aperture);
        }
        private void AddDates(MetadataExtractor.Directory xmpData, Photo photo)
        {
            var xmpDirectory         = xmpData as XmpDirectory;
            var dateCreated          = xmpDirectory.XmpMeta.Properties.SingleOrDefault(p => p.Path == "xmp:CreateDate");
            var photoshopDateCreated = xmpDirectory.XmpMeta.Properties.SingleOrDefault(p => p.Path == "photoshop:DateCreated");
            var dateModified         = xmpDirectory.XmpMeta.Properties.SingleOrDefault(p => p.Path == "xmp:ModifyDate");

            if (!String.IsNullOrWhiteSpace(dateCreated?.Value))
            {
                if (DateTime.TryParse(dateCreated.Value, out DateTime takenDate))
                {
                    photo.TakenDate = takenDate;
                }
            }
            if (!photo.TakenDate.HasValue && !String.IsNullOrWhiteSpace(photoshopDateCreated?.Value))
            {
                if (DateTime.TryParse(photoshopDateCreated.Value, out DateTime photoshopTakenDate))
                {
                    photo.TakenDate = photoshopTakenDate;
                }
            }
            if (!String.IsNullOrWhiteSpace(dateModified?.Value))
            {
                if (DateTime.TryParse(dateCreated.Value, out DateTime modifiedDate))
                {
                    photo.ModifiedDate = modifiedDate;
                }
            }
        }
Beispiel #6
0
        public static FileIndexItem.Rotation GetOrientationFromExifItem(Directory exifItem)
        {
            var tCounts = exifItem.Tags.Count(p => p.DirectoryName == "Exif IFD0" && p.Name == "Orientation");

            if (tCounts < 1)
            {
                return(FileIndexItem.Rotation.DoNotChange);
            }

            var caption = exifItem.Tags.FirstOrDefault(
                p => p.DirectoryName == "Exif IFD0" &&
                p.Name == "Orientation")?.Description;

            // Not unit tested :(
            switch (caption)
            {
            case "Top, left side (Horizontal / normal)":
                return(FileIndexItem.Rotation.Horizontal);

            case "Right side, top (Rotate 90 CW)":
                return(FileIndexItem.Rotation.Rotate90Cw);

            case "Bottom, right side (Rotate 180)":
                return(FileIndexItem.Rotation.Rotate180);

            case "Left side, bottom (Rotate 270 CW)":
                return(FileIndexItem.Rotation.Rotate270Cw);

            default:
                return(FileIndexItem.Rotation.Horizontal);
            }
        }
Beispiel #7
0
        /// <summary>
        /// [Exif SubIFD] Lens Model = E 18-200mm F3.5-6.3 OSS LE
        /// </summary>
        /// <param name="exifItem"></param>
        /// <returns></returns>
        private static string GetMakeLensModel(Directory exifItem)
        {
            var lensModel = exifItem.Tags.FirstOrDefault(
                p => p.DirectoryName == "Exif SubIFD" &&
                p.Name == "Lens Model")?.Description;

            return(lensModel == "----" ? string.Empty : lensModel);
        }
        private void AddMetadataLabel(List <string> labels, MetadataExtractor.Directory exifDir, string tagName)
        {
            var tag = exifDir.Tags.SingleOrDefault(t => t.Name == tagName);

            if (!string.IsNullOrWhiteSpace(tag?.Description))
            {
                labels.Add(tag.Description);
            }
        }
        private void AddExifDates(MetadataExtractor.Directory directory, Photo photo)
        {
            var tag = directory.Tags.SingleOrDefault(t => t.Name == "Date/Time");

            if (!string.IsNullOrWhiteSpace(tag?.Description) && DateTime.TryParse(tag.Description, out DateTime creationDate))
            {
                photo.TakenDate = creationDate;
            }
        }
        /// <summary>
        /// Extract exif data from picture directories.
        /// </summary>
        /// <param name="pictureDirectory"></param>
        /// <param name="pictureExiftag"></param>
        /// <returns></returns>
        public string GetExifData(MetadataExtractor.Directory pictureDirectory, int pictureExiftag)
        {
            var exifData = pictureDirectory?.GetDescription(pictureExiftag);

            var pictureExifData = (!string.IsNullOrEmpty(exifData)) ?
                                  (pictureExifMetaData.SpaceTabulation + exifData) :
                                  pictureExifMetaData.TabEmpty;

            return(pictureExifData);
        }
        private void AddLabelFromXmpDescription(List <string> labels, MetadataExtractor.Directory xmpData)
        {
            var xmpDirectory = xmpData as XmpDirectory;
            var artworkDesc  = xmpDirectory.XmpMeta.Properties.SingleOrDefault(p => p.Path == "Iptc4xmpExt:ArtworkContentDescription");

            if (artworkDesc != null)
            {
                labels.Add(artworkDesc.Value);
            }
        }
Beispiel #12
0
        private static string GetXmpData(Directory exifItem, string propertyPath)
        {
            // for xmp notes
            if (!(exifItem is XmpDirectory xmpDirectory) || xmpDirectory.XmpMeta == null)
            {
                return(string.Empty);
            }

            return((from property in xmpDirectory.XmpMeta.Properties.Where(p => !string.IsNullOrEmpty(p.Value))
                    where property.Path == propertyPath select property.Value).FirstOrDefault());
        }
Beispiel #13
0
        private static string ParseString(Directory subIfd, int tag)
        {
            var stringValue = subIfd.GetStringValue(tag);

            if (stringValue.Bytes != null)
            {
                return(stringValue.ToString());
            }

            return(null);
        }
Beispiel #14
0
        private static T?ParseRational <T>(Directory directory, int tag, Func <double, T> convert) where T : struct
        {
            if (directory.TryGetRational(tag, out var rational))
            {
                var orig = (rational.Numerator / (double)rational.Denominator);
                // var boxed = (object) orig;

                return(convert(orig));
            }

            return(null);
        }
Beispiel #15
0
        /// <summary>
        /// Copmare if two exif tags has the same value
        /// </summary>
        /// <param name="tag"></param>
        /// <param name="subDir1"></param>
        /// <param name="subDif2"></param>
        /// <returns>true if not null and has the same value</returns>
        private static bool CompareDir(int tag, MetadataExtractor.Directory subDir1, MetadataExtractor.Directory subDif2)
        {
            var width1 = subDir1?.GetDescription(tag);
            var width2 = subDif2?.GetDescription(tag);

            if (width1 == null && width2 == null)
            {
                return(true);
            }

            return(width1 != null && width1.Equals(width2));
        }
Beispiel #16
0
        /// <summary>
        /// Extracts all tags with names matching the filter from the directory and returns an enumerable of those tags.
        /// </summary>
        private static IEnumerable <Tag> ExtractDirectoryTags(MetadataExtractor.Directory dir, Func <Tag, bool> filter)
        {
            List <Tag> tags = new List <Tag>();

            foreach (Tag t in dir.Tags)
            {
                if (filter(t))
                {
                    tags.Add(t);
                }
            }
            return(tags);
        }
Beispiel #17
0
        private static DateTime?ParseDateTime(Directory gpsDirectory, DateTimeStyles dateTimeStyles)
        {
            var timeStamp = gpsDirectory.GetRationalArray(GpsDirectory.TagTimeStamp);
            var dateStamp = gpsDirectory.GetString(GpsDirectory.TagDateStamp);

            if (timeStamp == null || dateStamp == null)
            {
                return(null);
            }

            var hour   = ParseRational(timeStamp[0], Convert.ToInt32);
            var minute = ParseRational(timeStamp[1], Convert.ToInt32);
            var second = ParseRational(timeStamp[2], Convert.ToInt32);
Beispiel #18
0
        private static int?GetOrientation(Directory directory)
        {
            try
            {
                return(directory?.GetInt32(ExifDirectoryBase.TagOrientation));
            }
            catch (Exception)
            {
                // ignored
            }

            return(null);
        }
        private void AddQuickTimeMetaCreationDate(MetadataExtractor.Directory quickTimeMeta, Photo photo)
        {
            var tag = quickTimeMeta.Tags.SingleOrDefault(t => t.Name == QuickTimeMetaDataCreationDateTag);

            if (tag != null)
            {
                var tagValue = (StringValue)quickTimeMeta.GetObject(tag.Type);
                if (DateTime.TryParse(tagValue.ToString(), out DateTime creationDate))
                {
                    photo.TakenDate = creationDate;
                }
            }
        }
        private static void AddQuickTimeMetaCreationDate(MetadataExtractor.Directory quickTimeMeta, Photo photo)
        {
            var tag = quickTimeMeta.Tags.SingleOrDefault(t => t.Name == "mdta.com.apple.quicktime.creationdate");

            if (tag != null)
            {
                var tagValue = quickTimeMeta.GetObject(tag.Type) as QuickTimeMetadataValue;
                if (DateTime.TryParse(tagValue.Value, out DateTime creationDate))
                {
                    photo.TakenDate = creationDate;
                }
            }
        }
Beispiel #21
0
        /// <summary>
        ///     For the location element
        ///    [IPTC] City = Diepenveen
        ///    [IPTC] Province/State = Overijssel
        ///    [IPTC] Country/Primary Location Name = Nederland
        /// </summary>
        /// <param name="exifItem"></param>
        /// <param name="iptcName">City, State or Country</param>
        /// <param name="xmpPropertyPath">photoshop:State</param>
        /// <returns></returns>
        private static string GetLocationPlaces(Directory exifItem, string iptcName, string xmpPropertyPath)
        {
            var tCounts = exifItem.Tags.Count(p => p.DirectoryName == "IPTC" && p.Name == iptcName);

            if (tCounts < 1)
            {
                return(GetXmpData(exifItem, xmpPropertyPath));
            }

            var locationCity = exifItem.Tags.FirstOrDefault(
                p => p.DirectoryName == "IPTC" &&
                p.Name == iptcName)?.Description;

            return(locationCity);
        }
Beispiel #22
0
        public static string GetCaptionAbstract(Directory exifItem)
        {
            var tCounts = exifItem.Tags.Count(p => p.DirectoryName == "IPTC" && p.Name == "Caption/Abstract");

            // Xmp readings
            if (tCounts == 0)
            {
                return(GetXmpData(exifItem, "dc:description[1]"));
            }

            var caption = exifItem.Tags.FirstOrDefault(
                p => p.DirectoryName == "IPTC" &&
                p.Name == "Caption/Abstract")?.Description;

            return(caption);
        }
Beispiel #23
0
        private static int?GetHeight(Directory directory)
        {
            int[] tags = { ExifDirectoryBase.TagImageHeight, ExifDirectoryBase.TagExifImageHeight };

            foreach (var tag in tags)
            {
                try
                {
                    return(directory?.GetInt32(tag));
                }
                catch (Exception)
                {
                    // ignored
                }
            }

            return(null);
        }
Beispiel #24
0
        /// <summary>
        /// Read "dc:subject" values from XMP
        /// </summary>
        /// <param name="exifItem">item</param>
        /// <returns></returns>
        private static string GetXmpDataSubject(Directory exifItem)     //
        {
            if (!(exifItem is XmpDirectory xmpDirectory) || xmpDirectory.XmpMeta == null)
            {
                return(string.Empty);
            }

            var tagsList = new HashSet <string>();

            foreach (var property in xmpDirectory.XmpMeta.Properties.Where(p => !string.IsNullOrEmpty(p.Value)))
            {
                if (property.Path.StartsWith("dc:subject["))
                {
                    tagsList.Add(property.Value);
                }
            }
            return(HashSetHelper.HashSetToString(tagsList));
        }
Beispiel #25
0
        private static int GetImageSizeInsideLoop(Directory exifItem, string dirName, string typeName)
        {
            var ratingCountsJpeg =
                exifItem.Tags.Count(p => p.DirectoryName == dirName &&
                                    p.Name.Contains(typeName) && p.Description != "0");

            if (ratingCountsJpeg >= 1)
            {
                var widthTag = exifItem.Tags
                               .FirstOrDefault(p => p.DirectoryName == dirName &&
                                               p.Name.Contains(typeName) && p.Description != "0")
                               ?.Description;
                widthTag = widthTag?.Replace(" pixels", string.Empty);
                int.TryParse(widthTag, out var widthInt);
                return(widthInt >= 1 ? widthInt : 0);        // (widthInt >= 1) return widthInt)
            }
            return(0);
        }
Beispiel #26
0
        public static string GetExifKeywords(Directory exifItem)
        {
            var tCounts = exifItem.Tags.Count(p => p.DirectoryName == "IPTC" && p.Name == "Keywords");

            if (tCounts == 0)
            {
                return(GetXmpDataSubject(exifItem));
            }

            var tags = exifItem.Tags.FirstOrDefault(
                p => p.DirectoryName == "IPTC" &&
                p.Name == "Keywords")?.Description;

            if (!string.IsNullOrWhiteSpace(tags))
            {
                tags = tags.Replace(";", ", ");
            }

            return(tags);
        }
        private void AddGpsMeta(Photo photo, MetadataExtractor.Directory gpsMeta)
        {
            var latitudeTag  = gpsMeta.Tags.SingleOrDefault(t => t.Name == "GPS Latitude");
            var longitudeTag = gpsMeta.Tags.SingleOrDefault(t => t.Name == "GPS Longitude");
            var altitudeTag  = gpsMeta.Tags.SingleOrDefault(t => t.Name == "GPS Altitude");

            if (latitudeTag != null)
            {
                photo.Latitude = GetCoordinateFromDegrees(latitudeTag);
            }

            if (longitudeTag != null)
            {
                photo.Longitude = GetCoordinateFromDegrees(longitudeTag);
            }

            if (altitudeTag != null)
            {
                photo.Altitude = altitudeTag.Description;
            }
        }
Beispiel #28
0
        private static int GetIsoSpeedValue(Directory exifItem)
        {
            var isoSpeedString = exifItem.Tags.FirstOrDefault(p =>
                                                              p.DirectoryName == "Exif SubIFD" && p.Name == "ISO Speed Ratings")?.Description;

            if (string.IsNullOrEmpty(isoSpeedString))
            {
                isoSpeedString = exifItem.Tags.FirstOrDefault(p =>
                                                              p.DirectoryName == "Canon Makernote" && p.Name == "Iso")?.Description;
                if (isoSpeedString == "Auto")
                {
                    // src: https://github.com/exiftool/exiftool/blob/
                    // 6b994069d52302062b9d7a462dc27082c4196d95/lib/Image/ExifTool/Canon.pm#L8882
                    var autoIso = exifItem.Tags.FirstOrDefault(p =>
                                                               p.DirectoryName == "Canon Makernote" && p.Name == "Auto ISO")?.Description;
                    var baseIso = exifItem.Tags.FirstOrDefault(p =>
                                                               p.DirectoryName == "Canon Makernote" && p.Name == "Base ISO")?.Description;
                    if (!string.IsNullOrEmpty(autoIso) && !string.IsNullOrEmpty(baseIso))
                    {
                        int.TryParse(autoIso, NumberStyles.Number, CultureInfo.InvariantCulture, out var autoIsoSpeed);
                        int.TryParse(baseIso, NumberStyles.Number, CultureInfo.InvariantCulture, out var baseIsoSpeed);
                        return(baseIsoSpeed * autoIsoSpeed / 100);
                    }
                }
            }

            // XMP,http://ns.adobe.com/exif/1.0/,exif:ISOSpeedRatings,
            // XMP,,exif:ISOSpeedRatings[1],101
            // XMP,,exif:ISOSpeedRatings[2],101
            var isoSpeedXmp = GetXmpData(exifItem, "exif:ISOSpeedRatings[1]");

            if (string.IsNullOrEmpty(isoSpeedString) && !string.IsNullOrEmpty(isoSpeedXmp))
            {
                isoSpeedString = isoSpeedXmp;
            }

            int.TryParse(isoSpeedString, NumberStyles.Number, CultureInfo.InvariantCulture, out var isoSpeed);
            return(isoSpeed);
        }
Beispiel #29
0
 /// <summary>
 /// Requires exifDirectory is an actual metadata exif directory.
 /// Attempts to return the tags that have 'date' in their names
 /// </summary>
 private static IEnumerable <Tag> ExtractExIfDateTags(MetadataExtractor.Directory exifDirectory)
 {
     return(ExtractDirectoryTags(exifDirectory, n => { return n.Name.ToLower().Contains("date"); }));
 }
 public Tag(int tagType, [NotNull] Directory directory)
 {
     TagType = tagType;
     _directory = directory;
 }
Beispiel #31
0
 private static int?ParseInt(Directory directory, int tag)
 {
     return(directory.TryGetInt32(tag, out var intValue) ? intValue : (int?)null);
 }