From aa8de2b98550e9e52633893e90a29329c4d598c4 Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Sat, 5 Jul 2025 22:30:19 -0700 Subject: [PATCH] Removed Rectangle from LocationContainer mapped-ids-then-whole-percentages-to-location-container save-extract-faces --- Compare/Compare.cs | 108 +++++++++++++++++++++- Compare/Models/CompareSettings.cs | 3 +- Distance/Models/Stateless/FilterLogicA.cs | 8 +- Distance/Models/Stateless/FilterLogicB.cs | 47 +++++----- Distance/Models/Stateless/FilterLogicC.cs | 14 +-- Distance/Models/Stateless/IDistance.cs | 24 ++--- Distance/Models/Stateless/MappedLogicA.cs | 31 ++++--- Shared/Models/LocationContainer.cs | 9 +- Shared/Models/Stateless/ILocation.cs | 5 - Shared/Models/Stateless/Location.cs | 32 +------ 10 files changed, 173 insertions(+), 108 deletions(-) diff --git a/Compare/Compare.cs b/Compare/Compare.cs index 32129e1..33547be 100644 --- a/Compare/Compare.cs +++ b/Compare/Compare.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Logging; using ShellProgressBar; using System.Collections.ObjectModel; +using System.Drawing; using View_by_Distance.Compare.Models; using View_by_Distance.Distance.Models.Stateless; using View_by_Distance.Face.Models.Stateless; @@ -63,21 +64,25 @@ public partial class Compare : ICompare, IDisposable bool runToDoCollectionFirst = GetRunToDoCollectionFirst(appSettings, compare); ReadOnlyCollections readOnlyCollections = GetReadOnlyCollections(appSettings); ReadOnlyCollection mappedExifDirectoryWithEncoding = GetMappedExifDirectoryWithEncoding(appSettings, compare, readOnlyCollections); - ReadOnlyDictionary> keyValuePairs = IDistance.Extract(appSettings.CompareSettings, mappedExifDirectoryWithEncoding); + ReadOnlyDictionary> mappedIdsThenWholePercentagesToLocationContainer = IDistance.Extract(appSettings.DistanceSettings, appSettings.CompareSettings, compare, mappedExifDirectoryWithEncoding); + if (appSettings.CompareSettings.SaveExtractFaces) + SaveExtractFaces(appSettings, mappedIdsThenWholePercentagesToLocationContainer); foreach (string outputResolution in appSettings.CompareSettings.OutputResolutions) { if (runToDoCollectionFirst || outputResolution.Any(char.IsNumber)) continue; logger?.LogInformation("{outputResolution}", outputResolution); exifDirectories = IFace.GetExifDirectories(appSettings.ResultSettings, appSettings.MetadataSettings, appSettings.DistanceSettings, appSettings.CompareSettings, compare, outputResolution); - preFiltered = IDistance.GetPreFilterLocationContainer(appSettings.DistanceSettings, appSettings.CompareSettings, compare, readOnlyCollections, keyValuePairs, exifDirectories); + preFiltered = IDistance.GetPreFilterLocationContainer(appSettings.DistanceSettings, appSettings.CompareSettings, compare, readOnlyCollections, mappedIdsThenWholePercentagesToLocationContainer, exifDirectories); if (preFiltered.Count == 0) continue; + if (appSettings.CompareSettings.SaveExtractFaces) + SaveExtractFaces(appSettings, preFiltered); distanceLimits = new(appSettings.DistanceSettings); postFiltered = IDistance.GetPostFilterLocationContainer(preFiltered, distanceLimits); if (postFiltered.Count == 0) continue; - matrix = IDistance.GetMatrixLocationContainers(appSettings.DistanceSettings, appSettings.CompareSettings, compare, mappedExifDirectoryWithEncoding, distanceLimits, postFiltered); + matrix = IDistance.GetMatrixLocationContainers(appSettings.DistanceSettings, compare, mappedIdsThenWholePercentagesToLocationContainer, distanceLimits, postFiltered); if (matrix.Count == 0) continue; onlyOne = IDistance.GetOnlyOne(appSettings.DistanceSettings, matrix); @@ -167,4 +172,101 @@ public partial class Compare : ICompare, IDisposable return results; } + private void SaveExtractFaces(AppSettings appSettings, ReadOnlyDictionary> mappedIdsThenWholePercentagesToLocationContainer) + { + ReadOnlyCollection? paths; + ReadOnlyDictionary> rootDirectoryFileNameToPaths = GetRootDirectoryFileNameToPaths(appSettings.ResultSettings, appSettings.CompareSettings); + foreach (KeyValuePair> keyValuePair in mappedIdsThenWholePercentagesToLocationContainer) + { + foreach (KeyValuePair keyValue in keyValuePair.Value) + { + if (keyValue.Value.ExifDirectory is null || keyValue.Value.FaceFile?.Location is null) + continue; + if (rootDirectoryFileNameToPaths.TryGetValue(keyValue.Value.FilePath.FileNameFirstSegment, out paths)) + ExtractFace(keyValuePair.Key, keyValue.Key, keyValue.Value.ExifDirectory, keyValue.Value.FaceFile.Location, keyValue.Value.PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName, paths); + } + } + } + + private static void SaveExtractFaces(AppSettings appSettings, ReadOnlyCollection preFiltered) + { + ReadOnlyCollection? paths; + ReadOnlyDictionary> rootDirectoryFileNameToPaths = GetRootDirectoryFileNameToPaths(appSettings.ResultSettings, appSettings.CompareSettings); + foreach (LocationContainer locationContainer in preFiltered) + { + if (locationContainer?.FilePath?.Id is null || locationContainer?.WholePercentages is null || locationContainer?.ExifDirectory is null || locationContainer?.FaceFile?.Location is null) + continue; + if (rootDirectoryFileNameToPaths.TryGetValue(locationContainer.FilePath.FileNameFirstSegment, out paths)) + ExtractFace(locationContainer.FilePath.Id.Value, locationContainer.WholePercentages.Value, locationContainer.ExifDirectory, locationContainer.FaceFile.Location, locationContainer.PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName, paths); + } + } + + private static ReadOnlyDictionary> GetRootDirectoryFileNameToPaths(ResultSettings resultSettings, CompareSettings compareSettings) + { + Dictionary> results = []; + string key; + string extension; + List? collection; + Dictionary> keyValuePairs = []; + string[] files = !compareSettings.SaveExtractFaces ? [] : Directory.GetFiles(resultSettings.RootDirectory, "*", SearchOption.AllDirectories); + foreach (string file in files) + { + extension = Path.GetExtension(file); + if (resultSettings.IgnoreExtensions.Contains(extension)) + continue; + key = Path.GetFileNameWithoutExtension(file); + if (!keyValuePairs.TryGetValue(key, out collection)) + { + keyValuePairs.Add(key, []); + if (!keyValuePairs.TryGetValue(key, out collection)) + throw new Exception(); + } + collection.Add(file); + } + foreach (KeyValuePair> keyValuePair in keyValuePairs) + results.Add(keyValuePair.Key, keyValuePair.Value.AsReadOnly()); + return results.AsReadOnly(); + } + + private static void ExtractFace(int id, int wholePercentages, ExifDirectory _, Location location, PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName? __, ReadOnlyCollection paths) + { + int width; + int height; + foreach (string path in paths) + { + // RectangleF? rectangleF = Shared.Models.Stateless.ILocation.GetPercentagesRectangle(faceFile); + // if (rectangleF is null) + // return; + // RectangleF? rectangle = Shared.Models.Stateless.ILocation.GetPercentagesRectangle(distanceSettings, wholePercentages.Value); + // if (rectangle is null) + // return; + // if (rectangleF.Value.X != rectangle.Value.X + // || rectangleF.Value.Y != rectangle.Value.Y + // || rectangleF.Value.Height != rectangle.Value.Height + // || rectangleF.Value.Width != rectangle.Value.Width) + // return; + // RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value); + // if (rectangle is null) + // return; + width = location.Right - location.Left; + height = location.Bottom - location.Top; + ExtractFace(file: path, + width: width, + height: height, + left: location.Left, + top: location.Top, + suffix: $"-{id}-{wholePercentages}-face.jpg"); + } + } + + private static void ExtractFace(string file, float width, float height, double left, double top, string suffix) + { + RectangleF rectangle = new((float)left, (float)top, width, height); + using Bitmap source = new(file); + using Bitmap bitmap = new((int)width, (int)height); + using (Graphics graphics = Graphics.FromImage(bitmap)) + graphics.DrawImage(source, new RectangleF(0, 0, width, height), rectangle, GraphicsUnit.Pixel); + bitmap.Save($"{file}{suffix}"); + } + } \ No newline at end of file diff --git a/Compare/Models/CompareSettings.cs b/Compare/Models/CompareSettings.cs index 98214cd..9629d21 100644 --- a/Compare/Models/CompareSettings.cs +++ b/Compare/Models/CompareSettings.cs @@ -9,7 +9,8 @@ public record CompareSettings(string Company, string FacesHiddenFileNameExtension, string FacesPartsFileNameExtension, int MaxDegreeOfParallelism, - string[] OutputResolutions) : Shared.Models.Properties.ICompareSettings + string[] OutputResolutions, + bool SaveExtractFaces) : Shared.Models.Properties.ICompareSettings { public override string ToString() diff --git a/Distance/Models/Stateless/FilterLogicA.cs b/Distance/Models/Stateless/FilterLogicA.cs index c74c9ac..0b4e4b2 100644 --- a/Distance/Models/Stateless/FilterLogicA.cs +++ b/Distance/Models/Stateless/FilterLogicA.cs @@ -32,7 +32,7 @@ internal static class FilterLogicA return result; } - internal static ReadOnlyCollection GetPreFilterLocationContainer(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollections readOnlyCollections, ReadOnlyDictionary> keyValuePairs, ReadOnlyCollection exifDirectories) + internal static ReadOnlyCollection GetPreFilterLocationContainer(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollections readOnlyCollections, ReadOnlyDictionary> mappedIdsThenWholePercentagesToLocationContainer, ReadOnlyCollection exifDirectories) { List results = []; string? json; @@ -41,8 +41,8 @@ internal static class FilterLogicA bool? isFocusPerson; bool? inSkipCollection; FaceEncoding? faceEncoding; - ReadOnlyDictionary? keyValues; FaceRecognitionDotNet.Models.FaceEncoding? encoding; + ReadOnlyDictionary? keyValues; List? wholePercentagesCollection; ReadOnlyCollection locationContainers = FilterLogicB.GetLocationContainers(distanceSettings, compareSettings, compare, exifDirectories, nameof(FilterLogicA)); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - compare.Ticks).TotalSeconds); @@ -53,7 +53,7 @@ internal static class FilterLogicA compare.Tick(); if (locationContainer.FilePath.Id is null || locationContainer.WholePercentages is null) continue; - if (keyValuePairs.TryGetValue(locationContainer.FilePath.Id.Value, out keyValues)) + if (mappedIdsThenWholePercentagesToLocationContainer.TryGetValue(locationContainer.FilePath.Id.Value, out keyValues)) { if (keyValues.ContainsKey(locationContainer.WholePercentages.Value)) continue; @@ -85,7 +85,7 @@ internal static class FilterLogicA if (faceEncoding is null) continue; encoding = FaceRecognitionDotNet.Models.FaceRecognition.LoadFaceEncoding(faceEncoding.RawEncoding); - results.Add(LocationContainer.Get(locationContainer, encoding, keepExifDirectory: false)); + results.Add(LocationContainer.Get(locationContainer, encoding)); } return results.AsReadOnly(); } diff --git a/Distance/Models/Stateless/FilterLogicB.cs b/Distance/Models/Stateless/FilterLogicB.cs index f36d0a5..513bd5b 100644 --- a/Distance/Models/Stateless/FilterLogicB.cs +++ b/Distance/Models/Stateless/FilterLogicB.cs @@ -1,5 +1,4 @@ using System.Collections.ObjectModel; -using System.Drawing; using System.Text.Json; using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Properties; @@ -17,12 +16,25 @@ internal static class FilterLogicB File.Move(filePath.FullName, checkFile); } - private static void LocationContainersParallelFor(DistanceSettings distanceSettings, ICompareSettings compareSettings, List locationContainers, ExifDirectory exifDirectory) + internal static ReadOnlyCollection GetLocationContainers(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollection exifDirectories, string sourceClass) { - string? json; + List results = []; + int maxDegreeOfParallelism = compareSettings.MaxDegreeOfParallelism; + ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism }; + int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - compare.Ticks).TotalSeconds); + string message = $") Building LocationContainers Face Files Collection {sourceClass} - {totalSeconds} total second(s)"; + compare.ConstructProgressBar(exifDirectories.Count, message); + _ = Parallel.For(0, exifDirectories.Count, parallelOptions, (i, state) => + LocationContainersParallelFor(distanceSettings, compareSettings, compare, exifDirectories, i, results)); + return results.AsReadOnly(); + } + + private static void LocationContainersParallelFor(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollection exifDirectories, int i, List results) + { + compare.Tick(); + ExifDirectory exifDirectory = exifDirectories[i]; if (exifDirectory.FilePath.Id is null) return; - DateOnly dateOnly = DateOnly.FromDateTime(new DateTime(exifDirectory.FilePath.CreationTicks)); int? wholePercentages = IMapping.GetWholePercentages(compareSettings, exifDirectory.FilePath); if (wholePercentages is null) { @@ -30,6 +42,13 @@ internal static class FilterLogicB MoveUnableToMatch(exifDirectory.FilePath); return; } + LocationContainersParallelFor(distanceSettings, results, exifDirectory, wholePercentages); + } + + private static void LocationContainersParallelFor(DistanceSettings distanceSettings, List locationContainers, ExifDirectory exifDirectory, int? wholePercentages) + { + string? json; + DateOnly dateOnly = DateOnly.FromDateTime(new DateTime(exifDirectory.FilePath.CreationTicks)); json = Metadata.Models.Stateless.IMetadata.GetOutputResolution(exifDirectory); if (json is null || !json.Contains(nameof(DateTime))) { @@ -44,9 +63,6 @@ internal static class FilterLogicB MoveUnableToMatch(exifDirectory.FilePath); return; } - RectangleF? rectangle = Shared.Models.Stateless.ILocation.GetPercentagesRectangle(distanceSettings, wholePercentages.Value); - if (rectangle is null) - return; LocationContainer locationContainer = new(CreationDateOnly: dateOnly, ExifDirectory: exifDirectory, Encoding: exifDirectory.Encoding, @@ -55,26 +71,9 @@ internal static class FilterLogicB LengthPermyriad: null, LengthSource: null, PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName: exifDirectory.PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName, - Rectangle: rectangle, WholePercentages: wholePercentages); lock (locationContainers) locationContainers.Add(locationContainer); } - internal static ReadOnlyCollection GetLocationContainers(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollection exifDirectories, string sourceClass) - { - List results = []; - int maxDegreeOfParallelism = compareSettings.MaxDegreeOfParallelism; - int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - compare.Ticks).TotalSeconds); - ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism }; - string message = $") Building LocationContainers Face Files Collection {sourceClass} - {totalSeconds} total second(s)"; - compare.ConstructProgressBar(exifDirectories.Count, message); - _ = Parallel.For(0, exifDirectories.Count, parallelOptions, (i, state) => - { - compare.Tick(); - LocationContainersParallelFor(distanceSettings, compareSettings, results, exifDirectories[i]); - }); - return results.AsReadOnly(); - } - } \ No newline at end of file diff --git a/Distance/Models/Stateless/FilterLogicC.cs b/Distance/Models/Stateless/FilterLogicC.cs index ea1c4f8..6c6259c 100644 --- a/Distance/Models/Stateless/FilterLogicC.cs +++ b/Distance/Models/Stateless/FilterLogicC.cs @@ -24,22 +24,24 @@ internal static class FilterLogicC return results.AsReadOnly(); } - private static ReadOnlyCollection GetCombined(DistanceSettings distanceSettings, Shared.Models.Properties.ICompareSettings compareSettings, ICompare compare, ReadOnlyCollection exifDirectories, ReadOnlyCollection postFiltered) + private static ReadOnlyCollection GetCombined(ReadOnlyDictionary> mappedIdsThenWholePercentagesToLocationContainer, ReadOnlyCollection postFiltered) { List results = []; foreach (LocationContainer locationContainer in postFiltered) results.Add(locationContainer); - ReadOnlyCollection locationContainers = FilterLogicB.GetLocationContainers(distanceSettings, compareSettings, compare, exifDirectories, nameof(FilterLogicC)); - foreach (LocationContainer locationContainer in locationContainers) - results.Add(locationContainer); + foreach (KeyValuePair> keyValuePair in mappedIdsThenWholePercentagesToLocationContainer) + { + foreach (KeyValuePair keyValue in keyValuePair.Value) + results.Add(keyValue.Value); + } return results.AsReadOnly(); } - internal static ReadOnlyCollection GetMatrixLocationContainers(DistanceSettings distanceSettings, Shared.Models.Properties.ICompareSettings compareSettings, ICompare compare, ReadOnlyCollection mappedExifDirectoryWithEncoding, DistanceLimits distanceLimits, ReadOnlyCollection postFiltered) + internal static ReadOnlyCollection GetMatrixLocationContainers(DistanceSettings distanceSettings, ICompare compare, ReadOnlyDictionary> mappedIdsThenWholePercentagesToLocationContainer, DistanceLimits distanceLimits, ReadOnlyCollection postFiltered) { List results = []; ReadOnlyCollection collection; - ReadOnlyCollection locationContainers = GetCombined(distanceSettings, compareSettings, compare, mappedExifDirectoryWithEncoding, postFiltered); + ReadOnlyCollection locationContainers = GetCombined(mappedIdsThenWholePercentagesToLocationContainer, postFiltered); string message = $") Building Matrix - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - compare.Ticks).TotalSeconds)} total second(s)"; compare.ConstructProgressBar(postFiltered.Count, message); foreach (LocationContainer locationContainer in postFiltered) diff --git a/Distance/Models/Stateless/IDistance.cs b/Distance/Models/Stateless/IDistance.cs index bc50388..67f7777 100644 --- a/Distance/Models/Stateless/IDistance.cs +++ b/Distance/Models/Stateless/IDistance.cs @@ -29,8 +29,8 @@ public interface IDistance public static ReadOnlyCollection GetPostFilterLocationContainer(ReadOnlyCollection preFiltered, DistanceLimits distanceLimits) => FilterLogicC.GetPostFilterLocationContainer(preFiltered, distanceLimits); - public static ReadOnlyDictionary> Extract(ICompareSettings compareSettings, ReadOnlyCollection exifDirectories) => - MappedLogicA.Extract(compareSettings, exifDirectories); + public static ReadOnlyDictionary> Extract(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollection exifDirectories) => + MappedLogicA.Extract(distanceSettings, compareSettings, compare, exifDirectories); public static void SaveContainers(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, int? updated, ReadOnlyCollection saveContainers) => FilterLogicD.SaveContainers(distanceSettings, compareSettings, compare, updated, saveContainers); @@ -41,11 +41,11 @@ public interface IDistance public static ReadOnlyCollection GetMapped(ResultSettings resultSettings, MetadataSettings metadataSettings, PeopleSettings peopleSettings, DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollections readOnlyCollections) => MappedLogicA.GetMapped(resultSettings, metadataSettings, peopleSettings, distanceSettings, compareSettings, compare, readOnlyCollections); - public static ReadOnlyCollection GetMatrixLocationContainers(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollection mappedExifDirectoryWithEncoding, DistanceLimits distanceLimits, ReadOnlyCollection postFiltered) => - FilterLogicC.GetMatrixLocationContainers(distanceSettings, compareSettings, compare, mappedExifDirectoryWithEncoding, distanceLimits, postFiltered); + public static ReadOnlyCollection GetMatrixLocationContainers(DistanceSettings distanceSettings, ICompare compare, ReadOnlyDictionary> mappedIdsThenWholePercentagesToLocationContainer, DistanceLimits distanceLimits, ReadOnlyCollection postFiltered) => + FilterLogicC.GetMatrixLocationContainers(distanceSettings, compare, mappedIdsThenWholePercentagesToLocationContainer, distanceLimits, postFiltered); - public static ReadOnlyCollection GetPreFilterLocationContainer(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollections readOnlyCollections, ReadOnlyDictionary> keyValuePairs, ReadOnlyCollection exifDirectories) => - FilterLogicA.GetPreFilterLocationContainer(distanceSettings, compareSettings, compare, readOnlyCollections, keyValuePairs, exifDirectories); + public static ReadOnlyCollection GetPreFilterLocationContainer(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollections readOnlyCollections, ReadOnlyDictionary> mappedIdsThenWholePercentagesToLocationContainer, ReadOnlyCollection exifDirectories) => + FilterLogicA.GetPreFilterLocationContainer(distanceSettings, compareSettings, compare, readOnlyCollections, mappedIdsThenWholePercentagesToLocationContainer, exifDirectories); internal static ReadOnlyDictionary TestStatic_GetOnlyOne(DistanceSettings distanceSettings, ReadOnlyCollection matrix) => GetOnlyOne(distanceSettings, matrix); @@ -56,8 +56,8 @@ public interface IDistance internal static ReadOnlyCollection TestStatic_GetPostFilterLocationContainer(ReadOnlyCollection preFiltered, DistanceLimits distanceLimits) => GetPostFilterLocationContainer(preFiltered, distanceLimits); - internal static ReadOnlyDictionary> TestStatic_Extract(ICompareSettings compareSettings, ReadOnlyCollection exifDirectories) => - Extract(compareSettings, exifDirectories); + internal static ReadOnlyDictionary> TestStatic_Extract(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollection exifDirectories) => + Extract(distanceSettings, compareSettings, compare, exifDirectories); internal static void TestStatic_SaveContainers(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, int? updated, ReadOnlyCollection saveContainers) => SaveContainers(distanceSettings, compareSettings, compare, updated, saveContainers); @@ -68,10 +68,10 @@ public interface IDistance internal static ReadOnlyCollection TestStatic_GetMapped(ResultSettings resultSettings, MetadataSettings metadataSettings, PeopleSettings peopleSettings, DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollections readOnlyCollections) => GetMapped(resultSettings, metadataSettings, peopleSettings, distanceSettings, compareSettings, compare, readOnlyCollections); - internal static ReadOnlyCollection TestStatic_GetMatrixLocationContainers(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollection mappedExifDirectoryWithEncoding, DistanceLimits distanceLimits, ReadOnlyCollection postFiltered) => - GetMatrixLocationContainers(distanceSettings, compareSettings, compare, mappedExifDirectoryWithEncoding, distanceLimits, postFiltered); + internal static ReadOnlyCollection TestStatic_GetMatrixLocationContainers(DistanceSettings distanceSettings, ICompare compare, ReadOnlyDictionary> mappedIdsThenWholePercentagesToLocationContainer, DistanceLimits distanceLimits, ReadOnlyCollection postFiltered) => + GetMatrixLocationContainers(distanceSettings, compare, mappedIdsThenWholePercentagesToLocationContainer, distanceLimits, postFiltered); - internal static ReadOnlyCollection TestStatic_GetPreFilterLocationContainer(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollections readOnlyCollections, ReadOnlyDictionary> keyValuePairs, ReadOnlyCollection exifDirectories) => - GetPreFilterLocationContainer(distanceSettings, compareSettings, compare, readOnlyCollections, keyValuePairs, exifDirectories); + internal static ReadOnlyCollection TestStatic_GetPreFilterLocationContainer(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollections readOnlyCollections, ReadOnlyDictionary> mappedIdsThenWholePercentagesToLocationContainer, ReadOnlyCollection exifDirectories) => + GetPreFilterLocationContainer(distanceSettings, compareSettings, compare, readOnlyCollections, mappedIdsThenWholePercentagesToLocationContainer, exifDirectories); } \ No newline at end of file diff --git a/Distance/Models/Stateless/MappedLogicA.cs b/Distance/Models/Stateless/MappedLogicA.cs index 16d8669..67ee26e 100644 --- a/Distance/Models/Stateless/MappedLogicA.cs +++ b/Distance/Models/Stateless/MappedLogicA.cs @@ -14,28 +14,29 @@ internal static class MappedLogicA string? PersonDisplayDirectoryName, FilePath FilePath); - internal static ReadOnlyDictionary> Extract(ICompareSettings compareSettings, ReadOnlyCollection exifDirectories) + internal static ReadOnlyDictionary> Extract(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollection exifDirectories) { - Dictionary> results = []; - int? wholePercentages; - Dictionary? keyValues; - Dictionary> keyValuePairs = []; - foreach (ExifDirectory exifDirectory in exifDirectories) + Dictionary> results = []; + int id; + int wholePercentages; + Dictionary? keyValue; + Dictionary> keyValuePairs = []; + ReadOnlyCollection locationContainers = FilterLogicB.GetLocationContainers(distanceSettings, compareSettings, compare, exifDirectories, nameof(MappedLogicA)); + foreach (LocationContainer locationContainer in locationContainers) { - if (exifDirectory.FilePath.Id is null) + if (locationContainer.FilePath.Id is null || locationContainer.WholePercentages is null) continue; - if (!keyValuePairs.TryGetValue(exifDirectory.FilePath.Id.Value, out keyValues)) + id = locationContainer.FilePath.Id.Value; + wholePercentages = locationContainer.WholePercentages.Value; + if (!keyValuePairs.TryGetValue(id, out keyValue)) { - keyValuePairs.Add(exifDirectory.FilePath.Id.Value, []); - if (!keyValuePairs.TryGetValue(exifDirectory.FilePath.Id.Value, out keyValues)) + keyValuePairs.Add(id, []); + if (!keyValuePairs.TryGetValue(id, out keyValue)) throw new Exception(); } - wholePercentages = IMapping.GetWholePercentages(compareSettings, exifDirectory.FilePath); - if (wholePercentages is null) - continue; - keyValues.Add(wholePercentages.Value, exifDirectory.FilePath); + keyValue.Add(wholePercentages, locationContainer); } - foreach (KeyValuePair> keyValuePair in keyValuePairs) + foreach (KeyValuePair> keyValuePair in keyValuePairs) results.Add(keyValuePair.Key, keyValuePair.Value.AsReadOnly()); return results.AsReadOnly(); } diff --git a/Shared/Models/LocationContainer.cs b/Shared/Models/LocationContainer.cs index c474a24..da7f8f4 100644 --- a/Shared/Models/LocationContainer.cs +++ b/Shared/Models/LocationContainer.cs @@ -1,5 +1,3 @@ -using System.Drawing; - namespace View_by_Distance.Shared.Models; public record LocationContainer(DateOnly? CreationDateOnly, @@ -10,22 +8,20 @@ public record LocationContainer(DateOnly? CreationDateOnly, int? LengthPermyriad, FilePath? LengthSource, PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName? PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName, - RectangleF? Rectangle, int? WholePercentages) { - public static LocationContainer Get(LocationContainer locationContainer, object? encoding, bool keepExifDirectory) + public static LocationContainer Get(LocationContainer locationContainer, object? encoding) { LocationContainer result; result = new(CreationDateOnly: locationContainer.CreationDateOnly, - ExifDirectory: keepExifDirectory ? locationContainer.ExifDirectory : null, + ExifDirectory: locationContainer.ExifDirectory, Encoding: encoding, FaceFile: locationContainer.FaceFile, FilePath: locationContainer.FilePath, LengthPermyriad: locationContainer.LengthPermyriad, LengthSource: locationContainer.LengthSource, PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName: locationContainer.PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName, - Rectangle: locationContainer.Rectangle, WholePercentages: locationContainer.WholePercentages); return result; } @@ -41,7 +37,6 @@ public record LocationContainer(DateOnly? CreationDateOnly, LengthPermyriad: lengthPermyriad, LengthSource: source.FilePath, PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName: locationContainer.PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName, - Rectangle: locationContainer.Rectangle, WholePercentages: locationContainer.WholePercentages); return result; } diff --git a/Shared/Models/Stateless/ILocation.cs b/Shared/Models/Stateless/ILocation.cs index b494be8..8514431 100644 --- a/Shared/Models/Stateless/ILocation.cs +++ b/Shared/Models/Stateless/ILocation.cs @@ -5,11 +5,6 @@ namespace View_by_Distance.Shared.Models.Stateless; public interface ILocation { - RectangleF? TestStatic_GetPercentagesRectangle(DistanceSettings distanceSettings, int wholePercentages) => - GetPercentagesRectangle(distanceSettings, wholePercentages); - static RectangleF? GetPercentagesRectangle(DistanceSettings distanceSettings, int wholePercentages) => - Location.GetPercentagesRectangle(distanceSettings, wholePercentages); - Models.Location TestStatic_GetTrimBound(double detectionConfidence, Rectangle rectangle, int width, int height, int facesCount) => TrimBound(detectionConfidence, rectangle, width, height, facesCount); static Models.Location TrimBound(double detectionConfidence, Rectangle rectangle, int width, int height, int facesCount) => diff --git a/Shared/Models/Stateless/Location.cs b/Shared/Models/Stateless/Location.cs index cef980e..e04ebb0 100644 --- a/Shared/Models/Stateless/Location.cs +++ b/Shared/Models/Stateless/Location.cs @@ -1,6 +1,4 @@ -using System.Drawing; - -namespace View_by_Distance.Shared.Models.Stateless; +namespace View_by_Distance.Shared.Models.Stateless; internal abstract class Location { @@ -47,32 +45,4 @@ internal abstract class Location return result; } - internal static RectangleF? GetPercentagesRectangle(DistanceSettings distanceSettings, int wholePercentages) - { - RectangleF? result; - string wp = wholePercentages.ToString(); - int length = (distanceSettings.LocationDigits - 1) / 4; - string[] segments = - [ - wp[..1], - wp.Substring(1, length), - wp.Substring(3, length), - wp.Substring(5, length), - wp.Substring(7, length) - ]; - if (string.Join(string.Empty, segments) != wp) - result = null; - else - { - if (!int.TryParse(segments[1], out int xWholePercent) || !int.TryParse(segments[2], out int yWholePercent) || !int.TryParse(segments[3], out int wWholePercent) || !int.TryParse(segments[4], out int hWholePercent)) - result = null; - else - { - float factor = 100; - result = new(xWholePercent / factor, yWholePercent / factor, wWholePercent / factor, hWholePercent / factor); - } - } - return result; - } - } \ No newline at end of file