diff --git a/Distance/Models/_E_Distance.cs b/Distance/Models/_E_Distance.cs index 8aa0875..6991d3a 100644 --- a/Distance/Models/_E_Distance.cs +++ b/Distance/Models/_E_Distance.cs @@ -223,7 +223,7 @@ public partial class E_Distance throw new NullReferenceException(nameof(locationContainer.Directories)); continue; } - json = Metadata.Models.Stateless.IMetadata.GetFaceEncoding(locationContainer.Directories); + json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(locationContainer.Directories); if (json is null) { if (_DistanceMoveUnableToMatch) diff --git a/Drag-Drop/Drag-Drop.csproj b/Drag-Drop/Drag-Drop.csproj index d73bef4..0914b94 100644 --- a/Drag-Drop/Drag-Drop.csproj +++ b/Drag-Drop/Drag-Drop.csproj @@ -27,8 +27,6 @@ - - diff --git a/Drag-Drop/Form.cs b/Drag-Drop/Form.cs index 202f2b3..8dc2494 100644 --- a/Drag-Drop/Form.cs +++ b/Drag-Drop/Form.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.Configuration; -using Microsoft.WindowsAPICodePack.Shell; using Phares.Shared; using Serilog; using System.Diagnostics; @@ -177,7 +176,9 @@ public partial class Form : System.Windows.Forms.Form int? id; string? message; string checkFile; + TimeSpan timeSpan; DateTime? dateTime; + DateTime?[] dateTimes; FileHolder fileHolder; bool isIgnoreExtension; string checkFileExtension; @@ -188,7 +189,8 @@ public partial class Form : System.Windows.Forms.Form const string jpeg = ".jpeg"; _InnerProgressBar.Visible = true; bool isValidImageFormatExtension; - string? extraLargeBitmapThumbnail; + bool nameWithoutExtensionIsIdFormat; + IReadOnlyList directories; string[] files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly); if (files.All(l => l.EndsWith(".id"))) { @@ -207,7 +209,8 @@ public partial class Form : System.Windows.Forms.Form continue; isValidImageFormatExtension = _Configuration.PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered); isIgnoreExtension = isValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered); - if (IProperty.NameWithoutExtensionIsIdFormat(fileHolder)) + nameWithoutExtensionIsIdFormat = IProperty.NameWithoutExtensionIsIdFormat(fileHolder); + if (!isIgnoreExtension && isValidImageFormatExtension) { if (fileHolder.ExtensionLowered == jpeg) { @@ -215,28 +218,28 @@ public partial class Form : System.Windows.Forms.Form File.Move($"{fileHolder.FullName}.id", Path.Combine(fileHolder.DirectoryName, $"{fileHolder.NameWithoutExtension}{jpg}.id")); File.Move(fileHolder.FullName, Path.Combine(fileHolder.DirectoryName, $"{fileHolder.NameWithoutExtension}{jpg}")); } - continue; + if (nameWithoutExtensionIsIdFormat) + continue; + } + (dateTimes, id, message) = IProperty.Get(fileHolder, isIgnoreExtension, isValidImageFormatExtension); + minimumDateTime = dateTimes.Min(); + if (minimumDateTime is null || !isIgnoreExtension && isValidImageFormatExtension) + { + dateTime = IProperty.GetDateTimeFromName(fileHolder); + if (dateTime is null || minimumDateTime is null) + timeSpan = new TimeSpan(0); + else + timeSpan = new(Math.Abs(minimumDateTime.Value.Ticks - dateTime.Value.Ticks)); } - if (!isIgnoreExtension && isValidImageFormatExtension) - extraLargeBitmapThumbnail = null; else { - extraLargeBitmapThumbnail = SaveExtraLargeBitmapThumbnail(fileHolder); - if (extraLargeBitmapThumbnail is null) - continue; - fileHolder = new(extraLargeBitmapThumbnail); - isValidImageFormatExtension = _Configuration.PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered); - isIgnoreExtension = isValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered); - if (isIgnoreExtension || !isValidImageFormatExtension) - continue; + if (!int.TryParse(Path.GetFileName(fileHolder.DirectoryName)[..4], out int year)) + year = minimumDateTime.Value.Year; + directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file); + dateTime = Metadata.Models.Stateless.Methods.IMetadata.GetMinimumDateTime(dateTimes, year, directories); + timeSpan = new TimeSpan(int.MaxValue); } - if (fileHolder.DirectoryName is null) - continue; - (minimumDateTime, id, message) = IProperty.Get(fileHolder); - if (id is null) - continue; - dateTime = IProperty.GetDateTimeFromName(fileHolder); - if (dateTime is not null && minimumDateTime is not null && new TimeSpan(Math.Abs(minimumDateTime.Value.Ticks - dateTime.Value.Ticks)).TotalMinutes > 2) + if (dateTime is not null && timeSpan.TotalMinutes > 2) { checkFileExtension = fileHolder.ExtensionLowered == jpeg ? jpg : fileHolder.ExtensionLowered; checkFile = Path.Combine(fileHolder.DirectoryName, $"{dateTime.Value:yyyy-MM-dd}.{dateTime.Value.Ticks}{checkFileExtension}"); @@ -252,42 +255,21 @@ public partial class Form : System.Windows.Forms.Form if (File.Exists(checkFile)) continue; File.Move(fileHolder.FullName, checkFile); - File.WriteAllText($"{checkFile}.id", $"{id.Value}{Environment.NewLine}{fileHolder.Name}"); + File.WriteAllText($"{checkFile}.id", $"{checkFile}{Environment.NewLine}{fileHolder.Name}"); continue; } - if (extraLargeBitmapThumbnail is not null) - { - File.Delete(fileHolder.FullName); - fileHolder = new(file); - if (fileHolder.DirectoryName is null) - continue; - } + if (id is null) + continue; checkFileExtension = fileHolder.ExtensionLowered == jpeg ? jpg : fileHolder.ExtensionLowered; checkFile = Path.Combine(fileHolder.DirectoryName, $"{id.Value}{checkFileExtension}"); if (checkFile == fileHolder.FullName || File.Exists(checkFile)) continue; File.Move(fileHolder.FullName, checkFile); - File.WriteAllText($"{checkFile}.id", $"{id.Value}{Environment.NewLine}{fileHolder.Name}"); + File.WriteAllText($"{checkFile}.id", $"{checkFile}{Environment.NewLine}{fileHolder.Name}"); } _InnerProgressBar.Visible = false; } - private string? SaveExtraLargeBitmapThumbnail(FileHolder fileHolder) - { - string? result; - ShellFile shellFile = ShellFile.FromFilePath(fileHolder.FullName); - if (shellFile is null || shellFile.Thumbnail is null || shellFile.Thumbnail.ExtraLargeBitmap.Clone() is not Bitmap bitmap || bitmap.Width == 0) - result = null; - else - { - result = $"{fileHolder.FullName}{_ResizeFileNameExtension}"; - bitmap.Save(result); - bitmap.Dispose(); - shellFile.Dispose(); - } - return result; - } - private List<(string, FaceDistance)> GetFileAndFaceDistanceCollection(string[] files) { // int? id; @@ -308,7 +290,7 @@ public partial class Form : System.Windows.Forms.Form { _ProgressBar.PerformStep(); directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file); - json = Metadata.Models.Stateless.IMetadata.GetFaceEncoding(directories); + json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(directories); if (json is null) break; modelsFaceEncoding = JsonSerializer.Deserialize(json); diff --git a/Face/Models/_D_Face.cs b/Face/Models/_D_Face.cs index 96d2315..976b4a3 100644 --- a/Face/Models/_D_Face.cs +++ b/Face/Models/_D_Face.cs @@ -218,7 +218,7 @@ public class D_Face } } - private List GetFaces(Shared.Models.Methods.IResize resize, string outputResolution, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary outputResolutionToResize, List? locations) + private List GetFaces(string outputResolution, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary outputResolutionToResize, List? locations) { if (_Log is null) throw new NullReferenceException(nameof(_Log)); @@ -237,7 +237,7 @@ public class D_Face } if (unknownImage is not null) { - (int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation) = resize.Get(outputResolution, outputResolutionToResize); + (int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation) = Resize.Models.Stateless.Methods.IResize.Get(outputResolution, outputResolutionToResize); List<(Location Location, FaceRecognitionDotNet.FaceEncoding? FaceEncoding, Dictionary? FaceParts)> collection; FaceRecognition faceRecognition = new(_Configuration.NumberOfJitters.Value, _Configuration.NumberOfTimesToUpsample.Value, _Model, _ModelParameter, _PredictorModel); collection = faceRecognition.GetCollection(unknownImage, locations, includeFaceEncoding: true, includeFaceParts: true); @@ -298,7 +298,7 @@ public class D_Face #pragma warning restore CA1416 - private static List> GetCollection(Shared.Models.Methods.IResize resize, string outputResolution, List> collection, Dictionary outputResolutionToResize, List faces) + private static List> GetCollection(string outputResolution, List> collection, Dictionary outputResolutionToResize, List faces) { List> results = new(); string? json; @@ -307,7 +307,7 @@ public class D_Face Rectangle? rectangle; List skip = new(); OutputResolution? outputResolutionCheck = null; - (int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation) = resize.Get(outputResolution, outputResolutionToResize); + (int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation) = Resize.Models.Stateless.Methods.IResize.Get(outputResolution, outputResolutionToResize); foreach (Shared.Models.Face face in faces) { if (face.Location is null || face.OutputResolution is null) @@ -324,7 +324,7 @@ public class D_Face { if (face.Location is not null && face.OutputResolution is not null) continue; - json = Metadata.Models.Stateless.IMetadata.GetOutputResolution(locationContainer.Directories); + json = Metadata.Models.Stateless.Methods.IMetadata.GetOutputResolution(locationContainer.Directories); if (json is not null) { outputResolutionCheck = JsonSerializer.Deserialize(json); @@ -347,7 +347,7 @@ public class D_Face return results; } - public List GetFaces(Shared.Models.Methods.IResize resize, string outputResolution, string dResultsFullGroupDirectory, List> subFileTuples, List parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary outputResolutionToResize, List>? collection, List? mappingFromPhotoPrismCollection) + public List GetFaces(string outputResolution, string dResultsFullGroupDirectory, List> subFileTuples, List parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary outputResolutionToResize, List>? collection, List? mappingFromPhotoPrismCollection) { List? results; if (string.IsNullOrEmpty(dResultsFullGroupDirectory)) @@ -394,14 +394,14 @@ public class D_Face if (results is null || collection is null) locationContainers = new(); else - locationContainers = GetCollection(resize, outputResolution, collection, outputResolutionToResize, results); + locationContainers = GetCollection(outputResolution, collection, outputResolutionToResize, results); if (mappingFromPhotoPrismCollection is null || results is null) locations = (from l in locationContainers where l is not null select l.Location).ToList(); else locations = Shared.Models.Stateless.Methods.ILocation.GetLocations(mappingFromPhotoPrismCollection, results, locationContainers); if (results is null || (locations is not null && locations.Any())) { - results = GetFaces(resize, outputResolution, property, mappingFromItem, outputResolutionToResize, locations); + results = GetFaces(outputResolution, property, mappingFromItem, outputResolutionToResize, locations); if (!results.Any()) File.Move(mappingFromItem.ResizedFileHolder.FullName, $"{mappingFromItem.ResizedFileHolder.FullName}.err"); else diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index 2bdd207..4373639 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -365,7 +365,7 @@ public partial class DlibDotNet _ = idToMappedFaceFilesWithCollection.TryGetValue(item.Property.Id.Value, out collection); if (!_FileNameToCollection.TryGetValue(mappingFromItem.RelativePath[1..], out mappingFromPhotoPrismCollection)) mappingFromPhotoPrismCollection = null; - faces = _Faces.GetFaces(_Resize, outputResolution, dResultsFullGroupDirectory, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, collection, mappingFromPhotoPrismCollection); + faces = _Faces.GetFaces(outputResolution, dResultsFullGroupDirectory, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, collection, mappingFromPhotoPrismCollection); if (_AppSettings.MaxDegreeOfParallelism < 2) ticks = LogDelta(ticks, nameof(D_Face.GetFaces)); bool anyFacesSaved = _Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, mappingFromItem, facesDirectory, faces); diff --git a/Metadata/Models/B_Metadata.cs b/Metadata/Models/B_Metadata.cs index 26fc853..399dfaa 100644 --- a/Metadata/Models/B_Metadata.cs +++ b/Metadata/Models/B_Metadata.cs @@ -19,8 +19,6 @@ public class B_Metadata private readonly bool _ForceMetadataLastWriteTimeToCreationTime; private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions; - public static string DateTimeFormat() => "ddd MMM dd HH:mm:ss yyyy"; - public B_Metadata(bool forceMetadataLastWriteTimeToCreationTime, bool propertiesChangedForMetadata) { AngleBracketCollection = new List(); diff --git a/Metadata/Models/Stateless/IMetadata.cs b/Metadata/Models/Stateless/IMetadata.cs deleted file mode 100644 index a54d17e..0000000 --- a/Metadata/Models/Stateless/IMetadata.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace View_by_Distance.Metadata.Models.Stateless; - -public interface IMetadata -{ - - string? TestStatic_GetFaceEncoding(IReadOnlyList directories) => - GetFaceEncoding(directories); - static string? GetFaceEncoding(IReadOnlyList directories) => - Metadata.GetFaceEncoding(directories); - - string? TestStatic_GetOutputResolution(IReadOnlyList directories) => - GetOutputResolution(directories); - static string? GetOutputResolution(IReadOnlyList directories) => - Metadata.GetOutputResolution(directories); - -} \ No newline at end of file diff --git a/Metadata/Models/Stateless/Metadata.cs b/Metadata/Models/Stateless/Metadata.cs deleted file mode 100644 index 996305c..0000000 --- a/Metadata/Models/Stateless/Metadata.cs +++ /dev/null @@ -1,50 +0,0 @@ -namespace View_by_Distance.Metadata.Models.Stateless; - -internal class Metadata -{ - - internal static string? GetFaceEncoding(IReadOnlyList directories) - { - string? result; - List results = new(); - const string comment = "Comment: "; - foreach (MetadataExtractor.Directory directory in directories) - { - if (directory.Name != "PNG-tEXt") - continue; - foreach (MetadataExtractor.Tag tag in directory.Tags) - { - if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description)) - continue; - if (!tag.Description.StartsWith(comment)) - continue; - results.Add(tag.Description); - } - } - result = results.Any() ? results[0][comment.Length..] : null; - return result; - } - - internal static string? GetOutputResolution(IReadOnlyList directories) - { - string? result; - List results = new(); - const string artist = "Artist: "; - foreach (MetadataExtractor.Directory directory in directories) - { - if (directory.Name != "PNG-tEXt") - continue; - foreach (MetadataExtractor.Tag tag in directory.Tags) - { - if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description)) - continue; - if (!tag.Description.StartsWith(artist)) - continue; - results.Add(tag.Description); - } - } - result = results.Any() ? results[0][artist.Length..] : null; - return result; - } - -} \ No newline at end of file diff --git a/Metadata/Models/Stateless/Methods/IMetadata.cs b/Metadata/Models/Stateless/Methods/IMetadata.cs new file mode 100644 index 0000000..97baa99 --- /dev/null +++ b/Metadata/Models/Stateless/Methods/IMetadata.cs @@ -0,0 +1,26 @@ +namespace View_by_Distance.Metadata.Models.Stateless.Methods; + +public interface IMetadata +{ + + DateTime TestStatic_GetMinimumDateTime(DateTime?[] dateTimes, int year, IReadOnlyList directories) => + GetMinimumDateTime(dateTimes, year, directories); + static DateTime GetMinimumDateTime(DateTime?[] dateTimes, int year, IReadOnlyList directories) => + Metadata.GetMinimumDateTime(dateTimes, year, directories); + + string? TestStatic_GetFaceEncoding(IReadOnlyList directories) => + GetFaceEncoding(directories); + static string? GetFaceEncoding(IReadOnlyList directories) => + Metadata.GetFaceEncoding(directories); + + string? TestStatic_GetOutputResolution(IReadOnlyList directories) => + GetOutputResolution(directories); + static string? GetOutputResolution(IReadOnlyList directories) => + Metadata.GetOutputResolution(directories); + + int TestStatic_GetOrientation(List> metadataCollection) => + GetOrientation(metadataCollection); + static int GetOrientation(List> metadataCollection) => + Metadata.GetOrientation(metadataCollection); + +} \ No newline at end of file diff --git a/Metadata/Models/Stateless/Methods/Metadata.cs b/Metadata/Models/Stateless/Methods/Metadata.cs new file mode 100644 index 0000000..7d44b2c --- /dev/null +++ b/Metadata/Models/Stateless/Methods/Metadata.cs @@ -0,0 +1,109 @@ +using MetadataExtractor; +using MetadataExtractor.Formats.Avi; +using MetadataExtractor.Formats.Exif; +using MetadataExtractor.Formats.QuickTime; +using View_by_Distance.Shared.Models.Stateless; + +namespace View_by_Distance.Metadata.Models.Stateless.Methods; + +internal class Metadata +{ + + internal static string? GetFaceEncoding(IReadOnlyList directories) + { + string? result; + List results = new(); + const string comment = "Comment: "; + foreach (MetadataExtractor.Directory directory in directories) + { + if (directory.Name != "PNG-tEXt") + continue; + foreach (Tag tag in directory.Tags) + { + if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description)) + continue; + if (!tag.Description.StartsWith(comment)) + continue; + results.Add(tag.Description); + } + } + result = results.Any() ? results[0][comment.Length..] : null; + return result; + } + + internal static string? GetOutputResolution(IReadOnlyList directories) + { + string? result; + List results = new(); + const string artist = "Artist: "; + foreach (MetadataExtractor.Directory directory in directories) + { + if (directory.Name != "PNG-tEXt") + continue; + foreach (Tag tag in directory.Tags) + { + if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description)) + continue; + if (!tag.Description.StartsWith(artist)) + continue; + results.Add(tag.Description); + } + } + result = results.Any() ? results[0][artist.Length..] : null; + return result; + } + + internal static DateTime GetMinimumDateTime(DateTime?[] dateTimes, int year, IReadOnlyList directories) + { + DateTime result; + DateTime dateTime; + List results = (from l in dateTimes where l is not null select l.Value).ToList(); + ExifSubIfdDirectory? exifSubIfdDirectory = directories.OfType().FirstOrDefault(); + if (exifSubIfdDirectory is not null) + { + if (exifSubIfdDirectory.TryGetDateTime(ExifDirectoryBase.TagDateTime, out dateTime)) + results.Add(dateTime); + if (exifSubIfdDirectory.TryGetDateTime(ExifDirectoryBase.TagDateTimeDigitized, out dateTime)) + results.Add(dateTime); + if (exifSubIfdDirectory.TryGetDateTime(ExifDirectoryBase.TagDateTimeOriginal, out dateTime)) + results.Add(dateTime); + } + AviDirectory? aviDirectory = directories.OfType().FirstOrDefault(); + if (aviDirectory is not null) + { + if (aviDirectory.TryGetDateTime(AviDirectory.TagDateTimeOriginal, out dateTime)) + results.Add(dateTime); + } + QuickTimeMovieHeaderDirectory? quickTimeMovieHeaderDirectory = directories.OfType().FirstOrDefault(); + if (quickTimeMovieHeaderDirectory is not null) + { + if (quickTimeMovieHeaderDirectory.TryGetDateTime(QuickTimeMovieHeaderDirectory.TagCreated, out dateTime)) + results.Add(dateTime); + } + QuickTimeTrackHeaderDirectory? quickTimeTrackHeaderDirectory = directories.OfType().FirstOrDefault(); + if (quickTimeTrackHeaderDirectory is not null) + { + if (quickTimeTrackHeaderDirectory.TryGetDateTime(QuickTimeTrackHeaderDirectory.TagCreated, out dateTime)) + results.Add(dateTime); + } + DateTime[] filtered = (from l in results where l.Year >= year select l).ToArray(); + if (!filtered.Any()) + result = results.Min(); + else + result = filtered.Min(); + return result; + } + + internal static int GetOrientation(List> metadataCollection) + { + int result; + const string orientation = nameof(IExif.Tags.Orientation); + List orientations = (from l in metadataCollection where l.Key.Contains(orientation) select l.Value).ToList(); + if (!orientations.Any()) + result = 0; + else if (!int.TryParse(orientations[0], out result)) + result = 0; + return result; + } + +} \ No newline at end of file diff --git a/Resize/Models/Stateless/Methods/IResize.cs b/Resize/Models/Stateless/Methods/IResize.cs new file mode 100644 index 0000000..2db3baa --- /dev/null +++ b/Resize/Models/Stateless/Methods/IResize.cs @@ -0,0 +1,11 @@ +namespace View_by_Distance.Resize.Models.Stateless.Methods; + +public interface IResize +{ + + (int, int, int) TestStatic_Get(string outputResolution, Dictionary outputResolutionToResize) => + Get(outputResolution, outputResolutionToResize); + static (int, int, int) Get(string outputResolution, Dictionary outputResolutionToResize) => + Resize.Get(outputResolution, outputResolutionToResize); + +} \ No newline at end of file diff --git a/Resize/Models/Stateless/Methods/Resize.cs b/Resize/Models/Stateless/Methods/Resize.cs new file mode 100644 index 0000000..3569874 --- /dev/null +++ b/Resize/Models/Stateless/Methods/Resize.cs @@ -0,0 +1,15 @@ +namespace View_by_Distance.Resize.Models.Stateless.Methods; + +internal class Resize +{ + + internal static (int, int, int) Get(string outputResolution, Dictionary outputResolutionToResize) + { + int[] outputResolutionCollection = outputResolutionToResize[outputResolution]; + int outputResolutionWidth = outputResolutionCollection[0]; + int outputResolutionHeight = outputResolutionCollection[1]; + int outputResolutionOrientation = outputResolutionCollection[2]; + return new(outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation); + } + +} \ No newline at end of file diff --git a/Resize/Models/_C_Resize.cs b/Resize/Models/_C_Resize.cs index 64bac97..4a93255 100644 --- a/Resize/Models/_C_Resize.cs +++ b/Resize/Models/_C_Resize.cs @@ -14,7 +14,7 @@ namespace View_by_Distance.Resize.Models; /// // Dictionary /// -public class C_Resize : Shared.Models.Methods.IResize +public class C_Resize { public List AngleBracketCollection { get; } @@ -297,15 +297,6 @@ public class C_Resize : Shared.Models.Methods.IResize throw new Exception(); } - (int, int, int) Shared.Models.Methods.IResize.Get(string outputResolution, Dictionary outputResolutionToResize) - { - int[] outputResolutionCollection = outputResolutionToResize[outputResolution]; - int outputResolutionWidth = outputResolutionCollection[0]; - int outputResolutionHeight = outputResolutionCollection[1]; - int outputResolutionOrientation = outputResolutionCollection[2]; - return new(outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation); - } - public void SaveResizedSubfile(Property.Models.Configuration configuration, string outputResolution, string cResultsFullGroupDirectory, List> subFileTuples, Item item, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary outputResolutionToResize) { if (mappingFromItem.ResizedFileHolder is null) @@ -362,18 +353,6 @@ public class C_Resize : Shared.Models.Methods.IResize return results.ToArray(); } - private static int GetOrientation(List> metadataCollection) - { - int result; - const string orientation = nameof(IExif.Tags.Orientation); - List orientations = (from l in metadataCollection where l.Key.Contains(orientation) select l.Value).ToList(); - if (!orientations.Any()) - result = 0; - else if (!int.TryParse(orientations[0], out result)) - result = 0; - return result; - } - private Dictionary GetImageResizes(Shared.Models.Property property, List> metadataCollection) { Dictionary results = new(); @@ -388,7 +367,7 @@ public class C_Resize : Shared.Models.Methods.IResize if (!string.IsNullOrEmpty(property.Orientation) && int.TryParse(property.Orientation, out int propertyOrientation)) orientation = propertyOrientation; else - orientation = GetOrientation(metadataCollection); + orientation = Metadata.Models.Stateless.Methods.IMetadata.GetOrientation(metadataCollection); checkWidth = property.Width.Value; checkHeight = property.Height.Value; if (!_ValidResolutions.Contains(_Original)) diff --git a/Shared/Models/Methods/IResize.cs b/Shared/Models/Methods/IResize.cs deleted file mode 100644 index 748b039..0000000 --- a/Shared/Models/Methods/IResize.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace View_by_Distance.Shared.Models.Methods; - -public interface IResize -{ - - (int, int, int) Get(string outputResolution, Dictionary outputResolutionToResize); - -} \ No newline at end of file diff --git a/Shared/Models/Stateless/Methods/IProperty.cs b/Shared/Models/Stateless/Methods/IProperty.cs index fe7a680..769d415 100644 --- a/Shared/Models/Stateless/Methods/IProperty.cs +++ b/Shared/Models/Stateless/Methods/IProperty.cs @@ -46,10 +46,10 @@ public interface IProperty static (bool?, string[]) IsWrongYear(string[] segments, string year) => Property.IsWrongYear(segments, year); - (DateTime?, int?, string?) TestStatic_Get(Models.FileHolder fileHolder) => - Get(fileHolder); - static (DateTime?, int?, string?) Get(Models.FileHolder fileHolder) => - Property.Get(fileHolder); + (DateTime?[], int?, string?) TestStatic_Get(Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension) => + Get(fileHolder, isIgnoreExtension, isValidImageFormatExtension); + static (DateTime?[], int?, string?) Get(Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension) => + Property.Get(fileHolder, isIgnoreExtension, isValidImageFormatExtension); DateTime? TestStatic_GetDateTimeFromName(Models.FileHolder fileHolder) => GetDateTimeFromName(fileHolder); diff --git a/Shared/Models/Stateless/Methods/Property.cs b/Shared/Models/Stateless/Methods/Property.cs index 851dbd3..afb2921 100644 --- a/Shared/Models/Stateless/Methods/Property.cs +++ b/Shared/Models/Stateless/Methods/Property.cs @@ -345,89 +345,92 @@ internal abstract class Property #pragma warning disable CA1416 - internal static (DateTime?, int?, string?) Get(Models.FileHolder fileHolder) + internal static (DateTime?[], int?, string?) Get(Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension) { - byte[] bytes; - string value; int? id = null; - DateTime checkDateTime; string? message = null; DateTime? dateTime = null; - PropertyItem? propertyItem; DateTime? gpsDateStamp = null; DateTime? dateTimeOriginal = null; DateTime? dateTimeDigitized = null; - ASCIIEncoding asciiEncoding = new(); - string dateTimeFormat = IProperty.DateTimeFormat(); - try + if (!isIgnoreExtension && isValidImageFormatExtension) { - using Image image = Image.FromFile(fileHolder.FullName); - using Bitmap bitmap = new(image); - Rectangle rectangle = new(0, 0, image.Width, image.Height); - BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat); - IntPtr intPtr = bitmapData.Scan0; - int length = bitmapData.Stride * bitmap.Height; - bytes = new byte[length]; - Marshal.Copy(intPtr, bytes, 0, length); - bitmap.UnlockBits(bitmapData); - id = IProperty.GetDeterministicHashCode(bytes); - if (image.PropertyIdList.Contains((int)IExif.Tags.DateTime)) + try { - propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTime); - if (propertyItem?.Value is not null) + byte[] bytes; + string value; + DateTime checkDateTime; + PropertyItem? propertyItem; + ASCIIEncoding asciiEncoding = new(); + string dateTimeFormat = IProperty.DateTimeFormat(); + using Image image = Image.FromFile(fileHolder.FullName); + using Bitmap bitmap = new(image); + Rectangle rectangle = new(0, 0, image.Width, image.Height); + BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat); + IntPtr intPtr = bitmapData.Scan0; + int length = bitmapData.Stride * bitmap.Height; + bytes = new byte[length]; + Marshal.Copy(intPtr, bytes, 0, length); + bitmap.UnlockBits(bitmapData); + id = IProperty.GetDeterministicHashCode(bytes); + bitmap.Dispose(); + if (image.PropertyIdList.Contains((int)IExif.Tags.DateTime)) { - value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1); - if (value.Length > dateTimeFormat.Length) - value = value[..dateTimeFormat.Length]; - if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime)) - dateTime = checkDateTime; + propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTime); + if (propertyItem?.Value is not null) + { + value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1); + if (value.Length > dateTimeFormat.Length) + value = value[..dateTimeFormat.Length]; + if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime)) + dateTime = checkDateTime; + } } + if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeDigitized)) + { + propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeDigitized); + if (propertyItem?.Value is not null) + { + value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1); + if (value.Length > dateTimeFormat.Length) + value = value[..dateTimeFormat.Length]; + if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime)) + dateTimeDigitized = checkDateTime; + } + } + if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeOriginal)) + { + propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeOriginal); + if (propertyItem?.Value is not null) + { + value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1); + if (value.Length > dateTimeFormat.Length) + value = value[..dateTimeFormat.Length]; + if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime)) + dateTimeOriginal = checkDateTime; + } + } + if (image.PropertyIdList.Contains((int)IExif.Tags.GPSDateStamp)) + { + propertyItem = image.GetPropertyItem((int)IExif.Tags.GPSDateStamp); + if (propertyItem?.Value is not null) + { + value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1); + if (value.Length > dateTimeFormat.Length) + value = value[..dateTimeFormat.Length]; + if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime)) + gpsDateStamp = checkDateTime; + } + } + image.Dispose(); } - if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeDigitized)) + catch (Exception) { - propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeDigitized); - if (propertyItem?.Value is not null) - { - value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1); - if (value.Length > dateTimeFormat.Length) - value = value[..dateTimeFormat.Length]; - if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime)) - dateTimeDigitized = checkDateTime; - } + message = string.Concat(new StackFrame().GetMethod()?.Name, " <", fileHolder.FullName, ">"); } - if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeOriginal)) - { - propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeOriginal); - if (propertyItem?.Value is not null) - { - value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1); - if (value.Length > dateTimeFormat.Length) - value = value[..dateTimeFormat.Length]; - if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime)) - dateTimeOriginal = checkDateTime; - } - } - if (image.PropertyIdList.Contains((int)IExif.Tags.GPSDateStamp)) - { - propertyItem = image.GetPropertyItem((int)IExif.Tags.GPSDateStamp); - if (propertyItem?.Value is not null) - { - value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1); - if (value.Length > dateTimeFormat.Length) - value = value[..dateTimeFormat.Length]; - if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime)) - gpsDateStamp = checkDateTime; - } - } - bitmap.Dispose(); - image.Dispose(); - } - catch (Exception) - { - message = string.Concat(new StackFrame().GetMethod()?.Name, " <", fileHolder.FullName, ">"); } DateTime?[] dateTimes = new DateTime?[] { fileHolder.LastWriteTime, fileHolder.CreationTime, dateTime, dateTimeDigitized, dateTimeOriginal, gpsDateStamp }; - return new(dateTimes.Min(), id, message); + return new(dateTimes, id, message); } #pragma warning restore CA1416