Removed SaveExtraLargeBitmapThumbnail
This commit is contained in:
		| @ -223,7 +223,7 @@ public partial class E_Distance | |||||||
|                     throw new NullReferenceException(nameof(locationContainer.Directories)); |                     throw new NullReferenceException(nameof(locationContainer.Directories)); | ||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|             json = Metadata.Models.Stateless.IMetadata.GetFaceEncoding(locationContainer.Directories); |             json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(locationContainer.Directories); | ||||||
|             if (json is null) |             if (json is null) | ||||||
|             { |             { | ||||||
|                 if (_DistanceMoveUnableToMatch) |                 if (_DistanceMoveUnableToMatch) | ||||||
|  | |||||||
| @ -27,8 +27,6 @@ | |||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <PackageReference Include="Humanizer.Core" Version="2.14.1" /> |     <PackageReference Include="Humanizer.Core" Version="2.14.1" /> | ||||||
|     <PackageReference Include="Microsoft-WindowsAPICodePack-Core" Version="1.1.4" /> |  | ||||||
|     <PackageReference Include="Microsoft-WindowsAPICodePack-Shell" Version="1.1.4" /> |  | ||||||
|     <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" /> |     <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" /> | ||||||
|     <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="7.0.0" /> |     <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="7.0.0" /> | ||||||
|     <PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" /> |     <PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" /> | ||||||
|  | |||||||
| @ -1,5 +1,4 @@ | |||||||
| using Microsoft.Extensions.Configuration; | using Microsoft.Extensions.Configuration; | ||||||
| using Microsoft.WindowsAPICodePack.Shell; |  | ||||||
| using Phares.Shared; | using Phares.Shared; | ||||||
| using Serilog; | using Serilog; | ||||||
| using System.Diagnostics; | using System.Diagnostics; | ||||||
| @ -177,7 +176,9 @@ public partial class Form : System.Windows.Forms.Form | |||||||
|         int? id; |         int? id; | ||||||
|         string? message; |         string? message; | ||||||
|         string checkFile; |         string checkFile; | ||||||
|  |         TimeSpan timeSpan; | ||||||
|         DateTime? dateTime; |         DateTime? dateTime; | ||||||
|  |         DateTime?[] dateTimes; | ||||||
|         FileHolder fileHolder; |         FileHolder fileHolder; | ||||||
|         bool isIgnoreExtension; |         bool isIgnoreExtension; | ||||||
|         string checkFileExtension; |         string checkFileExtension; | ||||||
| @ -188,7 +189,8 @@ public partial class Form : System.Windows.Forms.Form | |||||||
|         const string jpeg = ".jpeg"; |         const string jpeg = ".jpeg"; | ||||||
|         _InnerProgressBar.Visible = true; |         _InnerProgressBar.Visible = true; | ||||||
|         bool isValidImageFormatExtension; |         bool isValidImageFormatExtension; | ||||||
|         string? extraLargeBitmapThumbnail; |         bool nameWithoutExtensionIsIdFormat; | ||||||
|  |         IReadOnlyList<MetadataExtractor.Directory> directories; | ||||||
|         string[] files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly); |         string[] files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly); | ||||||
|         if (files.All(l => l.EndsWith(".id"))) |         if (files.All(l => l.EndsWith(".id"))) | ||||||
|         { |         { | ||||||
| @ -207,7 +209,8 @@ public partial class Form : System.Windows.Forms.Form | |||||||
|                 continue; |                 continue; | ||||||
|             isValidImageFormatExtension = _Configuration.PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered); |             isValidImageFormatExtension = _Configuration.PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered); | ||||||
|             isIgnoreExtension = isValidImageFormatExtension && _Configuration.IgnoreExtensions.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) |                 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}.id", Path.Combine(fileHolder.DirectoryName, $"{fileHolder.NameWithoutExtension}{jpg}.id")); | ||||||
|                     File.Move(fileHolder.FullName, Path.Combine(fileHolder.DirectoryName, $"{fileHolder.NameWithoutExtension}{jpg}")); |                     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 |             else | ||||||
|             { |             { | ||||||
|                 extraLargeBitmapThumbnail = SaveExtraLargeBitmapThumbnail(fileHolder); |                 if (!int.TryParse(Path.GetFileName(fileHolder.DirectoryName)[..4], out int year)) | ||||||
|                 if (extraLargeBitmapThumbnail is null) |                     year = minimumDateTime.Value.Year; | ||||||
|                     continue; |                 directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file); | ||||||
|                 fileHolder = new(extraLargeBitmapThumbnail); |                 dateTime = Metadata.Models.Stateless.Methods.IMetadata.GetMinimumDateTime(dateTimes, year, directories); | ||||||
|                 isValidImageFormatExtension = _Configuration.PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered); |                 timeSpan = new TimeSpan(int.MaxValue); | ||||||
|                 isIgnoreExtension = isValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered); |  | ||||||
|                 if (isIgnoreExtension || !isValidImageFormatExtension) |  | ||||||
|                     continue; |  | ||||||
|             } |             } | ||||||
|             if (fileHolder.DirectoryName is null) |             if (dateTime is not null && timeSpan.TotalMinutes > 2) | ||||||
|                 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) |  | ||||||
|             { |             { | ||||||
|                 checkFileExtension = fileHolder.ExtensionLowered == jpeg ? jpg : fileHolder.ExtensionLowered; |                 checkFileExtension = fileHolder.ExtensionLowered == jpeg ? jpg : fileHolder.ExtensionLowered; | ||||||
|                 checkFile = Path.Combine(fileHolder.DirectoryName, $"{dateTime.Value:yyyy-MM-dd}.{dateTime.Value.Ticks}{checkFileExtension}"); |                 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)) |                 if (File.Exists(checkFile)) | ||||||
|                     continue; |                     continue; | ||||||
|                 File.Move(fileHolder.FullName, checkFile); |                 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; |                 continue; | ||||||
|             } |             } | ||||||
|             if (extraLargeBitmapThumbnail is not null) |             if (id is null) | ||||||
|             { |                 continue; | ||||||
|                 File.Delete(fileHolder.FullName); |  | ||||||
|                 fileHolder = new(file); |  | ||||||
|                 if (fileHolder.DirectoryName is null) |  | ||||||
|                     continue; |  | ||||||
|             } |  | ||||||
|             checkFileExtension = fileHolder.ExtensionLowered == jpeg ? jpg : fileHolder.ExtensionLowered; |             checkFileExtension = fileHolder.ExtensionLowered == jpeg ? jpg : fileHolder.ExtensionLowered; | ||||||
|             checkFile = Path.Combine(fileHolder.DirectoryName, $"{id.Value}{checkFileExtension}"); |             checkFile = Path.Combine(fileHolder.DirectoryName, $"{id.Value}{checkFileExtension}"); | ||||||
|             if (checkFile == fileHolder.FullName || File.Exists(checkFile)) |             if (checkFile == fileHolder.FullName || File.Exists(checkFile)) | ||||||
|                 continue; |                 continue; | ||||||
|             File.Move(fileHolder.FullName, checkFile); |             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; |         _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) |     private List<(string, FaceDistance)> GetFileAndFaceDistanceCollection(string[] files) | ||||||
|     { |     { | ||||||
|         // int? id; |         // int? id; | ||||||
| @ -308,7 +290,7 @@ public partial class Form : System.Windows.Forms.Form | |||||||
|         { |         { | ||||||
|             _ProgressBar.PerformStep(); |             _ProgressBar.PerformStep(); | ||||||
|             directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file); |             directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file); | ||||||
|             json = Metadata.Models.Stateless.IMetadata.GetFaceEncoding(directories); |             json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(directories); | ||||||
|             if (json is null) |             if (json is null) | ||||||
|                 break; |                 break; | ||||||
|             modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json); |             modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json); | ||||||
|  | |||||||
| @ -218,7 +218,7 @@ public class D_Face | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private List<Shared.Models.Face> GetFaces(Shared.Models.Methods.IResize resize, string outputResolution, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, List<Location>? locations) |     private List<Shared.Models.Face> GetFaces(string outputResolution, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, List<Location>? locations) | ||||||
|     { |     { | ||||||
|         if (_Log is null) |         if (_Log is null) | ||||||
|             throw new NullReferenceException(nameof(_Log)); |             throw new NullReferenceException(nameof(_Log)); | ||||||
| @ -237,7 +237,7 @@ public class D_Face | |||||||
|         } |         } | ||||||
|         if (unknownImage is not null) |         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<FacePart, FacePoint[]>? FaceParts)> collection; |             List<(Location Location, FaceRecognitionDotNet.FaceEncoding? FaceEncoding, Dictionary<FacePart, FacePoint[]>? FaceParts)> collection; | ||||||
|             FaceRecognition faceRecognition = new(_Configuration.NumberOfJitters.Value, _Configuration.NumberOfTimesToUpsample.Value, _Model, _ModelParameter, _PredictorModel); |             FaceRecognition faceRecognition = new(_Configuration.NumberOfJitters.Value, _Configuration.NumberOfTimesToUpsample.Value, _Model, _ModelParameter, _PredictorModel); | ||||||
|             collection = faceRecognition.GetCollection(unknownImage, locations, includeFaceEncoding: true, includeFaceParts: true); |             collection = faceRecognition.GetCollection(unknownImage, locations, includeFaceEncoding: true, includeFaceParts: true); | ||||||
| @ -298,7 +298,7 @@ public class D_Face | |||||||
|  |  | ||||||
| #pragma warning restore CA1416 | #pragma warning restore CA1416 | ||||||
|  |  | ||||||
|     private static List<LocationContainer<MetadataExtractor.Directory>> GetCollection(Shared.Models.Methods.IResize resize, string outputResolution, List<LocationContainer<MetadataExtractor.Directory>> collection, Dictionary<string, int[]> outputResolutionToResize, List<Shared.Models.Face> faces) |     private static List<LocationContainer<MetadataExtractor.Directory>> GetCollection(string outputResolution, List<LocationContainer<MetadataExtractor.Directory>> collection, Dictionary<string, int[]> outputResolutionToResize, List<Shared.Models.Face> faces) | ||||||
|     { |     { | ||||||
|         List<LocationContainer<MetadataExtractor.Directory>> results = new(); |         List<LocationContainer<MetadataExtractor.Directory>> results = new(); | ||||||
|         string? json; |         string? json; | ||||||
| @ -307,7 +307,7 @@ public class D_Face | |||||||
|         Rectangle? rectangle; |         Rectangle? rectangle; | ||||||
|         List<int> skip = new(); |         List<int> skip = new(); | ||||||
|         OutputResolution? outputResolutionCheck = null; |         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) |         foreach (Shared.Models.Face face in faces) | ||||||
|         { |         { | ||||||
|             if (face.Location is null || face.OutputResolution is null) |             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) |                 if (face.Location is not null && face.OutputResolution is not null) | ||||||
|                     continue; |                     continue; | ||||||
|                 json = Metadata.Models.Stateless.IMetadata.GetOutputResolution(locationContainer.Directories); |                 json = Metadata.Models.Stateless.Methods.IMetadata.GetOutputResolution(locationContainer.Directories); | ||||||
|                 if (json is not null) |                 if (json is not null) | ||||||
|                 { |                 { | ||||||
|                     outputResolutionCheck = JsonSerializer.Deserialize<OutputResolution>(json); |                     outputResolutionCheck = JsonSerializer.Deserialize<OutputResolution>(json); | ||||||
| @ -347,7 +347,7 @@ public class D_Face | |||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public List<Shared.Models.Face> GetFaces(Shared.Models.Methods.IResize resize, string outputResolution, string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, List<LocationContainer<MetadataExtractor.Directory>>? collection, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection) |     public List<Shared.Models.Face> GetFaces(string outputResolution, string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, List<LocationContainer<MetadataExtractor.Directory>>? collection, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection) | ||||||
|     { |     { | ||||||
|         List<Shared.Models.Face>? results; |         List<Shared.Models.Face>? results; | ||||||
|         if (string.IsNullOrEmpty(dResultsFullGroupDirectory)) |         if (string.IsNullOrEmpty(dResultsFullGroupDirectory)) | ||||||
| @ -394,14 +394,14 @@ public class D_Face | |||||||
|         if (results is null || collection is null) |         if (results is null || collection is null) | ||||||
|             locationContainers = new(); |             locationContainers = new(); | ||||||
|         else |         else | ||||||
|             locationContainers = GetCollection(resize, outputResolution, collection, outputResolutionToResize, results); |             locationContainers = GetCollection(outputResolution, collection, outputResolutionToResize, results); | ||||||
|         if (mappingFromPhotoPrismCollection is null || results is null) |         if (mappingFromPhotoPrismCollection is null || results is null) | ||||||
|             locations = (from l in locationContainers where l is not null select l.Location).ToList(); |             locations = (from l in locationContainers where l is not null select l.Location).ToList(); | ||||||
|         else |         else | ||||||
|             locations = Shared.Models.Stateless.Methods.ILocation.GetLocations(mappingFromPhotoPrismCollection, results, locationContainers); |             locations = Shared.Models.Stateless.Methods.ILocation.GetLocations(mappingFromPhotoPrismCollection, results, locationContainers); | ||||||
|         if (results is null || (locations is not null && locations.Any())) |         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()) |             if (!results.Any()) | ||||||
|                 File.Move(mappingFromItem.ResizedFileHolder.FullName, $"{mappingFromItem.ResizedFileHolder.FullName}.err"); |                 File.Move(mappingFromItem.ResizedFileHolder.FullName, $"{mappingFromItem.ResizedFileHolder.FullName}.err"); | ||||||
|             else |             else | ||||||
|  | |||||||
| @ -365,7 +365,7 @@ public partial class DlibDotNet | |||||||
|                 _ = idToMappedFaceFilesWithCollection.TryGetValue(item.Property.Id.Value, out collection); |                 _ = idToMappedFaceFilesWithCollection.TryGetValue(item.Property.Id.Value, out collection); | ||||||
|             if (!_FileNameToCollection.TryGetValue(mappingFromItem.RelativePath[1..], out mappingFromPhotoPrismCollection)) |             if (!_FileNameToCollection.TryGetValue(mappingFromItem.RelativePath[1..], out mappingFromPhotoPrismCollection)) | ||||||
|                 mappingFromPhotoPrismCollection = null; |                 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) |             if (_AppSettings.MaxDegreeOfParallelism < 2) | ||||||
|                 ticks = LogDelta(ticks, nameof(D_Face.GetFaces)); |                 ticks = LogDelta(ticks, nameof(D_Face.GetFaces)); | ||||||
|             bool anyFacesSaved = _Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, mappingFromItem, facesDirectory, faces); |             bool anyFacesSaved = _Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, mappingFromItem, facesDirectory, faces); | ||||||
|  | |||||||
| @ -19,8 +19,6 @@ public class B_Metadata | |||||||
|     private readonly bool _ForceMetadataLastWriteTimeToCreationTime; |     private readonly bool _ForceMetadataLastWriteTimeToCreationTime; | ||||||
|     private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions; |     private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions; | ||||||
|  |  | ||||||
|     public static string DateTimeFormat() => "ddd MMM dd HH:mm:ss yyyy"; |  | ||||||
|  |  | ||||||
|     public B_Metadata(bool forceMetadataLastWriteTimeToCreationTime, bool propertiesChangedForMetadata) |     public B_Metadata(bool forceMetadataLastWriteTimeToCreationTime, bool propertiesChangedForMetadata) | ||||||
|     { |     { | ||||||
|         AngleBracketCollection = new List<string>(); |         AngleBracketCollection = new List<string>(); | ||||||
|  | |||||||
| @ -1,16 +0,0 @@ | |||||||
| namespace View_by_Distance.Metadata.Models.Stateless; |  | ||||||
|  |  | ||||||
| public interface IMetadata |  | ||||||
| { |  | ||||||
|  |  | ||||||
|     string? TestStatic_GetFaceEncoding(IReadOnlyList<MetadataExtractor.Directory> directories) => |  | ||||||
|         GetFaceEncoding(directories); |  | ||||||
|     static string? GetFaceEncoding(IReadOnlyList<MetadataExtractor.Directory> directories) => |  | ||||||
|         Metadata.GetFaceEncoding(directories); |  | ||||||
|  |  | ||||||
|     string? TestStatic_GetOutputResolution(IReadOnlyList<MetadataExtractor.Directory> directories) => |  | ||||||
|         GetOutputResolution(directories); |  | ||||||
|     static string? GetOutputResolution(IReadOnlyList<MetadataExtractor.Directory> directories) => |  | ||||||
|         Metadata.GetOutputResolution(directories); |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @ -1,50 +0,0 @@ | |||||||
| namespace View_by_Distance.Metadata.Models.Stateless; |  | ||||||
|  |  | ||||||
| internal class Metadata |  | ||||||
| { |  | ||||||
|  |  | ||||||
|     internal static string? GetFaceEncoding(IReadOnlyList<MetadataExtractor.Directory> directories) |  | ||||||
|     { |  | ||||||
|         string? result; |  | ||||||
|         List<string> 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<MetadataExtractor.Directory> directories) |  | ||||||
|     { |  | ||||||
|         string? result; |  | ||||||
|         List<string> 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; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
							
								
								
									
										26
									
								
								Metadata/Models/Stateless/Methods/IMetadata.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								Metadata/Models/Stateless/Methods/IMetadata.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | namespace View_by_Distance.Metadata.Models.Stateless.Methods; | ||||||
|  |  | ||||||
|  | public interface IMetadata | ||||||
|  | { | ||||||
|  |  | ||||||
|  |     DateTime TestStatic_GetMinimumDateTime(DateTime?[] dateTimes, int year, IReadOnlyList<MetadataExtractor.Directory> directories) => | ||||||
|  |         GetMinimumDateTime(dateTimes, year, directories); | ||||||
|  |     static DateTime GetMinimumDateTime(DateTime?[] dateTimes, int year, IReadOnlyList<MetadataExtractor.Directory> directories) => | ||||||
|  |         Metadata.GetMinimumDateTime(dateTimes, year, directories); | ||||||
|  |  | ||||||
|  |     string? TestStatic_GetFaceEncoding(IReadOnlyList<MetadataExtractor.Directory> directories) => | ||||||
|  |         GetFaceEncoding(directories); | ||||||
|  |     static string? GetFaceEncoding(IReadOnlyList<MetadataExtractor.Directory> directories) => | ||||||
|  |         Metadata.GetFaceEncoding(directories); | ||||||
|  |  | ||||||
|  |     string? TestStatic_GetOutputResolution(IReadOnlyList<MetadataExtractor.Directory> directories) => | ||||||
|  |         GetOutputResolution(directories); | ||||||
|  |     static string? GetOutputResolution(IReadOnlyList<MetadataExtractor.Directory> directories) => | ||||||
|  |         Metadata.GetOutputResolution(directories); | ||||||
|  |  | ||||||
|  |     int TestStatic_GetOrientation(List<KeyValuePair<string, string>> metadataCollection) => | ||||||
|  |         GetOrientation(metadataCollection); | ||||||
|  |     static int GetOrientation(List<KeyValuePair<string, string>> metadataCollection) => | ||||||
|  |         Metadata.GetOrientation(metadataCollection); | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										109
									
								
								Metadata/Models/Stateless/Methods/Metadata.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								Metadata/Models/Stateless/Methods/Metadata.cs
									
									
									
									
									
										Normal file
									
								
							| @ -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<MetadataExtractor.Directory> directories) | ||||||
|  |     { | ||||||
|  |         string? result; | ||||||
|  |         List<string> 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<MetadataExtractor.Directory> directories) | ||||||
|  |     { | ||||||
|  |         string? result; | ||||||
|  |         List<string> 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<MetadataExtractor.Directory> directories) | ||||||
|  |     { | ||||||
|  |         DateTime result; | ||||||
|  |         DateTime dateTime; | ||||||
|  |         List<DateTime> results = (from l in dateTimes where l is not null select l.Value).ToList(); | ||||||
|  |         ExifSubIfdDirectory? exifSubIfdDirectory = directories.OfType<ExifSubIfdDirectory>().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<AviDirectory>().FirstOrDefault(); | ||||||
|  |         if (aviDirectory is not null) | ||||||
|  |         { | ||||||
|  |             if (aviDirectory.TryGetDateTime(AviDirectory.TagDateTimeOriginal, out dateTime)) | ||||||
|  |                 results.Add(dateTime); | ||||||
|  |         } | ||||||
|  |         QuickTimeMovieHeaderDirectory? quickTimeMovieHeaderDirectory = directories.OfType<QuickTimeMovieHeaderDirectory>().FirstOrDefault(); | ||||||
|  |         if (quickTimeMovieHeaderDirectory is not null) | ||||||
|  |         { | ||||||
|  |             if (quickTimeMovieHeaderDirectory.TryGetDateTime(QuickTimeMovieHeaderDirectory.TagCreated, out dateTime)) | ||||||
|  |                 results.Add(dateTime); | ||||||
|  |         } | ||||||
|  |         QuickTimeTrackHeaderDirectory? quickTimeTrackHeaderDirectory = directories.OfType<QuickTimeTrackHeaderDirectory>().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<KeyValuePair<string, string>> metadataCollection) | ||||||
|  |     { | ||||||
|  |         int result; | ||||||
|  |         const string orientation = nameof(IExif.Tags.Orientation); | ||||||
|  |         List<string> 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; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								Resize/Models/Stateless/Methods/IResize.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Resize/Models/Stateless/Methods/IResize.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | namespace View_by_Distance.Resize.Models.Stateless.Methods; | ||||||
|  |  | ||||||
|  | public interface IResize | ||||||
|  | { | ||||||
|  |  | ||||||
|  |     (int, int, int) TestStatic_Get(string outputResolution, Dictionary<string, int[]> outputResolutionToResize) => | ||||||
|  |         Get(outputResolution, outputResolutionToResize); | ||||||
|  |     static (int, int, int) Get(string outputResolution, Dictionary<string, int[]> outputResolutionToResize) => | ||||||
|  |         Resize.Get(outputResolution, outputResolutionToResize); | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								Resize/Models/Stateless/Methods/Resize.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								Resize/Models/Stateless/Methods/Resize.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | namespace View_by_Distance.Resize.Models.Stateless.Methods; | ||||||
|  |  | ||||||
|  | internal class Resize | ||||||
|  | { | ||||||
|  |  | ||||||
|  |     internal static (int, int, int) Get(string outputResolution, Dictionary<string, int[]> outputResolutionToResize) | ||||||
|  |     { | ||||||
|  |         int[] outputResolutionCollection = outputResolutionToResize[outputResolution]; | ||||||
|  |         int outputResolutionWidth = outputResolutionCollection[0]; | ||||||
|  |         int outputResolutionHeight = outputResolutionCollection[1]; | ||||||
|  |         int outputResolutionOrientation = outputResolutionCollection[2]; | ||||||
|  |         return new(outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -14,7 +14,7 @@ namespace View_by_Distance.Resize.Models; | |||||||
| /// <summary> | /// <summary> | ||||||
| // Dictionary<string, int[]> | // Dictionary<string, int[]> | ||||||
| /// </summary> | /// </summary> | ||||||
| public class C_Resize : Shared.Models.Methods.IResize | public class C_Resize | ||||||
| { | { | ||||||
|  |  | ||||||
|     public List<string> AngleBracketCollection { get; } |     public List<string> AngleBracketCollection { get; } | ||||||
| @ -297,15 +297,6 @@ public class C_Resize : Shared.Models.Methods.IResize | |||||||
|             throw new Exception(); |             throw new Exception(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     (int, int, int) Shared.Models.Methods.IResize.Get(string outputResolution, Dictionary<string, int[]> 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<Tuple<string, DateTime>> subFileTuples, Item item, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize) |     public void SaveResizedSubfile(Property.Models.Configuration configuration, string outputResolution, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, Item item, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize) | ||||||
|     { |     { | ||||||
|         if (mappingFromItem.ResizedFileHolder is null) |         if (mappingFromItem.ResizedFileHolder is null) | ||||||
| @ -362,18 +353,6 @@ public class C_Resize : Shared.Models.Methods.IResize | |||||||
|         return results.ToArray(); |         return results.ToArray(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static int GetOrientation(List<KeyValuePair<string, string>> metadataCollection) |  | ||||||
|     { |  | ||||||
|         int result; |  | ||||||
|         const string orientation = nameof(IExif.Tags.Orientation); |  | ||||||
|         List<string> 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<string, int[]> GetImageResizes(Shared.Models.Property property, List<KeyValuePair<string, string>> metadataCollection) |     private Dictionary<string, int[]> GetImageResizes(Shared.Models.Property property, List<KeyValuePair<string, string>> metadataCollection) | ||||||
|     { |     { | ||||||
|         Dictionary<string, int[]> results = new(); |         Dictionary<string, int[]> 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)) |         if (!string.IsNullOrEmpty(property.Orientation) && int.TryParse(property.Orientation, out int propertyOrientation)) | ||||||
|             orientation = propertyOrientation; |             orientation = propertyOrientation; | ||||||
|         else |         else | ||||||
|             orientation = GetOrientation(metadataCollection); |             orientation = Metadata.Models.Stateless.Methods.IMetadata.GetOrientation(metadataCollection); | ||||||
|         checkWidth = property.Width.Value; |         checkWidth = property.Width.Value; | ||||||
|         checkHeight = property.Height.Value; |         checkHeight = property.Height.Value; | ||||||
|         if (!_ValidResolutions.Contains(_Original)) |         if (!_ValidResolutions.Contains(_Original)) | ||||||
|  | |||||||
| @ -1,8 +0,0 @@ | |||||||
| namespace View_by_Distance.Shared.Models.Methods; |  | ||||||
|  |  | ||||||
| public interface IResize |  | ||||||
| { |  | ||||||
|  |  | ||||||
|     (int, int, int) Get(string outputResolution, Dictionary<string, int[]> outputResolutionToResize); |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @ -46,10 +46,10 @@ public interface IProperty | |||||||
|     static (bool?, string[]) IsWrongYear(string[] segments, string year) => |     static (bool?, string[]) IsWrongYear(string[] segments, string year) => | ||||||
|         Property.IsWrongYear(segments, year); |         Property.IsWrongYear(segments, year); | ||||||
|  |  | ||||||
|     (DateTime?, int?, string?) TestStatic_Get(Models.FileHolder fileHolder) => |     (DateTime?[], int?, string?) TestStatic_Get(Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension) => | ||||||
|         Get(fileHolder); |         Get(fileHolder, isIgnoreExtension, isValidImageFormatExtension); | ||||||
|     static (DateTime?, int?, string?) Get(Models.FileHolder fileHolder) => |     static (DateTime?[], int?, string?) Get(Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension) => | ||||||
|         Property.Get(fileHolder); |         Property.Get(fileHolder, isIgnoreExtension, isValidImageFormatExtension); | ||||||
|  |  | ||||||
|     DateTime? TestStatic_GetDateTimeFromName(Models.FileHolder fileHolder) => |     DateTime? TestStatic_GetDateTimeFromName(Models.FileHolder fileHolder) => | ||||||
|         GetDateTimeFromName(fileHolder); |         GetDateTimeFromName(fileHolder); | ||||||
|  | |||||||
| @ -345,89 +345,92 @@ internal abstract class Property | |||||||
|  |  | ||||||
| #pragma warning disable CA1416 | #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; |         int? id = null; | ||||||
|         DateTime checkDateTime; |  | ||||||
|         string? message = null; |         string? message = null; | ||||||
|         DateTime? dateTime = null; |         DateTime? dateTime = null; | ||||||
|         PropertyItem? propertyItem; |  | ||||||
|         DateTime? gpsDateStamp = null; |         DateTime? gpsDateStamp = null; | ||||||
|         DateTime? dateTimeOriginal = null; |         DateTime? dateTimeOriginal = null; | ||||||
|         DateTime? dateTimeDigitized = null; |         DateTime? dateTimeDigitized = null; | ||||||
|         ASCIIEncoding asciiEncoding = new(); |         if (!isIgnoreExtension && isValidImageFormatExtension) | ||||||
|         string dateTimeFormat = IProperty.DateTimeFormat(); |  | ||||||
|         try |  | ||||||
|         { |         { | ||||||
|             using Image image = Image.FromFile(fileHolder.FullName); |             try | ||||||
|             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)) |  | ||||||
|             { |             { | ||||||
|                 propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTime); |                 byte[] bytes; | ||||||
|                 if (propertyItem?.Value is not null) |                 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); |                     propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTime); | ||||||
|                     if (value.Length > dateTimeFormat.Length) |                     if (propertyItem?.Value is not null) | ||||||
|                         value = value[..dateTimeFormat.Length]; |                     { | ||||||
|                     if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime)) |                         value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1); | ||||||
|                         dateTime = checkDateTime; |                         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); |                 message = string.Concat(new StackFrame().GetMethod()?.Name, " <", fileHolder.FullName, ">"); | ||||||
|                 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; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             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 }; |         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 | #pragma warning restore CA1416 | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user