diff --git a/.txt b/.txt index a0b1096..50f3116 100644 --- a/.txt +++ b/.txt @@ -1,5 +1,8 @@ mklink /J "L:\Git\View-by-Distance-MKLink-Console\Compare" "L:\Git\View-by-Distance\Compare" mklink /J "L:\Git\View-by-Distance-MKLink-Console\Date-Group" "L:\Git\View-by-Distance\Date-Group" + mklink /J "L:\Git\View-by-Distance-MKLink-Console\Distance" "L:\Git\View-by-Distance\Distance" + mklink /J "L:\Git\View-by-Distance-MKLink-Console\Face" "L:\Git\View-by-Distance\Face" + mklink /J "L:\Git\View-by-Distance-MKLink-Console\FaceParts" "L:\Git\View-by-Distance\FaceParts" mklink /J "L:\Git\View-by-Distance-MKLink-Console\Instance" "L:\Git\View-by-Distance\Instance" mklink /J "L:\Git\View-by-Distance-MKLink-Console\Metadata" "L:\Git\View-by-Distance\Metadata" mklink /J "L:\Git\View-by-Distance-MKLink-Console\Not-Copy-Copy" "L:\Git\View-by-Distance\Not-Copy-Copy" diff --git a/Compare/Compare.cs b/Compare/Compare.cs index a6130f7..cea7457 100644 --- a/Compare/Compare.cs +++ b/Compare/Compare.cs @@ -55,9 +55,10 @@ public class Compare string outputExtension = ".jpg"; PredictorModel? predictorModel = null; string eResultsFullGroupDirectory = string.Empty; + string a2PeopleSingletonDirectory = string.Empty; Map.Models.Configuration? mapConfiguration = null; Shared.Models.PersonContainer[] personContainers = Array.Empty(); - Map.Models.MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, propertyConfiguration, mapConfiguration, outputExtension, ticks, personContainers, eResultsFullGroupDirectory); + Map.Models.MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, propertyConfiguration, mapConfiguration, outputExtension, ticks, personContainers, a2PeopleSingletonDirectory, eResultsFullGroupDirectory); A_Property propertyLogic = GetPropertyLogic(reverse, model, outputExtension, predictorModel, mapLogic); foreach (string spelling in configuration.Spelling) { diff --git a/Compare/appsettings.Development.json b/Compare/appsettings.Development.json index e3b9b6d..a64adfd 100644 --- a/Compare/appsettings.Development.json +++ b/Compare/appsettings.Development.json @@ -79,7 +79,7 @@ "/zzz Phares Slides/Slides 2015-06-10/Magazine 01" ], "Configuration": { - "DateGroup": "2022-09-15", + "DateGroup": "2022-09-22", "DiffPropertyDirectory": "", "FileNameDirectorySeparator": ".Z.", "ForcePropertyLastWriteTimeToCreationTime": false, @@ -87,20 +87,20 @@ "Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]", "PopulatePropertyId": true, "PropertiesChangedForProperty": false, - "RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-09-15 - 7390c13 - III", + "RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-09-22 - fb1c68e - III", "WriteBitmapDataBytes": false, "IgnoreExtensions": [ ".gif", ".GIF" ], "PropertyContentCollectionFiles": [ - "/Images 2022-09-15 - 7390c13 - III - Results/A) Property/2022-09-15/[()]/637869381676042455.json", - "/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869733124119330.json", - "/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869734240700328.json", - "/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869734970730630.json", - "/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869743752078399.json", - "/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-09-15/[()]/637869744751177715.json", - "/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-09-15/[()]/637869745134124462.json" + "/Images 2022-09-22 - fb1c68e - III - Results/A) Property/2022-09-22/[()]/637869381676042455.json", + "/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869733124119330.json", + "/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869734240700328.json", + "/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869734970730630.json", + "/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869743752078399.json", + "/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-09-22/[()]/637869744751177715.json", + "/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-09-22/[()]/637869745134124462.json" ], "ValidImageFormatExtensions": [ ".bmp", diff --git a/Compare/appsettings.json b/Compare/appsettings.json index f920592..54dfdc3 100644 --- a/Compare/appsettings.json +++ b/Compare/appsettings.json @@ -50,7 +50,7 @@ "WorkingDirectoryName": "PharesApps", "Windows": { "Configuration": { - "DateGroup": "2022-09-15", + "DateGroup": "2022-09-22", "DiffPropertyDirectory": "", "FileNameDirectorySeparator": ".Z.", "ForcePropertyLastWriteTimeToCreationTime": false, @@ -94,13 +94,13 @@ ".GIF" ], "PropertyContentCollectionFiles": [ - "/Images 2022-09-15 - 7390c13 - III - Results/A) Property/2022-09-15/[()]/637869381676042455.json", - "/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869733124119330.json", - "/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869734240700328.json", - "/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869734970730630.json", - "/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869743752078399.json", - "/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-09-15/[()]/637869744751177715.json", - "/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-09-15/[()]/637869745134124462.json" + "/Images 2022-09-22 - fb1c68e - III - Results/A) Property/2022-09-22/[()]/637869381676042455.json", + "/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869733124119330.json", + "/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869734240700328.json", + "/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869734970730630.json", + "/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869743752078399.json", + "/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-09-22/[()]/637869744751177715.json", + "/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-09-22/[()]/637869745134124462.json" ], "ValidImageFormatExtensions": [ ".bmp", diff --git a/Date-Group/appsettings.Development.json b/Date-Group/appsettings.Development.json index c9d2e45..aa667bb 100644 --- a/Date-Group/appsettings.Development.json +++ b/Date-Group/appsettings.Development.json @@ -55,7 +55,7 @@ "ByHash": false, "BySeason": false, "ByWeek": false, - "DateGroup": "2022-09-15", + "DateGroup": "2022-09-22", "FileNameDirectorySeparator": ".Z.", "ForcePropertyLastWriteTimeToCreationTime": false, "KeepFullPath": false, @@ -63,7 +63,7 @@ "Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]", "PopulatePropertyId": true, "PropertiesChangedForProperty": false, - "RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-09-15 - 7390c13 - III", + "RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-09-22 - fb1c68e - III", "WriteBitmapDataBytes": false, "IgnoreExtensions": [ ".gif", diff --git a/Distance/Distance.csproj b/Distance/Distance.csproj new file mode 100644 index 0000000..4397f8b --- /dev/null +++ b/Distance/Distance.csproj @@ -0,0 +1,52 @@ + + + enable + 10.0 + enable + library + win-x64 + net6.0 + + + Phares.View.by.Distance.Distance + false + 6.0.100.1 + Mike Phares + Phares + true + snupkg + + + true + true + true + + + Windows + + + OSX + + + Linux + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Distance/Models/Stateless/SerilogExtensionMethods.cs b/Distance/Models/Stateless/SerilogExtensionMethods.cs new file mode 100644 index 0000000..80d18c0 --- /dev/null +++ b/Distance/Models/Stateless/SerilogExtensionMethods.cs @@ -0,0 +1,10 @@ +namespace View_by_Distance.Distance.Models.Stateless; + +internal static class SerilogExtensionMethods +{ + + internal static void Warn(this Serilog.ILogger log, string messageTemplate) => log.Warning(messageTemplate); + + internal static void Info(this Serilog.ILogger log, string messageTemplate) => log.Information(messageTemplate); + +} \ No newline at end of file diff --git a/Instance/Models/_E_Distance.cs b/Distance/Models/_E_Distance.cs similarity index 89% rename from Instance/Models/_E_Distance.cs rename to Distance/Models/_E_Distance.cs index 248f602..75fe4ed 100644 --- a/Instance/Models/_E_Distance.cs +++ b/Distance/Models/_E_Distance.cs @@ -5,12 +5,12 @@ using View_by_Distance.Map.Models; using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Properties; -namespace View_by_Distance.Instance.Models; +namespace View_by_Distance.Distance.Models; -internal class E_Distance : Shared.Models.Methods.IFaceDistance +public class E_Distance : Shared.Models.Methods.IFaceDistance { - internal static void SaveFaceDistances(Property.Models.Configuration propertyConfiguration, string eResultsFullGroupDirectory, SortingContainer[] sortingContainers) + public static void SaveFaceDistances(Property.Models.Configuration propertyConfiguration, string eResultsFullGroupDirectory, SortingContainer[] sortingContainers) { string eDistanceContentCollectionDirectory = Path.Combine(eResultsFullGroupDirectory, "([])"); if (!Directory.Exists(eDistanceContentCollectionDirectory)) @@ -22,7 +22,7 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance File.WriteAllLines(eDistanceContentFileName, results); } - private static List GetSortingCollection(Map.Models.Configuration configuration, MapLogic mapLogic, List faceDistanceEncodings, int faceDistanceContainersLength, int i, FaceDistance faceDistanceEncoding) + private static List GetSortingCollection(Configuration configuration, MapLogic mapLogic, List faceDistanceEncodings, int faceDistanceContainersLength, int i, FaceDistance faceDistanceEncoding) { List results; List faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding); @@ -33,7 +33,7 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance return results; } - private static List GetSortingContainers(Map.Models.Configuration configuration, Face face, FaceDistance faceDistanceEncoding, List sortingCollection) + private static List GetSortingContainers(Configuration configuration, Face face, FaceDistance faceDistanceEncoding, List sortingCollection) { List results = new(); SortingContainer sortingContainer; @@ -64,7 +64,29 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance return faceDistanceEncodings; } - internal static SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, Map.Models.Configuration configuration, long ticks, MapLogic mapLogic, List selectedFilteredFaces) + private static FaceDistanceContainer[] GetFaceDistanceContainers(List selectedFilteredFaces) + { + FaceDistanceContainer[] results; + FaceDistance faceDistance; + FaceDistanceContainer faceDistanceContainer; + List collection = new(); + foreach (Face face in selectedFilteredFaces) + { + if (face.Mapping is null) + throw new NotSupportedException(); + if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding) + continue; + faceDistance = new(face.Mapping.MappingFromLocation.Confidence, faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromLocation.NormalizedPixelPercentage); + faceDistanceContainer = new(face, faceDistance); + collection.Add(faceDistanceContainer); + } + results = (from l in collection orderby l.FaceDistance.Encoding is not null select l).ToArray(); + if (results.Any() && results[0].FaceDistance.Encoding is null) + throw new Exception("Sorting failed!"); + return results; + } + + public static SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, Configuration configuration, long ticks, MapLogic mapLogic, List selectedFilteredFaces) { SortingContainer[] results; List collection = new(); @@ -94,29 +116,7 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance return results; } - private static FaceDistanceContainer[] GetFaceDistanceContainers(List selectedFilteredFaces) - { - FaceDistanceContainer[] results; - FaceDistance faceDistance; - FaceDistanceContainer faceDistanceContainer; - List collection = new(); - foreach (Face face in selectedFilteredFaces) - { - if (face.Mapping is null) - throw new NotSupportedException(); - if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding) - continue; - faceDistance = new(face.Mapping.MappingFromLocation.Confidence, faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromLocation.NormalizedPixelPercentage); - faceDistanceContainer = new(face, faceDistance); - collection.Add(faceDistanceContainer); - } - results = (from l in collection orderby l.FaceDistance.Encoding is not null select l).ToArray(); - if (results.Any() && results[0].FaceDistance.Encoding is null) - throw new Exception("Sorting failed!"); - return results; - } - - internal static List GetSelectedFilteredFaces(List distinctFilteredFaces) + public static List GetSelectedFilteredFaces(List distinctFilteredFaces) { List results; Face[] orderedFilteredFaces = (from l in distinctFilteredFaces orderby l.Mapping is not null, l.Mapping?.MappingFromItem.MinimumDateTime descending select l).ToArray(); @@ -124,7 +124,7 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance return results; } - internal static void SetFaceDistances(int maxDegreeOfParallelism, long ticks, List selectedFilteredFaces) + public static void SetFaceDistances(int maxDegreeOfParallelism, long ticks, List selectedFilteredFaces) { int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism }; @@ -186,7 +186,7 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance return results; } - void Shared.Models.Methods.IFaceDistance.SavePossiblyNewPersonContainers(IPropertyConfiguration propertyConfiguration, string personBirthdayFormat, string facesFileNameExtension, Dictionary personKeyToPersonContainer, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer) + void Shared.Models.Methods.IFaceDistance.SavePossiblyNewPersonContainers(IPropertyConfiguration propertyConfiguration, string personBirthdayFormat, string facesFileNameExtension, string a2PeopleSingletonDirectory, Dictionary personKeyToPersonContainer, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer) { char @char; string json; @@ -202,7 +202,6 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance string checkPersonKeyFormattedDirectory; char[] chars = Shared.Models.Stateless.Methods.IAge.GetChars(); JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true }; - string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A2_People), "{}"); foreach ((string[] personDisplayDirectoryNames, PersonContainer personContainer) in possiblyNewPersonDisplayDirectoryNamesAndPersonContainer) { if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) diff --git a/Face/Face.csproj b/Face/Face.csproj new file mode 100644 index 0000000..ca67660 --- /dev/null +++ b/Face/Face.csproj @@ -0,0 +1,49 @@ + + + enable + 10.0 + enable + library + win-x64 + net6.0 + + + Phares.View.by.Distance.Face + false + 6.0.100.1 + Mike Phares + Phares + true + snupkg + + + true + true + true + + + Windows + + + OSX + + + Linux + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Face/Models/Stateless/SerilogExtensionMethods.cs b/Face/Models/Stateless/SerilogExtensionMethods.cs new file mode 100644 index 0000000..50f236a --- /dev/null +++ b/Face/Models/Stateless/SerilogExtensionMethods.cs @@ -0,0 +1,10 @@ +namespace View_by_Distance.Face.Models.Stateless; + +internal static class SerilogExtensionMethods +{ + + internal static void Warn(this Serilog.ILogger log, string messageTemplate) => log.Warning(messageTemplate); + + internal static void Info(this Serilog.ILogger log, string messageTemplate) => log.Information(messageTemplate); + +} \ No newline at end of file diff --git a/Instance/Models/_D_Face.cs b/Face/Models/_D_Face.cs similarity index 68% rename from Instance/Models/_D_Face.cs rename to Face/Models/_D_Face.cs index 30a77cc..a0647d2 100644 --- a/Instance/Models/_D_Face.cs +++ b/Face/Models/_D_Face.cs @@ -1,5 +1,4 @@ using System.Drawing; -using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Reflection; using System.Text.Json; @@ -11,7 +10,7 @@ using View_by_Distance.Resize.Models; using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Stateless; -namespace View_by_Distance.Instance.Models; +namespace View_by_Distance.Face.Models; /// // List @@ -19,7 +18,7 @@ namespace View_by_Distance.Instance.Models; public class D_Face { - internal List AngleBracketCollection { get; } + public List AngleBracketCollection { get; } protected readonly string _FileNameExtension; public string FileNameExtension => _FileNameExtension; @@ -40,21 +39,60 @@ public class D_Face private readonly EncoderParameters _HiddenEncoderParameters; private readonly JsonSerializerOptions _WriteIndentedAndWhenWritingNull; - internal D_Face(Configuration configuration, string argZero, Model model, ModelParameter modelParameter, PredictorModel predictorModel, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension, ImageCodecInfo hiddenImageCodecInfo, EncoderParameters hiddenEncoderParameters, string hiddenFileNameExtension) + private readonly bool _CheckDFaceAndUpWriteDates; + private readonly int _FaceDistanceHiddenImageFactor; + private readonly bool _ForceFaceLastWriteTimeToCreationTime; + private readonly int _LocationDigits; + private readonly int _LocationFactor; + private readonly int _NumberOfJitters; + private readonly int _NumberOfTimesToUpsample; + private readonly bool _OverrideForFaceImages; + private readonly bool _PropertiesChangedForFaces; + + public D_Face( + string argZero, + bool checkDFaceAndUpWriteDates, + Configuration configuration, + EncoderParameters encoderParameters, + int faceDistanceHiddenImageFactor, + string filenameExtension, + bool forceFaceLastWriteTimeToCreationTime, + EncoderParameters hiddenEncoderParameters, + string hiddenFileNameExtension, + ImageCodecInfo hiddenImageCodecInfo, + ImageCodecInfo imageCodecInfo, + int locationDigits, + int locationFactor, + Model model, + ModelParameter modelParameter, + int numberOfJitters, + int numberOfTimesToUpsample, + bool overrideForFaceImages, + PredictorModel predictorModel, + bool propertiesChangedForFaces) { _Model = model; _ArgZero = argZero; _Configuration = configuration; _ImageCodecInfo = imageCodecInfo; + _LocationDigits = locationDigits; + _LocationFactor = locationFactor; _ModelParameter = modelParameter; _PredictorModel = predictorModel; + _NumberOfJitters = numberOfJitters; _EncoderParameters = encoderParameters; _FileNameExtension = filenameExtension; _Log = Serilog.Log.ForContext(); AngleBracketCollection = new List(); _HiddenImageCodecInfo = hiddenImageCodecInfo; + _OverrideForFaceImages = overrideForFaceImages; _HiddenEncoderParameters = hiddenEncoderParameters; _HiddenFileNameExtension = hiddenFileNameExtension; + _NumberOfTimesToUpsample = numberOfTimesToUpsample; + _CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates; + _PropertiesChangedForFaces = propertiesChangedForFaces; + _FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor; + _ForceFaceLastWriteTimeToCreationTime = forceFaceLastWriteTimeToCreationTime; ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, Array.Empty(), null); if (constructorInfo is null) throw new Exception(); @@ -62,25 +100,6 @@ public class D_Face _WriteIndentedAndWhenWritingNull = new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }; } - private static void GetPointBounds(PointF[] points, out float xMinimum, out float xMaximum, out float yMinimum, out float yMaximum) - { - xMinimum = points[0].X; - xMaximum = xMinimum; - yMinimum = points[0].Y; - yMaximum = yMinimum; - foreach (PointF point in points) - { - if (xMinimum > point.X) - xMinimum = point.X; - if (xMaximum < point.X) - xMaximum = point.X; - if (yMinimum > point.Y) - yMinimum = point.Y; - if (yMaximum < point.Y) - yMaximum = point.Y; - } - } - public override string ToString() { string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); @@ -89,67 +108,6 @@ public class D_Face #pragma warning disable CA1416 - internal static Bitmap RotateBitmap(Bitmap bitmap, float angle) - { - Bitmap result; -#if Linux - throw new Exception("Built on Linux!"); -#elif OSX - throw new Exception("Built on macOS!"); -#elif Windows - // Make a Matrix to represent rotation - // by this angle. - Matrix rotate_at_origin = new(); - rotate_at_origin.Rotate(angle); - - // Rotate the image's corners to see how big - // it will be after rotation. - PointF[] points = - { - new PointF(0, 0), - new PointF(bitmap.Width, 0), - new PointF(bitmap.Width, bitmap.Height), - new PointF(0, bitmap.Height), - }; - rotate_at_origin.TransformPoints(points); - float xMinimum, xMaximum, yMinimum, yMaximum; - GetPointBounds(points, out xMinimum, out xMaximum, out yMinimum, out yMaximum); - - // Make a bitmap to hold the rotated result. - int wid = (int)Math.Round(xMaximum - xMinimum); - int hgt = (int)Math.Round(yMaximum - yMinimum); - result = new Bitmap(wid, hgt); - - // Create the real rotation transformation. - Matrix rotate_at_center = new(); - rotate_at_center.RotateAt(angle, - new PointF(wid / 2f, hgt / 2f)); - - // Draw the image onto the new bitmap rotated. - using (Graphics gr = Graphics.FromImage(result)) - { - // Use smooth image interpolation. - gr.InterpolationMode = InterpolationMode.High; - - // Clear with the color in the image's upper left corner. - gr.Clear(bitmap.GetPixel(0, 0)); - - // For debugging. (It's easier to see the background.) - // gr.Clear(Color.LightBlue); - - // Set up the transformation to rotate. - gr.Transform = rotate_at_center; - - // Draw the image centered on the bitmap. - int x = (wid - bitmap.Width) / 2; - int y = (hgt - bitmap.Height) / 2; - gr.DrawImage(bitmap, x, y); - } -#endif - // Return the result bitmap. - return result; - } - private static byte[] GetBytes(string value) { byte[] results = new byte[value.Length + 1]; @@ -170,7 +128,7 @@ public class D_Face return result; } - private void SaveFaces(FileHolder resizedFileHolder, List<(Face, FileInfo?, string)> collection) + private void SaveFaces(FileHolder resizedFileHolder, List<(Shared.Models.Face, FileInfo?, string)> collection) { int pixel; int width; @@ -181,23 +139,21 @@ public class D_Face Location? location; Rectangle rectangle; PropertyItem? propertyItem; - int software = (int)IExif.Tags.Software; int userComment = (int)IExif.Tags.UserComment; using Bitmap source = new(resizedFileHolder.FullName); - int imageDescription = (int)IExif.Tags.ImageDescription; - foreach ((Face face, FileInfo? fileInfo, string fileName) in collection) + foreach ((Shared.Models.Face face, FileInfo? fileInfo, string fileName) in collection) { if (fileInfo is null) continue; if (face.FaceEncoding is null || face?.Location?.NormalizedPixelPercentage is null || face?.OutputResolution is null) continue; - location = Shared.Models.Stateless.Methods.ILocation.GetLocation(face.Location, _Configuration.LocationDigits, _Configuration.LocationFactor, source.Height, source.Width, collection.Count); + location = Shared.Models.Stateless.Methods.ILocation.GetLocation(face.Location, _LocationDigits, _LocationFactor, source.Height, source.Width, collection.Count); if (location is null) continue; width = location.Right - location.Left; height = location.Bottom - location.Top; json = JsonSerializer.Serialize(face.FaceEncoding); - pixel = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, _Configuration.LocationDigits, _Configuration.LocationFactor, face.OutputResolution); + pixel = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, _LocationDigits, _LocationFactor, face.OutputResolution); rectangle = new Rectangle(location.Left, location.Top, width, height); using (bitmap = new(width, height)) { @@ -205,15 +161,11 @@ public class D_Face graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel); propertyItem = GetPropertyItem(userComment, json); bitmap.SetPropertyItem(propertyItem); - propertyItem = GetPropertyItem(imageDescription, pixel.ToString()); - bitmap.SetPropertyItem(propertyItem); - propertyItem = GetPropertyItem(software, face.Location.NormalizedPixelPercentage.Value.ToString()); - bitmap.SetPropertyItem(propertyItem); bitmap.Save(fileInfo.FullName, _ImageCodecInfo, _EncoderParameters); } if (File.Exists(fileName)) File.Delete(fileName); - location = Shared.Models.Stateless.Methods.ILocation.GetLocation(_Configuration.FaceDistanceHiddenImageFactor, face.Location, _Configuration.LocationDigits, _Configuration.LocationFactor, source.Height, source.Width, collection.Count); + location = Shared.Models.Stateless.Methods.ILocation.GetLocation(_FaceDistanceHiddenImageFactor, face.Location, _LocationDigits, _LocationFactor, source.Height, source.Width, collection.Count); if (location is null) continue; width = location.Right - location.Left; @@ -229,9 +181,9 @@ public class D_Face } } - private List GetFaces(Item item, Shared.Models.Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation) + private List GetFaces(Item item, Shared.Models.Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation) { - List results = new(); + List results = new(); if (item.ImageFileHolder is null) throw new NullReferenceException(nameof(item.ImageFileHolder)); if (item.ResizedFileHolder is null) @@ -251,14 +203,14 @@ public class D_Face else { List<(int, Location Location, FaceRecognitionDotNet.FaceEncoding? FaceEncoding, Dictionary? FaceParts)> collection; - FaceRecognition faceRecognition = new(_Configuration.NumberOfTimesToUpsample, _Configuration.NumberOfJitters, _PredictorModel, _Model, _ModelParameter); + FaceRecognition faceRecognition = new(_NumberOfTimesToUpsample, _NumberOfJitters, _PredictorModel, _Model, _ModelParameter); collection = faceRecognition.GetCollection(unknownImage, includeFaceEncoding: true, includeFaceParts: true, sortByNormalizedPixelPercentage: true); if (!collection.Any()) results.Add(new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null)); else { - Face face; double[] rawEncoding; + Shared.Models.Face face; Shared.Models.FaceEncoding convertedFaceEncoding; foreach ((int locationIndex, Location location, FaceRecognitionDotNet.FaceEncoding? faceEncoding, Dictionary? faceParts) in collection) { @@ -284,9 +236,9 @@ public class D_Face #pragma warning restore CA1416 - internal List GetFaces(string dResultsFullGroupDirectory, List> subFileTuples, List parseExceptions, Item item, Shared.Models.Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation) + public List GetFaces(string dResultsFullGroupDirectory, List> subFileTuples, List parseExceptions, Item item, Shared.Models.Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation) { - List? results; + List? results; if (item.Property?.Id is null) throw new NullReferenceException(nameof(item.Property.Id)); if (item.ImageFileHolder is null) @@ -299,7 +251,7 @@ public class D_Face string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) }; List dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); string usingRelativePath = Path.Combine(AngleBracketCollection[0].Replace("<>", "[]"), $"{item.ImageFileHolder.NameWithoutExtension}.json"); - string dCollectionFile = Path.Combine(dResultsFullGroupDirectory, "[]", _Configuration.PropertyConfiguration.ResultAllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json"); + string dCollectionFile = Path.Combine(dResultsFullGroupDirectory, "[]", _Configuration.ResultAllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json"); FileInfo fileInfo = new(dCollectionFile); if (!fileInfo.Exists) { @@ -320,31 +272,31 @@ public class D_Face } } } - if (_Configuration.ForceFaceLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete"))) + if (_ForceFaceLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete"))) { File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName); fileInfo.Refresh(); } - if (_Configuration.ForceFaceLastWriteTimeToCreationTime && fileInfo.Exists && fileInfo.LastWriteTime != fileInfo.CreationTime) + if (_ForceFaceLastWriteTimeToCreationTime && fileInfo.Exists && fileInfo.LastWriteTime != fileInfo.CreationTime) { File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime); fileInfo.Refresh(); } - if (_Configuration.PropertiesChangedForFaces) + if (_PropertiesChangedForFaces) results = null; else if (!fileInfo.Exists) results = null; - else if (_Configuration.CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime) + else if (_CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime) results = null; else { json = Shared.Models.Stateless.Methods.IFace.GetJson(fileInfo.FullName); try { - results = JsonSerializer.Deserialize>(json); + results = JsonSerializer.Deserialize>(json); if (results is null) throw new NullReferenceException(nameof(results)); - if (!_Configuration.ForceFaceLastWriteTimeToCreationTime) + if (!_ForceFaceLastWriteTimeToCreationTime) { normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results); normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count(); @@ -368,9 +320,9 @@ public class D_Face if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime)) subFileTuples.Add(new Tuple(nameof(D_Face), DateTime.Now)); } - if (_Configuration.ForceFaceLastWriteTimeToCreationTime) + if (_ForceFaceLastWriteTimeToCreationTime) { - results = (from l in results select new Face(_Configuration.LocationDigits, _Configuration.LocationFactor, results.Count, l)).ToList(); + results = (from l in results select new Shared.Models.Face(_LocationDigits, _LocationFactor, results.Count, l)).ToList(); normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results); normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count(); if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length) @@ -388,7 +340,7 @@ public class D_Face return results; } - internal void SaveFaces(string dResultsFullGroupDirectory, List> subFileTuples, List parseExceptions, Item item, List faceCollection) + public void SaveFaces(string dResultsFullGroupDirectory, List> subFileTuples, List parseExceptions, Item item, List faceCollection) { if (item.ImageFileHolder is null) throw new NullReferenceException(nameof(item.ImageFileHolder)); @@ -398,14 +350,13 @@ public class D_Face bool check = false; string parentCheck; string deterministicHashCodeKeyDisplay; - List<(Face, FileInfo?, string)> collection = new(); + List<(Shared.Models.Face, FileInfo?, string)> collection = new(); string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) }; string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension); List dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); - bool facesDirectoryExisted = Directory.Exists(facesDirectory); - if (!facesDirectoryExisted) + if (!Directory.Exists(facesDirectory)) _ = Directory.CreateDirectory(facesDirectory); - foreach (Face face in faceCollection) + foreach (Shared.Models.Face face in faceCollection) { if (item.Property?.Id is null || face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null) { @@ -423,29 +374,15 @@ public class D_Face File.Delete(parentCheck); } collection.Add(new(face, fileInfo, Path.Combine(facesDirectory, $"{deterministicHashCodeKeyDisplay}{item.ImageFileHolder.ExtensionLowered}{_HiddenFileNameExtension}"))); - if (_Configuration.OverrideForFaceImages) + if (_OverrideForFaceImages) check = true; else if (!fileInfo.Exists) check = true; - else if (_Configuration.CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime) + else if (_CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime) check = true; } if (check) SaveFaces(item.ResizedFileHolder, collection); } - private static bool HasLeftAndRight(Dictionary faceParts) - { - bool result = true; - if (!faceParts.ContainsKey(FacePart.LeftEye.ToString())) - result = false; - else if (!faceParts.ContainsKey(FacePart.RightEye.ToString())) - result = false; - else if (!faceParts.ContainsKey(FacePart.LeftEyebrow.ToString())) - result = false; - else if (!faceParts.ContainsKey(FacePart.RightEyebrow.ToString())) - result = false; - return result; - } - } \ No newline at end of file diff --git a/FaceParts/FaceParts.csproj b/FaceParts/FaceParts.csproj new file mode 100644 index 0000000..b8000a5 --- /dev/null +++ b/FaceParts/FaceParts.csproj @@ -0,0 +1,50 @@ + + + enable + 10.0 + enable + library + win-x64 + net6.0 + + + Phares.View.by.Distance.FaceParts + false + 6.0.100.1 + Mike Phares + Phares + true + snupkg + + + true + true + true + + + Windows + + + OSX + + + Linux + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FaceParts/Models/Stateless/SerilogExtensionMethods.cs b/FaceParts/Models/Stateless/SerilogExtensionMethods.cs new file mode 100644 index 0000000..89d58f7 --- /dev/null +++ b/FaceParts/Models/Stateless/SerilogExtensionMethods.cs @@ -0,0 +1,10 @@ +namespace View_by_Distance.FaceParts.Models.Stateless; + +internal static class SerilogExtensionMethods +{ + + internal static void Warn(this Serilog.ILogger log, string messageTemplate) => log.Warning(messageTemplate); + + internal static void Info(this Serilog.ILogger log, string messageTemplate) => log.Information(messageTemplate); + +} \ No newline at end of file diff --git a/Instance/Models/_D2_FaceParts.cs b/FaceParts/Models/_D2_FaceParts.cs similarity index 64% rename from Instance/Models/_D2_FaceParts.cs rename to FaceParts/Models/_D2_FaceParts.cs index 1af87cb..17d32f2 100644 --- a/Instance/Models/_D2_FaceParts.cs +++ b/FaceParts/Models/_D2_FaceParts.cs @@ -1,35 +1,39 @@ using System.Drawing; +using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Text.Json; +using View_by_Distance.Face.Models; using View_by_Distance.Metadata.Models; using View_by_Distance.Resize.Models; using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Properties; using View_by_Distance.Shared.Models.Stateless; -namespace View_by_Distance.Instance.Models; +namespace View_by_Distance.FaceParts.Models; /// // *.png /// -internal class D2_FaceParts +public class D2_FaceParts { protected readonly string _FileNameExtension; public string FileNameExtension => _FileNameExtension; private readonly Serilog.ILogger? _Log; - private readonly Configuration _Configuration; private readonly ImageCodecInfo _ImageCodecInfo; + private readonly bool _CheckDFaceAndUpWriteDates; + private readonly bool _OverrideForFaceLandmarkImages; private readonly EncoderParameters _EncoderParameters; - internal D2_FaceParts(Configuration configuration, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) + public D2_FaceParts(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension, bool checkDFaceAndUpWriteDates, bool overrideForFaceLandmarkImages) { - _Configuration = configuration; _ImageCodecInfo = imageCodecInfo; _EncoderParameters = encoderParameters; _FileNameExtension = filenameExtension; _Log = Serilog.Log.ForContext(); + _CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates; + _OverrideForFaceLandmarkImages = overrideForFaceLandmarkImages; } public override string ToString() @@ -38,19 +42,99 @@ internal class D2_FaceParts return result; } + private static void GetPointBounds(PointF[] points, out float xMinimum, out float xMaximum, out float yMinimum, out float yMaximum) + { + xMinimum = points[0].X; + xMaximum = xMinimum; + yMinimum = points[0].Y; + yMaximum = yMinimum; + foreach (PointF point in points) + { + if (xMinimum > point.X) + xMinimum = point.X; + if (xMaximum < point.X) + xMaximum = point.X; + if (yMinimum > point.Y) + yMinimum = point.Y; + if (yMaximum < point.Y) + yMaximum = point.Y; + } + } + #pragma warning disable CA1416 + private static Bitmap RotateBitmap(Bitmap bitmap, float angle) + { + Bitmap result; +#if Linux + throw new Exception("Built on Linux!"); +#elif OSX + throw new Exception("Built on macOS!"); +#elif Windows + // Make a Matrix to represent rotation + // by this angle. + Matrix rotate_at_origin = new(); + rotate_at_origin.Rotate(angle); + + // Rotate the image's corners to see how big + // it will be after rotation. + PointF[] points = + { + new PointF(0, 0), + new PointF(bitmap.Width, 0), + new PointF(bitmap.Width, bitmap.Height), + new PointF(0, bitmap.Height), + }; + rotate_at_origin.TransformPoints(points); + float xMinimum, xMaximum, yMinimum, yMaximum; + GetPointBounds(points, out xMinimum, out xMaximum, out yMinimum, out yMaximum); + + // Make a bitmap to hold the rotated result. + int wid = (int)Math.Round(xMaximum - xMinimum); + int hgt = (int)Math.Round(yMaximum - yMinimum); + result = new Bitmap(wid, hgt); + + // Create the real rotation transformation. + Matrix rotate_at_center = new(); + rotate_at_center.RotateAt(angle, + new PointF(wid / 2f, hgt / 2f)); + + // Draw the image onto the new bitmap rotated. + using (Graphics gr = Graphics.FromImage(result)) + { + // Use smooth image interpolation. + gr.InterpolationMode = InterpolationMode.High; + + // Clear with the color in the image's upper left corner. + gr.Clear(bitmap.GetPixel(0, 0)); + + // For debugging. (It's easier to see the background.) + // gr.Clear(Color.LightBlue); + + // Set up the transformation to rotate. + gr.Transform = rotate_at_center; + + // Draw the image centered on the bitmap. + int x = (wid - bitmap.Width) / 2; + int y = (hgt - bitmap.Height) / 2; + gr.DrawImage(bitmap, x, y); + } +#endif + // Return the result bitmap. + return result; + } + private static Bitmap RotateBitmap(Image image, float angle) { Bitmap result; Bitmap bitmap = new(image); - result = D_Face.RotateBitmap(bitmap, angle); + result = RotateBitmap(bitmap, angle); if (bitmap is not null) bitmap.Dispose(); return result; } - private void SaveFaceParts(int pointSize, IFileHolder resizedFileHolder, bool saveRotated, List<(Face, string, string)> collection) + private void SaveFaceParts(int pointSize, IFileHolder resizedFileHolder, bool saveRotated, List<(Shared.Models.Face, string, string)> collection) { int x; int y; @@ -58,7 +142,7 @@ internal class D2_FaceParts int width; int height; Bitmap rotated; - foreach ((Face face, string fileName, string rotatedFileName) in collection) + foreach ((Shared.Models.Face face, string fileName, string rotatedFileName) in collection) { if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null) continue; @@ -118,7 +202,7 @@ internal class D2_FaceParts #pragma warning restore CA1416 - internal void SaveFaceLandmarkImages(string facesDirectory, List> subFileTuples, List parseExceptions, Item item, List faceCollection, bool saveRotated) + public void SaveFaceLandmarkImages(string facesDirectory, List> subFileTuples, List parseExceptions, Item item, List faceCollection, bool saveRotated) { if (item.ImageFileHolder is null) throw new NullReferenceException(nameof(item.ImageFileHolder)); @@ -133,12 +217,12 @@ internal class D2_FaceParts long ticks = DateTime.Now.Ticks; bool updateDateWhenMatches = false; string deterministicHashCodeKeyDisplay; - List<(Face, string, string)> collection = new(); + List<(Shared.Models.Face, string, string)> collection = new(); string[] changesFrom = new string[] { nameof(Property.Models.A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) }; List dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); if (!Directory.Exists(facesDirectory)) _ = Directory.CreateDirectory(facesDirectory); - foreach (Face face in faceCollection) + foreach (Shared.Models.Face face in faceCollection) { if (item.Property?.Id is null || face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null) { @@ -161,13 +245,13 @@ internal class D2_FaceParts collection.Add(new(face, fileInfo.FullName, rotatedFileInfo.FullName)); if (check) continue; - else if (_Configuration.OverrideForFaceLandmarkImages) + else if (_OverrideForFaceLandmarkImages) check = true; else if (!fileInfo.Exists) check = true; else if (saveRotated && !rotatedFileInfo.Exists) check = true; - else if (_Configuration.CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime) + else if (_CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime) check = true; if (check && !updateDateWhenMatches) { diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index dfb53aa..e42141d 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -3,6 +3,9 @@ using Phares.Shared; using ShellProgressBar; using System.Drawing.Imaging; using System.Text.Json; +using View_by_Distance.Distance.Models; +using View_by_Distance.Face.Models; +using View_by_Distance.FaceParts.Models; using View_by_Distance.FaceRecognitionDotNet; using View_by_Distance.Instance.Models; using View_by_Distance.Map.Models; @@ -37,7 +40,14 @@ public partial class DlibDotNet private readonly List> _FileKeyValuePairs; private readonly Dictionary>> _FilePropertiesKeyValuePairs; - public DlibDotNet(List args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console) + public DlibDotNet( + List args, + IsEnvironment isEnvironment, + IConfigurationRoot configurationRoot, + AppSettings appSettings, + string workingDirectory, + bool isSilent, + IConsole console) { _Console = console; string argZero; @@ -73,7 +83,27 @@ public partial class DlibDotNet { (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetPngLowQuality(); (ImageCodecInfo hiddenImageCodecInfo, EncoderParameters hiddenEncoderParameters, string hiddenFileNameExtension) = C_Resize.GetGifLowQuality(); - _Faces = new D_Face(configuration, argZero, model, modelParameter, predictorModel, imageCodecInfo, encoderParameters, filenameExtension, hiddenImageCodecInfo, hiddenEncoderParameters, hiddenFileNameExtension); + _Faces = new D_Face( + argZero, + configuration.CheckDFaceAndUpWriteDates, + configuration.PropertyConfiguration, + encoderParameters, + configuration.FaceDistanceHiddenImageFactor, + filenameExtension, + configuration.ForceFaceLastWriteTimeToCreationTime, + hiddenEncoderParameters, + hiddenFileNameExtension, + hiddenImageCodecInfo, + imageCodecInfo, + configuration.LocationDigits, + configuration.LocationFactor, + model, + modelParameter, + configuration.NumberOfJitters, + configuration.NumberOfTimesToUpsample, + configuration.OverrideForFaceImages, + predictorModel, + configuration.PropertiesChangedForFaces); } if (_FirstRun || !_ArgZeroIsConfigurationRootDirectory) personContainers = Array.Empty(); @@ -84,7 +114,17 @@ public partial class DlibDotNet ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; using ProgressBar progressBar = new(1, message, options); progressBar.Tick(); - personContainers = A2_People.GetPersonContainers(configuration, propertyConfiguration, _Faces.FileNameExtension); + string rootDirectory = propertyConfiguration.RootDirectory; + string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A2_People)); + string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory)); + if (rootResultsDirectory is null) + throw new Exception(); + Storage storage = new(rootDirectory, rootResultsDirectory, peopleRootDirectory); + personContainers = Shared.Models.Stateless.Methods.IPersonContainer.GetPersonContainers( + storage, + configuration.LocationDigits, + configuration.PersonBirthdayFormat, + _Faces.FileNameExtension); } if (!isSilent && configuration.TestDistanceResults) { @@ -94,17 +134,32 @@ public partial class DlibDotNet } { (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetGifLowQuality(); - _FaceParts = new D2_FaceParts(configuration, imageCodecInfo, encoderParameters, filenameExtension); + _FaceParts = new D2_FaceParts(imageCodecInfo, encoderParameters, filenameExtension, configuration.CheckDFaceAndUpWriteDates, configuration.OverrideForFaceLandmarkImages); } { - (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetTuple(configuration.OutputExtension, configuration.OutputQuality); - _Resize = new C_Resize(configuration.ForceResizeLastWriteTimeToCreationTime, configuration.OverrideForResizeImages, configuration.PropertiesChangedForResize, configuration.ValidResolutions, imageCodecInfo, encoderParameters, filenameExtension); + (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetTuple( + configuration.OutputExtension, + configuration.OutputQuality); + _Resize = new C_Resize( + configuration.ForceResizeLastWriteTimeToCreationTime, + configuration.OverrideForResizeImages, + configuration.PropertiesChangedForResize, + configuration.ValidResolutions, + imageCodecInfo, + encoderParameters, + filenameExtension); } if (!configuration.SkipSearch) Search(ticks, model, predictorModel, argZero, propertyRoot, personContainers); if (!_FirstRun && !_IsEnvironment.Development && _Exceptions.Count == 0 && _ArgZeroIsConfigurationRootDirectory) { - List directoryCollections = _Rename.GetDirectoryRenameCollections(propertyConfiguration, model, predictorModel, relativePath: string.Empty, newDirectoryName: string.Empty, jsonFiles4InfoAny: false); + List directoryCollections = _Rename.GetDirectoryRenameCollections( + propertyConfiguration, + model, + predictorModel, + relativePath: string.Empty, + newDirectoryName: string.Empty, + jsonFiles4InfoAny: false); foreach (string[] directoryCollection in directoryCollections) { _Log.Information(string.Concat("Cleaning <", directoryCollection[0], ">")); @@ -287,17 +342,32 @@ public partial class DlibDotNet return result; } - private void FullParallelForWork(A_Property propertyLogic, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, List> sourceDirectoryChanges, List propertyFileHolderCollection, List propertyCollection, List>> metadataCollections, List> resizeKeyValuePairs, List?> imageFaceCollections, Container container, int index, Item item) + private void FullParallelForWork( + A_Property propertyLogic, + string outputResolution, + string bResultsFullGroupDirectory, + string cResultsFullGroupDirectory, + string dResultsFullGroupDirectory, + string d2ResultsFullGroupDirectory, + List> sourceDirectoryChanges, + List propertyFileHolderCollection, + List propertyCollection, + List>> metadataCollections, + List> resizeKeyValuePairs, + List?> imageFaceCollections, + Container container, + int index, + Item item) { if (item.ImageFileHolder is null) throw new NullReferenceException(nameof(item.ImageFileHolder)); - List? faceCollection; string original = "Original"; FileHolder? resizedFileHolder; Shared.Models.Property property; long ticks = DateTime.Now.Ticks; DateTime dateTime = DateTime.Now; List parseExceptions = new(); + List? faceCollection; Dictionary imageResizeKeyValuePairs; List> subFileTuples = new(); List> metadataCollection; @@ -317,10 +387,22 @@ public partial class DlibDotNet sourceDirectoryChanges.Add(new Tuple(nameof(A_Property), (from l in subFileTuples select l.Item2).Max())); } } - (int metadataGroups, metadataCollection) = _Metadata.GetMetadataCollection(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, subFileTuples, parseExceptions, item); + (int metadataGroups, metadataCollection) = _Metadata.GetMetadataCollection( + _Configuration.PropertyConfiguration, + bResultsFullGroupDirectory, + subFileTuples, + parseExceptions, + item); if (_AppSettings.MaxDegreeOfParallelism < 2) ticks = LogDelta(ticks, nameof(B_Metadata.GetMetadataCollection)); - imageResizeKeyValuePairs = _Resize.GetResizeKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item); + imageResizeKeyValuePairs = _Resize.GetResizeKeyValuePairs( + _Configuration.PropertyConfiguration, + cResultsFullGroupDirectory, + subFileTuples, + parseExceptions, + original, + metadataCollection, + item); if (_AppSettings.MaxDegreeOfParallelism < 2) ticks = LogDelta(ticks, nameof(C_Resize.GetResizeKeyValuePairs)); if (_Configuration.SaveResizedSubfiles) @@ -345,7 +427,15 @@ public partial class DlibDotNet int outputResolutionWidth = outputResolutionCollection[0]; int outputResolutionHeight = outputResolutionCollection[1]; int outputResolutionOrientation = outputResolutionCollection[2]; - faceCollection = _Faces.GetFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation); + faceCollection = _Faces.GetFaces( + dResultsFullGroupDirectory, + subFileTuples, + parseExceptions, + item, + property, + outputResolutionWidth, + outputResolutionHeight, + outputResolutionOrientation); if (_AppSettings.MaxDegreeOfParallelism < 2) ticks = LogDelta(ticks, nameof(D_Face.GetFaces)); _Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, faceCollection); @@ -357,7 +447,9 @@ public partial class DlibDotNet { bool saveRotated = _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution); - string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath(_Configuration.PropertyConfiguration, container.SourceDirectory); + string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath( + _Configuration.PropertyConfiguration, + container.SourceDirectory); string facesDirectory = Path.GetFullPath(Path.Combine($"{Path.Combine(d2ResultsFullGroupDirectory, "()")}{sourceDirectorySegment}", item.ImageFileHolder.NameWithoutExtension)); _FaceParts.SaveFaceLandmarkImages(facesDirectory, subFileTuples, parseExceptions, item, faceCollection, saveRotated); if (_AppSettings.MaxDegreeOfParallelism < 2) @@ -375,14 +467,33 @@ public partial class DlibDotNet } } - private int FullParallelWork(int maxDegreeOfParallelism, A_Property propertyLogic, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, List> sourceDirectoryChanges, List propertyFileHolderCollection, List propertyCollection, List>> metadataCollection, List> resizeKeyValuePairs, List?> imageFaceCollections, Container container, Item[] filteredItems, string message) + private int FullParallelWork( + int maxDegreeOfParallelism, + A_Property propertyLogic, + string outputResolution, + string bResultsFullGroupDirectory, + string cResultsFullGroupDirectory, + string dResultsFullGroupDirectory, + string d2ResultsFullGroupDirectory, + List> sourceDirectoryChanges, + List propertyFileHolderCollection, + List propertyCollection, + List>> metadataCollection, + List> resizeKeyValuePairs, + List?> imageFaceCollections, + Container container, + Item[] filteredItems, + string message) { if (_Log is null) throw new NullReferenceException(nameof(_Log)); int result = 0; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; - if (imageFaceCollections.Count != filteredItems.Length || metadataCollection.Count != filteredItems.Length || resizeKeyValuePairs.Count != filteredItems.Length || propertyCollection.Count != filteredItems.Length) + if (imageFaceCollections.Count != filteredItems.Length + || metadataCollection.Count != filteredItems.Length + || resizeKeyValuePairs.Count != filteredItems.Length + || propertyCollection.Count != filteredItems.Length) { for (int f = 0; f < filteredItems.Length; f++) { @@ -398,7 +509,22 @@ public partial class DlibDotNet { try { - FullParallelForWork(propertyLogic, outputResolution, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, sourceDirectoryChanges, propertyFileHolderCollection, propertyCollection, metadataCollection, resizeKeyValuePairs, imageFaceCollections, container, index: i, filteredItems[i]); + FullParallelForWork( + propertyLogic, + outputResolution, + bResultsFullGroupDirectory, + cResultsFullGroupDirectory, + dResultsFullGroupDirectory, + d2ResultsFullGroupDirectory, + sourceDirectoryChanges, + propertyFileHolderCollection, + propertyCollection, + metadataCollection, + resizeKeyValuePairs, + imageFaceCollections, + container, + index: i, + filteredItems[i]); if (i == 0 || sourceDirectoryChanges.Any()) progressBar.Tick(); } @@ -448,7 +574,15 @@ public partial class DlibDotNet } } - private void WriteGroup(A_Property propertyLogic, Shared.Models.Property[] propertyCollection, List>> metadataCollection, List> resizeKeyValuePairs, List?> imageFaceCollections, string outputResolution, Container container, Item[] filteredItems) + private void WriteGroup( + A_Property propertyLogic, + Shared.Models.Property[] propertyCollection, + List>> metadataCollection, + List> resizeKeyValuePairs, + List?> imageFaceCollections, + string outputResolution, + Container container, + Item[] filteredItems) { Item item; string key; @@ -461,11 +595,13 @@ public partial class DlibDotNet if (!(from l in propertyCollection where l?.Width is null select true).Any()) { string checkDirectory; - List?>> imageFaceCollectionsKeyValuePairs = new(); + List?>> imageFaceCollectionsKeyValuePairs = new(); List> propertyCollectionKeyValuePairs = new(); List>> resizeKeyValuePairsCollections = new(); List>>> metadataCollectionKeyValuePairs = new(); - (int level, List directories) = Shared.Models.Stateless.Methods.IPath.Get(_Configuration.PropertyConfiguration.RootDirectory, container.SourceDirectory); + (int level, List directories) = Shared.Models.Stateless.Methods.IPath.Get( + _Configuration.PropertyConfiguration.RootDirectory, + container.SourceDirectory); string fileName = string.Concat(string.Join(_Configuration.PropertyConfiguration.FileNameDirectorySeparator, directories), ".json"); for (int i = 0; i < filteredItems.Length; i++) { @@ -480,7 +616,7 @@ public partial class DlibDotNet _FileKeyValuePairs.Add(new KeyValuePair(container.SourceDirectory, key)); _FilePropertiesKeyValuePairs[container.SourceDirectory].Add(new Tuple(key, propertyCollection[i])); } - imageFaceCollectionsKeyValuePairs.Add(new KeyValuePair?>(key, imageFaceCollections[i])); + imageFaceCollectionsKeyValuePairs.Add(new KeyValuePair?>(key, imageFaceCollections[i])); propertyCollectionKeyValuePairs.Add(new KeyValuePair(key, propertyCollection[i])); resizeKeyValuePairsCollections.Add(new KeyValuePair>(key, resizeKeyValuePairs[i])); metadataCollectionKeyValuePairs.Add(new KeyValuePair>>(key, metadataCollection[i])); @@ -528,24 +664,77 @@ public partial class DlibDotNet } } - private (string, string, string, string, string, string) GetResultsFullGroupDirectories(Model? model, PredictorModel? predictorModel, string outputResolution) + private (string, string, string, string, string, string) GetResultsFullGroupDirectories( + Model? model, + PredictorModel? predictorModel, + string outputResolution) { string aResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory( - _Configuration.PropertyConfiguration, model, predictorModel, nameof(A_Property), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false); + _Configuration.PropertyConfiguration, + model, + predictorModel, + nameof(A_Property), + outputResolution, + includeResizeGroup: false, + includeModel: false, + includePredictorModel: false); string bResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory( - _Configuration.PropertyConfiguration, model, predictorModel, nameof(B_Metadata), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false); + _Configuration.PropertyConfiguration, + model, + predictorModel, + nameof(B_Metadata), + outputResolution, + includeResizeGroup: false, + includeModel: false, + includePredictorModel: false); string cResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory( - _Configuration.PropertyConfiguration, model, predictorModel, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false); + _Configuration.PropertyConfiguration, + model, + predictorModel, + nameof(C_Resize), + outputResolution, + includeResizeGroup: true, + includeModel: false, + includePredictorModel: false); string dResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory( - _Configuration.PropertyConfiguration, model, predictorModel, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true); + _Configuration.PropertyConfiguration, + model, + predictorModel, + nameof(D_Face), + outputResolution, + includeResizeGroup: true, + includeModel: true, + includePredictorModel: true); string d2ResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory( - _Configuration.PropertyConfiguration, model, predictorModel, nameof(D2_FaceParts), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true); + _Configuration.PropertyConfiguration, + model, + predictorModel, + nameof(D2_FaceParts), + outputResolution, + includeResizeGroup: true, + includeModel: true, + includePredictorModel: true); string eResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory( - _Configuration.PropertyConfiguration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true); + _Configuration.PropertyConfiguration, + model, + predictorModel, + nameof(E_Distance), + outputResolution, + includeResizeGroup: true, + includeModel: true, + includePredictorModel: true); return new(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory); } - private void SetAngleBracketCollections(A_Property propertyLogic, string outputResolution, Container container, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory) + private void SetAngleBracketCollections( + A_Property propertyLogic, + string outputResolution, + Container container, + string aResultsFullGroupDirectory, + string bResultsFullGroupDirectory, + string cResultsFullGroupDirectory, + string dResultsFullGroupDirectory, + string d2ResultsFullGroupDirectory) { _Faces.AngleBracketCollection.Clear(); _Resize.AngleBracketCollection.Clear(); @@ -595,7 +784,29 @@ public partial class DlibDotNet converted: false); } - private void FullDoWork(string argZero, Model? model, PredictorModel? predictorModel, string propertyRoot, long ticks, A_Property propertyLogic, int t, Container[] containers) + private Item[] GetFilterItems(Container container) + { + List results = new(); + foreach (Item item in container.Items) + { + if (item.ImageFileHolder is not null + && (item.Abandoned is null || !item.Abandoned.Value) + && item.ValidImageFormatExtension + && !_Configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered)) + results.Add(item); + } + return results.ToArray(); + } + + private void FullDoWork( + string argZero, + Model? model, + PredictorModel? predictorModel, + string propertyRoot, + long ticks, + A_Property propertyLogic, + int t, + Container[] containers) { if (_Log is null) throw new NullReferenceException(nameof(_Log)); @@ -613,7 +824,7 @@ public partial class DlibDotNet string d2ResultsFullGroupDirectory; int containersLength = containers.Length; Shared.Models.Property[] propertyCollection; - List?> imageFaceCollections = new(); + List?> imageFaceCollections = new(); List propertyFileHolderCollection = new(); List> resizeKeyValuePairs = new(); List> sourceDirectoryChanges = new(); @@ -626,7 +837,15 @@ public partial class DlibDotNet total = 0; _FileKeyValuePairs.Clear(); _FilePropertiesKeyValuePairs.Clear(); - (aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory) = GetResultsFullGroupDirectories(model, predictorModel, outputResolution); + (aResultsFullGroupDirectory, + bResultsFullGroupDirectory, + cResultsFullGroupDirectory, + dResultsFullGroupDirectory, + d2ResultsFullGroupDirectory, + eResultsFullGroupDirectory) = GetResultsFullGroupDirectories( + model, + predictorModel, + outputResolution); _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "()")); for (int i = 0; i < containers.Length; i++) { @@ -635,7 +854,7 @@ public partial class DlibDotNet continue; if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero)) continue; - filteredItems = (from l in container.Items where l.ImageFileHolder is not null && (l.Abandoned is null || !l.Abandoned.Value) && l.ValidImageFormatExtension && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.ExtensionLowered) select l).ToArray(); + filteredItems = GetFilterItems(container); if (!filteredItems.Any()) continue; metadataCollection.Clear(); @@ -647,7 +866,23 @@ public partial class DlibDotNet totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); message = $"{i + 1:000}.{container.G} [{filteredItems.Length:000} files] / {containersLength:000} - {total} / {t} total files - {totalSeconds} total second(s) - {outputResolution} - {container.SourceDirectory}"; SetAngleBracketCollections(propertyLogic, outputResolution, container, aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory); - exceptionCount = FullParallelWork(maxDegreeOfParallelism, propertyLogic, outputResolution, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, sourceDirectoryChanges, propertyFileHolderCollection, nullablePropertyCollection, metadataCollection, resizeKeyValuePairs, imageFaceCollections, container, filteredItems, message); + exceptionCount = FullParallelWork( + maxDegreeOfParallelism, + propertyLogic, + outputResolution, + bResultsFullGroupDirectory, + cResultsFullGroupDirectory, + dResultsFullGroupDirectory, + d2ResultsFullGroupDirectory, + sourceDirectoryChanges, + propertyFileHolderCollection, + nullablePropertyCollection, + metadataCollection, + resizeKeyValuePairs, + imageFaceCollections, + container, + filteredItems, + message); if (metadataCollection.Count != filteredItems.Length || nullablePropertyCollection.Count != filteredItems.Length || resizeKeyValuePairs.Count != filteredItems.Length || imageFaceCollections.Count != filteredItems.Length) throw new Exception("Counts don't match!"); if (exceptionCount != 0) @@ -684,9 +919,9 @@ public partial class DlibDotNet } } - private List SetMappingThenGetDistinctFilteredFacesWithMapping(string argZero, Container[] containers) + private List SetMappingThenGetDistinctFilteredFacesWithMapping(string argZero, Container[] containers) { - List results = new(); + List results = new(); Mapping mapping; bool? isWrongYear; Item[] filteredItems; @@ -701,7 +936,7 @@ public partial class DlibDotNet continue; if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero)) continue; - filteredItems = (from l in container.Items where l.ImageFileHolder is not null && (l.Abandoned is null || !l.Abandoned.Value) && l.ValidImageFormatExtension && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.ExtensionLowered) select l).ToArray(); + filteredItems = GetFilterItems(container); if (!filteredItems.Any()) continue; foreach (Item item in filteredItems) @@ -710,7 +945,7 @@ public partial class DlibDotNet continue; if (!item.Faces.Any()) continue; - foreach (Face face in item.Faces) + foreach (Shared.Models.Face face in item.Faces) { if (face.RelativePath != item.RelativePath) break; @@ -731,20 +966,55 @@ public partial class DlibDotNet return results; } - private void DistanceThenMapLogic(string argZero, long ticks, PersonContainer[] personContainers, Container[] containers, string dResultsFullGroupDirectory, string eResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string outputResolution) + private void DistanceThenMapLogic( + string argZero, + long ticks, + PersonContainer[] personContainers, + Container[] containers, + string dResultsFullGroupDirectory, + string eResultsFullGroupDirectory, + string d2ResultsFullGroupDirectory, + string outputResolution) { E_Distance distance = new(); if (string.IsNullOrEmpty(eResultsFullGroupDirectory)) throw new NullReferenceException(nameof(eResultsFullGroupDirectory)); - List distinctFilteredFaces = SetMappingThenGetDistinctFilteredFacesWithMapping(argZero, containers); - List selectedFilteredFaces = E_Distance.GetSelectedFilteredFaces(distinctFilteredFaces); + string eDistanceContentDirectory = Path.Combine(eResultsFullGroupDirectory, "()"); + List distinctFilteredFaces = SetMappingThenGetDistinctFilteredFacesWithMapping(argZero, containers); + List selectedFilteredFaces = E_Distance.GetSelectedFilteredFaces(distinctFilteredFaces); E_Distance.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, selectedFilteredFaces); - MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension, ticks, personContainers, eResultsFullGroupDirectory, distinctFilteredFaces, distance); - SortingContainer[] sortingContainers = E_Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, _MapConfiguration, ticks, mapLogic, selectedFilteredFaces); + string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory( + _Configuration.PropertyConfiguration, + nameof(A2_People), + "{}"); + MapLogic mapLogic = new( + _AppSettings.MaxDegreeOfParallelism, + _Configuration.PropertyConfiguration, + _MapConfiguration, + _Faces.FileNameExtension, + _Faces.HiddenFileNameExtension, + _FaceParts.FileNameExtension, + ticks, + personContainers, + eDistanceContentDirectory, + a2PeopleSingletonDirectory, + distinctFilteredFaces, + distance); + SortingContainer[] sortingContainers = E_Distance.SetFaceMappingSortingCollectionThenGetSortingContainers( + _AppSettings.MaxDegreeOfParallelism, + _MapConfiguration, + ticks, + mapLogic, + selectedFilteredFaces); E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, eResultsFullGroupDirectory, sortingContainers); int totalNotMapped = mapLogic.AddToMapping(distinctFilteredFaces); if (totalNotMapped > 0) - mapLogic.ForceSingleImageThenSaveMapping(dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, distinctFilteredFaces, sortingContainers, totalNotMapped); + mapLogic.ForceSingleImageThenSaveMapping( + dResultsFullGroupDirectory, + d2ResultsFullGroupDirectory, + distinctFilteredFaces, + sortingContainers, + totalNotMapped); mapLogic.CopyManualFiles(dResultsFullGroupDirectory, distinctFilteredFaces); if (_MapConfiguration.MappingSaveNotMapped) mapLogic.SaveNotMappedTicks(); @@ -818,7 +1088,13 @@ public partial class DlibDotNet return result; } - private void Search(long ticks, Model? model, PredictorModel? predictorModel, string argZero, string propertyRoot, PersonContainer[] personContainers) + private void Search( + long ticks, + Model? model, + PredictorModel? predictorModel, + string argZero, + string propertyRoot, + PersonContainer[] personContainers) { int j; int f; @@ -844,33 +1120,72 @@ public partial class DlibDotNet { string? newRootDirectory = SaveUrlAndGetNewRootDirectory(container); for (int i = 1; i < 10; i++) - _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, string.Empty, create: true)); + _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Property.Models.Stateless.IResult.GetResultsGroupDirectory( + _Configuration.PropertyConfiguration, + string.Empty, + create: true)); argZero = newRootDirectory; _Configuration.PropertyConfiguration.ChangeRootDirectory(newRootDirectory); - propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, nameof(A_Property), create: false); - propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, model, predictorModel); + propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory( + _Configuration.PropertyConfiguration, + nameof(A_Property), + create: false); + propertyLogic = new( + _AppSettings.MaxDegreeOfParallelism, + _Configuration.PropertyConfiguration, + _Resize.FileNameExtension, + _Configuration.Reverse, + model, + predictorModel); } FullDoWork(argZero, model, predictorModel, propertyRoot, ticks, propertyLogic, t, containers); foreach (string outputResolution in _Configuration.OutputResolutions) { if (_FirstRun || container is not null) break; - (aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory) = GetResultsFullGroupDirectories(model, predictorModel, outputResolution); - if (_ArgZeroIsConfigurationRootDirectory && _Configuration.SaveResizedSubfiles && outputResolution == _Configuration.OutputResolutions[0] && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution) && _Exceptions.Count == 0) + (aResultsFullGroupDirectory, + bResultsFullGroupDirectory, + cResultsFullGroupDirectory, + dResultsFullGroupDirectory, + d2ResultsFullGroupDirectory, + eResultsFullGroupDirectory) = GetResultsFullGroupDirectories( + model, + predictorModel, + outputResolution); + if (_ArgZeroIsConfigurationRootDirectory + && _Configuration.SaveResizedSubfiles + && outputResolution == _Configuration.OutputResolutions[0] + && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution) + && _Exceptions.Count == 0) { if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any()) break; - DistanceThenMapLogic(argZero, ticks, personContainers, containers, dResultsFullGroupDirectory, eResultsFullGroupDirectory, d2ResultsFullGroupDirectory, outputResolution); + DistanceThenMapLogic( + argZero, + ticks, + personContainers, + containers, + dResultsFullGroupDirectory, + eResultsFullGroupDirectory, + d2ResultsFullGroupDirectory, + outputResolution); if (_IsEnvironment.Development) continue; if (_FileKeyValuePairs.Any()) _Random.Random(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], _FileKeyValuePairs); G2_Identify identify = new(_Configuration); - List identifiedCollection = identify.GetIdentifiedCollection(_IsEnvironment, _Configuration.PropertyConfiguration, _Faces.FileNameExtension); - A2_People.WriteAllText(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], identifiedCollection); + List identifiedCollection = identify.GetIdentifiedCollection( + _IsEnvironment, + _Configuration.PropertyConfiguration, + _Faces.FileNameExtension); identify.WriteAllText(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], identifiedCollection); if (_Configuration.LoadOrCreateThenSaveIndex && _FilePropertiesKeyValuePairs.Any()) - _Index.SetIndex(_Configuration.PropertyConfiguration, model, predictorModel, _Configuration.OutputResolutions[0], _FilePropertiesKeyValuePairs); + _Index.SetIndex( + _Configuration.PropertyConfiguration, + model, + predictorModel, + _Configuration.OutputResolutions[0], + _FilePropertiesKeyValuePairs); } if (!_IsEnvironment.Development) { @@ -887,6 +1202,9 @@ public partial class DlibDotNet } } - internal void RenameQueue(Model? model, PredictorModel? predictorModel) => _Rename.RenameQueue(_Configuration.PropertyConfiguration, model, predictorModel); + internal void RenameQueue(Model? model, PredictorModel? predictorModel) => _Rename.RenameQueue( + _Configuration.PropertyConfiguration, + model, + predictorModel); } \ No newline at end of file diff --git a/Instance/Instance.csproj b/Instance/Instance.csproj index 6ef8809..11c4b95 100644 --- a/Instance/Instance.csproj +++ b/Instance/Instance.csproj @@ -54,6 +54,9 @@ + + + diff --git a/Instance/Models/_A2_People.cs b/Instance/Models/_A2_People.cs index 7f74b66..50f8c2f 100644 --- a/Instance/Models/_A2_People.cs +++ b/Instance/Models/_A2_People.cs @@ -1,60 +1,7 @@ -using System.Text.Json; -using View_by_Distance.Shared.Models; - namespace View_by_Distance.Instance.Models; /// // ? /// internal class A2_People -{ - - internal static void WriteAllText(Property.Models.Configuration configuration, string outputResolution, List identifiedCollection) - { - string key; - string json; - string jsonFile; - FileInfo fileInfo; - string[] segments; - string directoryFullName; - Dictionary> keyValuePairs = new(); - JsonSerializerOptions writeIndentedJsonSerializerOptions = new() { WriteIndented = true }; - string a2PeopleCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People), "[]"); - string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(Property.Models.A_Property), "{}"); - foreach (G2_Identify identified in identifiedCollection) - { - fileInfo = new FileInfo(string.Concat(aPropertySingletonDirectory, identified.RelativePath)); - if (fileInfo?.Directory is null || !fileInfo.Directory.Exists || fileInfo.Exists) - continue; - key = string.Concat(identified.ParentDirectoryName, '|', identified.Person); - if (!keyValuePairs.ContainsKey(key)) - keyValuePairs.Add(key, new List()); - keyValuePairs[key].Add(identified); - } - foreach (KeyValuePair> keyValuePair in keyValuePairs) - { - segments = keyValuePair.Key.Split('|'); - directoryFullName = Path.Combine(a2PeopleCollectionDirectory, segments[0]); - if (!Directory.Exists(directoryFullName)) - _ = Directory.CreateDirectory(directoryFullName); - jsonFile = Path.Combine(directoryFullName, $"{segments[1]}.json"); - json = JsonSerializer.Serialize(keyValuePair.Value, writeIndentedJsonSerializerOptions); - if (!Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true)) - continue; - } - } - - internal static PersonContainer[] GetPersonContainers(Configuration configuration, Property.Models.Configuration propertyConfiguration, string facesFileNameExtension) - { - PersonContainer[] results; - string rootDirectory = propertyConfiguration.RootDirectory; - string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A2_People)); - string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory)); - if (rootResultsDirectory is null) - throw new Exception(); - Storage storage = new(rootDirectory, rootResultsDirectory, peopleRootDirectory); - results = Shared.Models.Stateless.Methods.IPersonContainer.GetPersonContainers(storage, configuration.LocationDigits, configuration.PersonBirthdayFormat, facesFileNameExtension); - return results; - } - -} \ No newline at end of file +{ } \ No newline at end of file diff --git a/Instance/Models/_E2_Navigate.cs b/Instance/Models/_E2_Navigate.cs index b07abff..3f0b41c 100644 --- a/Instance/Models/_E2_Navigate.cs +++ b/Instance/Models/_E2_Navigate.cs @@ -1,4 +1,6 @@ using System.Text.Json; +using View_by_Distance.Distance.Models; +using View_by_Distance.Face.Models; using View_by_Distance.Instance.Models.Stateless; using View_by_Distance.Metadata.Models; using View_by_Distance.Resize.Models; diff --git a/Instance/Models/_E3_Rename.cs b/Instance/Models/_E3_Rename.cs index 1fa7923..fc5f1d8 100644 --- a/Instance/Models/_E3_Rename.cs +++ b/Instance/Models/_E3_Rename.cs @@ -1,4 +1,7 @@ using System.Text.Json; +using View_by_Distance.Distance.Models; +using View_by_Distance.Face.Models; +using View_by_Distance.FaceParts.Models; using View_by_Distance.Metadata.Models; using View_by_Distance.Resize.Models; using View_by_Distance.Shared.Models.Stateless; diff --git a/Instance/Models/_G2_Identify.cs b/Instance/Models/_G2_Identify.cs index 9366b98..cf7a4d9 100644 --- a/Instance/Models/_G2_Identify.cs +++ b/Instance/Models/_G2_Identify.cs @@ -67,7 +67,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify return result; } - private void CheckLastWriteTimes(IsEnvironment isEnvironment, Property.Models.Configuration configuration, string facesFileNameExtension, FileInfo named, string g2IdentifySingletonDirectory) + private void CheckLastWriteTimes(IsEnvironment isEnvironment, string facesFileNameExtension, FileInfo named, string g2IdentifySingletonDirectory) { string json; FileInfo fileInfo; @@ -88,7 +88,13 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify } json = File.ReadAllText(named.FullName); Dictionary resultKeyValuePairs = new(); - PersonContainer[] personContainers = A2_People.GetPersonContainers(_Configuration, configuration, facesFileNameExtension); + string rootDirectory = _Configuration.PropertyConfiguration.RootDirectory; + string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People)); + string rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory)); + if (rootResultsDirectory is null) + throw new Exception(); + Storage storage = new(rootDirectory, rootResultsDirectory, peopleRootDirectory); + PersonContainer[] personContainers = Shared.Models.Stateless.Methods.IPersonContainer.GetPersonContainers(storage, _Configuration.LocationDigits, _Configuration.PersonBirthdayFormat, facesFileNameExtension); string[] peopleBirthDates = (from l in personContainers select Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, l.Person.Birthday)).ToArray(); Dictionary sourceKeyValuePairs = JsonSerializer.Deserialize>(json); foreach (KeyValuePair keyValuePair in sourceKeyValuePairs) @@ -125,7 +131,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify string g2IdentifySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(G2_Identify), "[]"); string jsonRootDirectory = Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, " - Copied"), string.Concat(directoryName, " - 4) Info"), _Configuration.PropertyConfiguration.DateGroup, "[]"); if (named is not null && named.Exists) - CheckLastWriteTimes(isEnvironment, configuration, facesFileNameExtension, named, g2IdentifySingletonDirectory); + CheckLastWriteTimes(isEnvironment, facesFileNameExtension, named, g2IdentifySingletonDirectory); if (Directory.Exists(jsonRootDirectory)) { jsonFiles = Directory.GetFiles(jsonRootDirectory, "*.json", SearchOption.AllDirectories); diff --git a/Instance/appsettings.Development.json b/Instance/appsettings.Development.json index fdf03f3..1c56fec 100644 --- a/Instance/appsettings.Development.json +++ b/Instance/appsettings.Development.json @@ -53,7 +53,7 @@ "CheckDFaceAndUpWriteDates": true, "CheckJsonForDistanceResults": false, "CrossDirectoryMaxItemsInDistanceCollection": 7, - "DateGroup": "2022-09-15", + "DateGroup": "2022-09-22", "DistanceFactor": 8, "FaceDistanceHiddenImageFactor": 2, "FaceDistanceMinimumConfidence": 0.8, @@ -108,7 +108,7 @@ "ResultSingleton": "{}", "Reverse": false, "xRootDirectory": "C:/Tmp/phares/Pictures", - "RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-09-15 - 7390c13 - III", + "RootDirectory": "F:/Tmp/Phares/Compare/Images 2022-09-22 - fb1c68e - III", "SaveFullYearOfRandomFiles": true, "SaveResizedSubFiles": true, "SkipSearch": false, diff --git a/Instance/appsettings.Staging.json b/Instance/appsettings.Staging.json index 9203456..9f99d43 100644 --- a/Instance/appsettings.Staging.json +++ b/Instance/appsettings.Staging.json @@ -53,7 +53,7 @@ "CheckDFaceAndUpWriteDates": true, "CheckJsonForDistanceResults": false, "CrossDirectoryMaxItemsInDistanceCollection": 7, - "DateGroup": "2022-09-15", + "DateGroup": "2022-09-22", "DistanceFactor": 8, "FaceDistanceHiddenImageFactor": 2, "FaceDistanceMinimumConfidence": 0.8, diff --git a/Instance/appsettings.json b/Instance/appsettings.json index ed1642b..9351574 100644 --- a/Instance/appsettings.json +++ b/Instance/appsettings.json @@ -53,7 +53,7 @@ "CheckDFaceAndUpWriteDates": true, "CheckJsonForDistanceResults": false, "CrossDirectoryMaxItemsInDistanceCollection": 7, - "DateGroup": "2022-09-15", + "DateGroup": "2022-09-22", "DistanceFactor": 8, "FaceDistanceHiddenImageFactor": 2, "FaceDistanceMinimumConfidence": 0.8, diff --git a/Map/Models/MapLogic.cs b/Map/Models/MapLogic.cs index 1facd5d..2e4155b 100644 --- a/Map/Models/MapLogic.cs +++ b/Map/Models/MapLogic.cs @@ -28,7 +28,7 @@ public class MapLogic private readonly string _FacesHiddenFileNameExtension; private readonly string _EDistanceContentTicksDirectory; - public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string facesFileNameExtension, string facesHiddenFileNameExtension, string facePartsFileNameExtension, long ticks, PersonContainer[] personContainers, string eResultsFullGroupDirectory, List distinctFilteredFaces, Shared.Models.Methods.IFaceDistance? faceDistance) + public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string facesFileNameExtension, string facesHiddenFileNameExtension, string facePartsFileNameExtension, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, List distinctFilteredFaces, Shared.Models.Methods.IFaceDistance? faceDistance) { _Ticks = ticks; _Configuration = configuration; @@ -49,7 +49,6 @@ public class MapLogic Dictionary> skipCollection = new(); List notMappedPersonContainers = new(); Dictionary personKeyToPersonContainer = new(); - string eDistanceContentDirectory = Path.Combine(eResultsFullGroupDirectory, "()"); string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory); Dictionary personKeyToRanges = new(); string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, $"({ticks})"); @@ -71,6 +70,7 @@ public class MapLogic facesFileNameExtension, ticks, personContainerCollection, + a2PeopleSingletonDirectory, eDistanceContentDirectory, distinctFilteredFaces, faceDistance, @@ -102,8 +102,8 @@ public class MapLogic _IdThenNormalizedPixelPercentageToPersonContainers = idThenNormalizedPixelPercentageToPersonContainers; } - public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string outputExtension, long ticks, PersonContainer[] personContainers, string eResultsFullGroupDirectory) : - this(maxDegreeOfParallelism, propertyConfiguration, configuration, outputExtension, outputExtension, outputExtension, ticks, personContainers, eResultsFullGroupDirectory, new(), null) + public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string outputExtension, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) : + this(maxDegreeOfParallelism, propertyConfiguration, configuration, outputExtension, outputExtension, outputExtension, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, new(), null) { } public override string ToString() diff --git a/Map/Models/Stateless/MapLogic.cs b/Map/Models/Stateless/MapLogic.cs index 9596109..c6e1a34 100644 --- a/Map/Models/Stateless/MapLogic.cs +++ b/Map/Models/Stateless/MapLogic.cs @@ -612,7 +612,7 @@ internal abstract class MapLogic } } - internal static void Set(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string facesFileNameExtension, long ticks, List personContainers, string eDistanceContentDirectory, List distinctFilteredFaces, Shared.Models.Methods.IFaceDistance faceDistance, Dictionary personKeyToPersonContainer, Dictionary personKeyToRanges, List notMappedPersonContainers, Dictionary> skipCollection, Dictionary> idThenNormalizedPixelPercentageToPersonContainers) + internal static void Set(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string facesFileNameExtension, long ticks, List personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, List distinctFilteredFaces, Shared.Models.Methods.IFaceDistance faceDistance, Dictionary personKeyToPersonContainer, Dictionary personKeyToRanges, List notMappedPersonContainers, Dictionary> skipCollection, Dictionary> idThenNormalizedPixelPercentageToPersonContainers) { if (configuration is null) throw new NullReferenceException(nameof(configuration)); @@ -696,6 +696,7 @@ internal abstract class MapLogic propertyConfiguration, configuration.PersonBirthdayFormat, facesFileNameExtension, + a2PeopleSingletonDirectory, personKeyToPersonContainer, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer); } diff --git a/Metadata/Models/B_Metadata.cs b/Metadata/Models/B_Metadata.cs index b0d60d3..538bd89 100644 --- a/Metadata/Models/B_Metadata.cs +++ b/Metadata/Models/B_Metadata.cs @@ -44,8 +44,8 @@ public class B_Metadata { object? @object; string? tagDescription; - int type = (int)IExif.Tags.Orientation; List tagNames = new(); + int type = (int)IExif.Tags.Orientation; string key = nameof(IExif.Tags.Orientation); IReadOnlyList directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(subFile); foreach (MetadataExtractor.Directory directory in directories) diff --git a/Not-Copy-Copy/appsettings.Development.json b/Not-Copy-Copy/appsettings.Development.json index e9aa783..2b3190c 100644 --- a/Not-Copy-Copy/appsettings.Development.json +++ b/Not-Copy-Copy/appsettings.Development.json @@ -50,7 +50,7 @@ "WorkingDirectoryName": "PharesApps", "Windows": { "Configuration": { - "DateGroup": "2022-09-15", + "DateGroup": "2022-09-22", "FileNameDirectorySeparator": ".Z.", "ForcePropertyLastWriteTimeToCreationTime": false, "MaxImagesInDirectoryForTopLevelFirstPass": 10, diff --git a/PrepareForOld/appsettings.Development.json b/PrepareForOld/appsettings.Development.json index 2156f61..c6f654c 100644 --- a/PrepareForOld/appsettings.Development.json +++ b/PrepareForOld/appsettings.Development.json @@ -50,7 +50,7 @@ "WorkingDirectoryName": "PharesApps", "Windows": { "Configuration": { - "DateGroup": "2022-09-15", + "DateGroup": "2022-09-22", "FileNameDirectorySeparator": ".Z.", "ForcePropertyLastWriteTimeToCreationTime": false, "KeepFullPath": false, diff --git a/Shared/Models/Methods/IFaceDistance.cs b/Shared/Models/Methods/IFaceDistance.cs index 6040ec0..3f83cd6 100644 --- a/Shared/Models/Methods/IFaceDistance.cs +++ b/Shared/Models/Methods/IFaceDistance.cs @@ -4,6 +4,6 @@ public interface IFaceDistance { List GetMatchingFaces(double faceDistanceTolerance, string checkFile, List faces); - void SavePossiblyNewPersonContainers(Properties.IPropertyConfiguration propertyConfiguration, string personBirthdayFormat, string facesFileNameExtension, Dictionary personKeyToPersonContainer, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer); + void SavePossiblyNewPersonContainers(Properties.IPropertyConfiguration propertyConfiguration, string personBirthdayFormat, string facesFileNameExtension, string a2PeopleContentDirectory, Dictionary personKeyToPersonContainer, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer); } \ No newline at end of file diff --git a/View-by-Distance-MKLink-Console.sln b/View-by-Distance-MKLink-Console.sln index 693edbc..a66c5b4 100644 --- a/View-by-Distance-MKLink-Console.sln +++ b/View-by-Distance-MKLink-Console.sln @@ -31,6 +31,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Map", "Map\Map.csproj", "{9 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Instance", "Instance\Instance.csproj", "{8085C1EE-C4DB-43DE-8888-1C956D69CF91}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Distance", "Distance\Distance.csproj", "{8D444B55-933C-40CD-B7FC-226136F16138}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Face", "Face\Face.csproj", "{A12E19E5-59C0-40D4-B807-DF1334D4906D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaceParts", "FaceParts\FaceParts.csproj", "{919525B1-60BA-40C6-BA66-6F7F4C526E01}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -96,5 +102,17 @@ Global {8085C1EE-C4DB-43DE-8888-1C956D69CF91}.Debug|Any CPU.Build.0 = Debug|Any CPU {8085C1EE-C4DB-43DE-8888-1C956D69CF91}.Release|Any CPU.ActiveCfg = Release|Any CPU {8085C1EE-C4DB-43DE-8888-1C956D69CF91}.Release|Any CPU.Build.0 = Release|Any CPU + {8D444B55-933C-40CD-B7FC-226136F16138}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D444B55-933C-40CD-B7FC-226136F16138}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D444B55-933C-40CD-B7FC-226136F16138}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D444B55-933C-40CD-B7FC-226136F16138}.Release|Any CPU.Build.0 = Release|Any CPU + {A12E19E5-59C0-40D4-B807-DF1334D4906D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A12E19E5-59C0-40D4-B807-DF1334D4906D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A12E19E5-59C0-40D4-B807-DF1334D4906D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A12E19E5-59C0-40D4-B807-DF1334D4906D}.Release|Any CPU.Build.0 = Release|Any CPU + {919525B1-60BA-40C6-BA66-6F7F4C526E01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {919525B1-60BA-40C6-BA66-6F7F4C526E01}.Debug|Any CPU.Build.0 = Debug|Any CPU + {919525B1-60BA-40C6-BA66-6F7F4C526E01}.Release|Any CPU.ActiveCfg = Release|Any CPU + {919525B1-60BA-40C6-BA66-6F7F4C526E01}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal