using System.Collections.ObjectModel; using System.Drawing; using System.Text; using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Methods; using View_by_Distance.Shared.Models.Properties; namespace View_by_Distance.BlurHash.Models; public class C2_BlurHasher : IBlurHasher { private readonly IPropertyConfiguration _PropertyConfiguration; private readonly ReadOnlyDictionary>[] _ResultContentFileGroups; private readonly ReadOnlyDictionary>[] _ResultSingletonFileGroups; public C2_BlurHasher(IPropertyConfiguration propertyConfiguration) { _PropertyConfiguration = propertyConfiguration; _ResultContentFileGroups = [new(new Dictionary>())]; _ResultSingletonFileGroups = [new(new Dictionary>())]; } public void Update(string resultsFullGroupDirectory) { ReadOnlyDictionary>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, resultsFullGroupDirectory, [_PropertyConfiguration.ResultContent, _PropertyConfiguration.ResultSingleton]); foreach (KeyValuePair>> keyValuePair in keyValuePairs) { if (keyValuePair.Key == _PropertyConfiguration.ResultContent) _ResultContentFileGroups[0] = keyValuePair.Value; else if (keyValuePair.Key == _PropertyConfiguration.ResultSingleton) _ResultSingletonFileGroups[0] = keyValuePair.Value; else throw new Exception(); } } string IBlurHasher.Encode(FileHolder fileHolder) { string result; #pragma warning disable CA1416 Image image = Image.FromFile(fileHolder.FullName); (int componentsX, int componentsY) = image.Width < image.Height ? (4, 3) : (3, 4); ReadOnlySpan blurHash = System.Drawing.BlurHash.BlurHasher.Encode(image, componentsX, componentsY); image.Dispose(); #pragma warning restore CA1416 result = blurHash.ToString(); return result; } private static void MoveIf(string fileName, CombinedEnumAndIndex cei, string directory, string fullFileName) { string[] segments = directory.Split(cei.Combined); string? checkDirectory = segments.Length == 1 ? Path.Combine(segments[0], $"{cei.Combined[2..]}") : segments.Length == 2 ? $"{segments[0]}{cei.Combined[2..]}{segments[1]}" : null; if (checkDirectory is not null && Directory.Exists(checkDirectory)) { string checkFile = Path.Combine(checkDirectory, fileName); if (File.Exists(checkFile)) File.Move(checkFile, fullFileName); } } string IBlurHasher.GetFile(FilePath filePath) { string result; if (_ResultSingletonFileGroups[0].Count == 0) throw new Exception("Call Update first!"); string fileName = $"{filePath.Name}.csv"; CombinedEnumAndIndex cei = Shared.Models.Stateless.Methods.IPath.GetCombinedEnumAndIndex(_PropertyConfiguration, filePath); string directory = _ResultSingletonFileGroups[0][cei.Enum][cei.Index]; result = Path.Combine(directory, fileName); MoveIf(fileName, cei, directory, result); return result; } string IBlurHasher.EncodeAndSave(FilePath filePath, FileHolder fileHolder) { string result; if (_ResultSingletonFileGroups[0].Count == 0) throw new Exception("Call Update first!"); int actualByte; string extension = ".png"; IBlurHasher blurHasher = this; string file = blurHasher.GetFile(filePath); #pragma warning disable CA1416 Image image = Image.FromFile(fileHolder.FullName); int outputWidth = (int)(image.Width * .25); int outputHeight = (int)(image.Height * .25); (int componentsX, int componentsY) = image.Width < image.Height ? (4, 3) : (3, 4); ReadOnlySpan blurHash = System.Drawing.BlurHash.BlurHasher.Encode(image, componentsX, componentsY); using Image actualImage = System.Drawing.BlurHash.BlurHasher.Decode(blurHash, outputWidth, outputHeight); result = blurHash.ToString(); byte[] blurHashBytes = Encoding.UTF8.GetBytes(result); string joined = string.Join(string.Empty, blurHashBytes.Select(l => l.ToString("000"))); string fileNameWithoutExtension = $"{componentsX}x{componentsY}-{outputWidth}x{outputHeight}-{joined}"; string fileName = $"{fileNameWithoutExtension}{extension}"; string contents = string.Concat(result, Environment.NewLine, fileNameWithoutExtension, Environment.NewLine, extension); _ = Shared.Models.Stateless.Methods.IPath.WriteAllText(file, contents, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null); CombinedEnumAndIndex cei = Shared.Models.Stateless.Methods.IPath.GetCombinedEnumAndIndex(_PropertyConfiguration, filePath); string directory = _ResultContentFileGroups[0][cei.Enum][cei.Index]; string fullFileName = Path.Combine(directory, fileName); MoveIf(fileName, cei, directory, fullFileName); if (!File.Exists(fullFileName)) { try { using FileStream fileStream = new(fullFileName, FileMode.CreateNew); actualImage.Save(fileStream, System.Drawing.Imaging.ImageFormat.Png); _ = fileStream.Seek(0, SeekOrigin.Begin); actualByte = fileStream.ReadByte(); while (actualByte > -1) actualByte = fileStream.ReadByte(); } catch (Exception) { } } image.Dispose(); #pragma warning restore CA1416 result = blurHash.ToString(); return result; } }