This commit is contained in:
2022-11-20 23:20:28 -07:00
parent c6aa7e8e3c
commit 3b988ba152
85 changed files with 1355 additions and 980 deletions

View File

@ -13,7 +13,6 @@ public class Face : Properties.IFace
protected readonly OutputResolution? _OutputResolution;
protected Location? _Location;
protected Mapping? _Mapping;
protected readonly string _RelativePath;
public DateTime DateTime => _DateTime;
public FaceDistance? FaceDistance => _FaceDistance;
public FaceEncoding? FaceEncoding => _FaceEncoding;
@ -21,10 +20,9 @@ public class Face : Properties.IFace
public Location? Location => _Location;
public Mapping? Mapping => _Mapping;
public OutputResolution? OutputResolution => _OutputResolution;
public string RelativePath => _RelativePath;
[JsonConstructor]
public Face(DateTime dateTime, FaceDistance? faceDistance, FaceEncoding? faceEncoding, Dictionary<Stateless.FacePart, FacePoint[]>? faceParts, Location? location, Mapping? mapping, OutputResolution? outputResolution, string relativePath)
public Face(DateTime dateTime, FaceDistance? faceDistance, FaceEncoding? faceEncoding, Dictionary<Stateless.FacePart, FacePoint[]>? faceParts, Location? location, Mapping? mapping, OutputResolution? outputResolution)
{
_DateTime = dateTime;
_FaceDistance = faceDistance;
@ -33,27 +31,26 @@ public class Face : Properties.IFace
_Location = location;
_Mapping = mapping;
_OutputResolution = outputResolution;
_RelativePath = relativePath;
}
public Face(int locationDigits, int locationFactor, int facesCount, Face face) :
this(face.DateTime, null, face.FaceEncoding, face.FaceParts, face.Location, null, face.OutputResolution, face.RelativePath)
this(face.DateTime, null, face.FaceEncoding, face.FaceParts, face.Location, null, face.OutputResolution)
{
if (face.Location?.Confidence is not null && face.OutputResolution is not null)
_Location = new(face.Location.Confidence, face.OutputResolution.Height, face.Location, locationDigits, locationFactor, face.OutputResolution.Width, facesCount);
}
public Face(Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string relativePath, Location? location) :
this(DateTime.MinValue, null, null, null, location, null, null, relativePath)
public Face(Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, Location? location) :
this(DateTime.MinValue, null, null, null, location, null, null)
{
DateTime?[] dateTimes;
_OutputResolution = new(outputResolutionHeight, outputResolutionOrientation, outputResolutionWidth);
dateTimes = new DateTime?[] { property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeOriginal, property.GPSDateStamp };
dateTimes = new DateTime?[] { property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeFromName, property.DateTimeOriginal, property.GPSDateStamp };
_DateTime = (from l in dateTimes where l.HasValue select l.Value).Min();
}
public Face(Face face, int height, Location location, int locationDigits, int locationFactor, int width, int zCount) :
this(face.DateTime, face.FaceDistance, face.FaceEncoding, face.FaceParts, new(height, location, locationDigits, locationFactor, width, zCount), face.Mapping, face.OutputResolution, face.RelativePath)
this(face.DateTime, face.FaceDistance, face.FaceEncoding, face.FaceParts, new(height, location, locationDigits, locationFactor, width, zCount), face.Mapping, face.OutputResolution)
{ }
public override string ToString()

View File

@ -144,9 +144,9 @@ public class FaceFileSystem : FileSystem, Properties.IFaceFileSystem
faceHeight = face.Location.Bottom - face.Location.Top;
confidence = face.Location.Confidence.ToString("00.000");
}
string? directoryName = Path.GetDirectoryName(face.RelativePath);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(face.RelativePath);
string sourceFullFileName = string.Concat(cResizeContent, face.RelativePath);
string? directoryName = Path.GetDirectoryName("face.RelativePath");
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension("face.RelativePath");
string sourceFullFileName = string.Concat(cResizeContent, "face.RelativePath");
if (directoryName is null)
throw new Exception();
string faceFullFileName = Path.Combine($"{dFacesContentDirectory}{directoryName}", fileNameWithoutExtension, $"{locationIndex} - {fileNameWithoutExtension}.png");

View File

@ -7,9 +7,10 @@ public class Item : Properties.IItem
{
protected readonly bool? _Abandoned;
protected readonly bool? _Changed;
protected List<Face> _Faces;
protected readonly FileHolder? _ImageFileHolder;
protected readonly bool? _FileSizeChanged;
protected readonly FileHolder _ImageFileHolder;
protected bool? _LastWriteTimeChanged;
protected bool? _Moved;
protected readonly bool? _NoJson;
protected Property? _Property;
@ -18,9 +19,10 @@ public class Item : Properties.IItem
protected readonly string _SourceDirectoryFile;
protected bool _ValidImageFormatExtension;
public bool? Abandoned => _Abandoned;
public bool? Changed => _Changed;
public List<Face> Faces => _Faces;
public FileHolder? ImageFileHolder => _ImageFileHolder;
public bool? FileSizeChanged => _FileSizeChanged;
public FileHolder ImageFileHolder => _ImageFileHolder;
public bool? LastWriteTimeChanged => _LastWriteTimeChanged;
public bool? Moved => _Moved;
public bool? NoJson => _NoJson;
public Property? Property => _Property;
@ -30,32 +32,25 @@ public class Item : Properties.IItem
public bool ValidImageFormatExtension => _ValidImageFormatExtension;
[JsonConstructor]
public Item(bool? abandoned, bool? changed, List<Face> faces, FileHolder? imageFileHolder, bool? moved, bool? noJson, Property? property, string relativePath, FileHolder? resizedFileHolder, string sourceDirectoryFile, bool validImageFormatExtension)
public Item(bool? abandoned, List<Face> faces, bool? fileSizeChanged, FileHolder imageFileHolder, bool? lastWriteTimeChanged, bool? moved, bool? noJson, Property? property, string relativePath, FileHolder? resizedFileHolder, string sourceDirectoryFile, bool validImageFormatExtension)
{
_Abandoned = abandoned;
_Changed = changed;
_Faces = faces;
_ImageFileHolder = imageFileHolder;
_Moved = moved;
_NoJson = noJson;
_Property = property;
_Abandoned = abandoned;
_RelativePath = relativePath;
_FileSizeChanged = fileSizeChanged;
_ImageFileHolder = imageFileHolder;
_ResizedFileHolder = resizedFileHolder;
_SourceDirectoryFile = sourceDirectoryFile;
_LastWriteTimeChanged = lastWriteTimeChanged;
_ValidImageFormatExtension = validImageFormatExtension;
}
public Item(string sourceDirectoryFile, string relativePath, FileHolder imageFileInfo, bool isValidImageFormatExtension, Property? property, bool? abandoned, bool? changed)
public Item(string sourceDirectoryFile, string relativePath, FileHolder imageFileInfo, bool validImageFormatExtension, Property? property, bool? abandoned, bool? fileSizeChanged, bool? lastWriteTimeChanged) :
this(abandoned, new(), fileSizeChanged, imageFileInfo, lastWriteTimeChanged, null, abandoned is null, property, relativePath, null, sourceDirectoryFile, validImageFormatExtension)
{
_Faces = new();
_Changed = changed;
_Property = property;
_Abandoned = abandoned;
_NoJson = abandoned is null;
_RelativePath = relativePath;
_ImageFileHolder = imageFileInfo;
_SourceDirectoryFile = sourceDirectoryFile;
_ValidImageFormatExtension = isValidImageFormatExtension;
if (relativePath.EndsWith(".json"))
throw new ArgumentException("Can not be a *.json file!");
if (imageFileInfo is not null && imageFileInfo.ExtensionLowered is ".json")
@ -63,7 +58,7 @@ public class Item : Properties.IItem
}
public Item(string sourceDirectoryFile, string relativePath, bool isValidImageFormatExtension) :
this(sourceDirectoryFile, relativePath, new(sourceDirectoryFile), isValidImageFormatExtension, null, null, null)
this(sourceDirectoryFile, relativePath, new(sourceDirectoryFile), isValidImageFormatExtension, null, null, null, null)
{ }
public override string ToString()
@ -84,7 +79,7 @@ public class Item : Properties.IItem
_ResizedFileHolder = fileHolder;
}
public bool Any() => (_Abandoned.HasValue && _Abandoned.Value) || (_Changed.HasValue && _Changed.Value) || (_Moved.HasValue && _Moved.Value) || (_NoJson.HasValue && _NoJson.Value);
public bool Any() => (_Abandoned.HasValue && _Abandoned.Value) || (_FileSizeChanged.HasValue && _FileSizeChanged.Value) || (_LastWriteTimeChanged.HasValue && _LastWriteTimeChanged.Value) || (_Moved.HasValue && _Moved.Value) || (_NoJson.HasValue && _NoJson.Value);
public void Update(Property property) => _Property = property;

View File

@ -30,6 +30,21 @@ public class MappingFromItem : Properties.IMappingFromItem
return result;
}
internal static MappingFromItem GetMappingFromItem(Item item, FileHolder? resizedFileHolder)
{
MappingFromItem result;
bool? isWrongYear;
DateTime minimumDateTime;
if (item.Property?.Id is null)
throw new NotSupportedException();
if (resizedFileHolder is null)
throw new NotSupportedException();
minimumDateTime = Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder, minimumDateTime);
result = new(item.Property.Id.Value, item.ImageFileHolder, isWrongYear, minimumDateTime, item.RelativePath, resizedFileHolder);
return result;
}
}
public class MappingFromLocation : Properties.IMappingFromLocation

View File

@ -9,6 +9,5 @@ public interface IFace
public Dictionary<Stateless.FacePart, FacePoint[]>? FaceParts { get; }
public Mapping? Mapping { get; }
public OutputResolution? OutputResolution { get; }
public string RelativePath { get; }
}

View File

@ -4,9 +4,9 @@ public interface IItem
{
public bool? Abandoned { get; }
public bool? Changed { get; }
public bool? FileSizeChanged { get; }
public List<Face> Faces { get; }
public FileHolder? ImageFileHolder { get; }
public FileHolder ImageFileHolder { get; }
public bool? Moved { get; }
public bool? NoJson { get; }
public Property? Property { get; }

View File

@ -6,6 +6,7 @@ public interface IProperty
public DateTime CreationTime { get; }
public DateTime? DateTime { get; }
public DateTime? DateTimeDigitized { get; }
public DateTime? DateTimeFromName { get; }
public DateTime? DateTimeOriginal { get; }
public long FileSize { get; }
public DateTime? GPSDateStamp { get; }

View File

@ -9,6 +9,7 @@ public class Property : Properties.IProperty
protected DateTime _CreationTime;
protected DateTime? _DateTime;
protected DateTime? _DateTimeDigitized;
protected DateTime? _DateTimeFromName;
protected DateTime? _DateTimeOriginal;
protected long _FileSize;
protected DateTime? _GPSDateStamp;
@ -23,6 +24,7 @@ public class Property : Properties.IProperty
public DateTime CreationTime => _CreationTime;
public DateTime? DateTime => _DateTime;
public DateTime? DateTimeDigitized => _DateTimeDigitized;
public DateTime? DateTimeFromName => _DateTimeFromName;
public DateTime? DateTimeOriginal => _DateTimeOriginal;
public long FileSize => _FileSize;
public DateTime? GPSDateStamp => _GPSDateStamp;
@ -36,8 +38,9 @@ public class Property : Properties.IProperty
public int? Width => _Width;
[JsonConstructor]
public Property(DateTime creationTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeOriginal, long fileSize, DateTime? gpsDateStamp, int? height, int? id, int[] indices, DateTime lastWriteTime, string make, string model, string orientation, int? width)
public Property(DateTime creationTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeFromName, DateTime? dateTimeOriginal, long fileSize, DateTime? gpsDateStamp, int? height, int? id, int[] indices, DateTime lastWriteTime, string make, string model, string orientation, int? width)
{
_DateTimeFromName = dateTimeFromName;
_CreationTime = creationTime;
_DateTime = dateTime;
_DateTimeDigitized = dateTimeDigitized;
@ -60,7 +63,7 @@ public class Property : Properties.IProperty
return result;
} // ...
public List<DateTime> GetDateTimes() => Stateless.Methods.Property.GetDateTimes(_CreationTime, _LastWriteTime, _DateTime, _DateTimeDigitized, _DateTimeOriginal, _GPSDateStamp);
public List<DateTime> GetDateTimes() => Stateless.Methods.Property.GetDateTimes(_CreationTime, _LastWriteTime, _DateTime, _DateTimeDigitized, _DateTimeFromName, _DateTimeOriginal, _GPSDateStamp);
public (bool?, string[]) IsWrongYear(FileHolder fileHolder, DateTime? minimumDateTime)
{

View File

@ -45,7 +45,7 @@ internal abstract class Face
foreach (JsonElement jsonElement in jsonElements)
{
tuple = JsonSerializer.Deserialize<Tuple<Models.Face, string>>(jsonElement.ToString());
if (tuple is null || tuple.Item1 is null || string.IsNullOrEmpty(tuple.Item1.RelativePath))
if (tuple is null || tuple.Item1 is null || string.IsNullOrEmpty("tuple.Item1.RelativePath"))
continue;
results.Add(tuple.Item1);
if (maximum.HasValue && results.Count >= maximum)

View File

@ -59,10 +59,10 @@ internal abstract class FaceFileSystem
if (face[i] is null)
continue;
locationIndex = 0;
directoryName = Path.GetDirectoryName(face[i].RelativePath);
directoryName = Path.GetDirectoryName("face[i].RelativePath");
if (directoryName is null)
continue;
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(face[i].RelativePath);
fileNameWithoutExtension = Path.GetFileNameWithoutExtension("face[i].RelativePath");
jsonFileName = string.Concat(locationIndex.Value, " - ", fileNameWithoutExtension, extension);
eDistanceCollectionFileFullName = Path.Combine($"{tuple.E_DistanceCollectionDirectory}{directoryName}", fileNameWithoutExtension, jsonFileName);
if (i == 0 && extension is ".json" && eDistanceCollectionFileFullName != selectedFileFullName)

View File

@ -0,0 +1,16 @@
namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IMappingFromItem
{ // ...
MappingFromItem TestStatic_GetMappingFromItem(Models.Item item, Models.FileHolder? resizedFileHolder)
=> GetMappingFromItem(item, resizedFileHolder);
static MappingFromItem GetMappingFromItem(Models.Item item, Models.FileHolder? resizedFileHolder)
=> MappingFromItem.GetMappingFromItem(item, resizedFileHolder);
MappingFromItem TestStatic_GetMappingFromItem(Models.Item item)
=> GetMappingFromItem(item);
static MappingFromItem GetMappingFromItem(Models.Item item)
=> GetMappingFromItem(item, item.ResizedFileHolder);
}

View File

@ -3,9 +3,10 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IPersonURL
{
string TestStatic_GetDefaultValue() => PersonURL.GetDefaultValue(); // <{1}>PluralValue
static string GetDefaultValue() => PersonURL.GetDefaultValue(); // <{1}>PluralValue
string TestStatic_GetDefaultValue() =>
GetDefaultValue(); // <{1}>PluralValue
static string GetDefaultValue() =>
PersonURL.GetDefaultValue(); // <{1}>PluralValue
// ...

View File

@ -6,56 +6,84 @@ public interface IProperty
string TestStatic_DateTimeFormat();
static string DateTimeFormat() => "yyyy:MM:dd HH:mm:ss";
int TestStatic_GetDeterministicHashCode(byte[] value);
int TestStatic_GetDeterministicHashCode(byte[] value) =>
GetDeterministicHashCode(value);
static int GetDeterministicHashCode(byte[] value) =>
Property.GetDeterministicHashCode(value);
int TestStatic_GetDeterministicHashCode(string value);
List<DateTime> TestStatic_GetMetadataDateTimesByPattern(string dateTimeFormat, Models.FileHolder fileHolder) =>
GetMetadataDateTimesByPattern(dateTimeFormat, fileHolder);
static List<DateTime> GetMetadataDateTimesByPattern(string dateTimeFormat, Models.FileHolder fileHolder) =>
Property.GetMetadataDateTimesByPattern(dateTimeFormat, fileHolder.FullName);
int TestStatic_GetDeterministicHashCode(string value) =>
GetDeterministicHashCode(value);
static int GetDeterministicHashCode(string value) =>
Property.GetDeterministicHashCode(value);
DateTime TestStatic_GetDateTime(Models.Property? property);
DateTime TestStatic_GetDateTime(Models.Property? property) =>
GetDateTime(property);
static DateTime GetDateTime(Models.Property? property) =>
Property.GetDateTime(property);
DateTime TestStatic_GetMinimumDateTime(Models.Property? property);
DateTime TestStatic_GetMinimumDateTime(Models.Property? property) =>
GetMinimumDateTime(property);
static DateTime GetMinimumDateTime(Models.Property? property) =>
Property.GetMinimumDateTime(property);
(int Season, string seasonName) TestStatic_GetSeason(int dayOfYear);
(int Season, string seasonName) TestStatic_GetSeason(int dayOfYear) =>
GetSeason(dayOfYear);
static (int Season, string seasonName) GetSeason(int dayOfYear) =>
Property.GetSeason(dayOfYear);
string TestStatic_GetDiffRootDirectory(string diffPropertyDirectory);
string TestStatic_GetDiffRootDirectory(string diffPropertyDirectory) =>
GetDiffRootDirectory(diffPropertyDirectory);
static string GetDiffRootDirectory(string diffPropertyDirectory) =>
Property.GetDiffRootDirectory(diffPropertyDirectory);
bool TestStatic_Any(Models.Container[] propertyHolderCollections);
bool TestStatic_Any(Models.Container[] propertyHolderCollections) =>
Any(propertyHolderCollections);
static bool Any(Models.Container[] propertyHolderCollections) =>
Property.Any(propertyHolderCollections);
(bool?, string[]) TestStatic_IsWrongYear(string[] segments, string year);
(bool?, string[]) TestStatic_IsWrongYear(string[] segments, string year) =>
IsWrongYear(segments, year);
static (bool?, string[]) IsWrongYear(string[] segments, string year) =>
Property.IsWrongYear(segments, year);
List<DateTime> TestStatic_GetDateTimes(Models.Property property);
static List<DateTime> GetDateTimes(Models.Property property) =>
Property.GetDateTimes(property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeOriginal, property.GPSDateStamp);
(DateTime?, int?, string?) TestStatic_Get(Models.FileHolder fileHolder) =>
Get(fileHolder);
static (DateTime?, int?, string?) Get(Models.FileHolder fileHolder) =>
Property.Get(fileHolder);
double TestStatic_GetStandardDeviation(IEnumerable<long> values, double average);
DateTime? TestStatic_GetDateTimeFromName(Models.FileHolder fileHolder) =>
GetDateTimeFromName(fileHolder);
static DateTime? GetDateTimeFromName(Models.FileHolder fileHolder) =>
Property.GetDateTimeFromName(fileHolder);
List<DateTime> TestStatic_GetDateTimes(Models.Property property) =>
GetDateTimes(property);
static List<DateTime> GetDateTimes(Models.Property property) =>
Property.GetDateTimes(property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeFromName, property.DateTimeOriginal, property.GPSDateStamp);
double TestStatic_GetStandardDeviation(IEnumerable<long> values, double average) =>
GetStandardDeviation(values, average);
static double GetStandardDeviation(IEnumerable<long> values, double average) =>
Property.GetStandardDeviation(values, average);
TimeSpan TestStatic_GetThreeStandardDeviationHigh(int minimum, Models.Container container);
TimeSpan TestStatic_GetThreeStandardDeviationHigh(int minimum, Models.Container container) =>
GetThreeStandardDeviationHigh(minimum, container);
static TimeSpan GetThreeStandardDeviationHigh(int minimum, Models.Container container) =>
Property.GetThreeStandardDeviationHigh(minimum, container);
(int, List<DateTime>, List<Models.Item>) TestStatic_Get(Models.Container container, TimeSpan threeStandardDeviationHigh, int i);
(int, List<DateTime>, List<Models.Item>) TestStatic_Get(Models.Container container, TimeSpan threeStandardDeviationHigh, int i) =>
Get(container, threeStandardDeviationHigh, i);
static (int, List<DateTime>, List<Models.Item>) Get(Models.Container container, TimeSpan threeStandardDeviationHigh, int i) =>
Property.Get(container, threeStandardDeviationHigh, i);
List<DateTime> TestStatic_GetDateTimes(DateTime creationTime, DateTime lastWriteTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeOriginal, DateTime? gpsDateStamp);
static List<DateTime> GetDateTimes(DateTime creationTime, DateTime lastWriteTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeOriginal, DateTime? gpsDateStamp) =>
Property.GetDateTimes(creationTime, lastWriteTime, dateTime, dateTimeDigitized, dateTimeOriginal, gpsDateStamp);
List<DateTime> TestStatic_GetDateTimes(DateTime creationTime, DateTime lastWriteTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeFromName, DateTime? dateTimeOriginal, DateTime? gpsDateStamp) =>
GetDateTimes(creationTime, lastWriteTime, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginal, gpsDateStamp);
static List<DateTime> GetDateTimes(DateTime creationTime, DateTime lastWriteTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeFromName, DateTime? dateTimeOriginal, DateTime? gpsDateStamp) =>
Property.GetDateTimes(creationTime, lastWriteTime, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginal, gpsDateStamp);
}

View File

@ -5,8 +5,7 @@ internal abstract class Index
private static string GetJsonContains(string result, string jsonFileFullName, FileInfo fileInfo, string fileSegmentCollection)
{
if (fileInfo is null)
fileInfo = new FileInfo(jsonFileFullName);
fileInfo ??= new FileInfo(jsonFileFullName);
result = result.Replace(fileSegmentCollection, nameof(Properties.IIndex.RelativePaths)).Replace("\\\\", "/");
File.WriteAllText(fileInfo.FullName, result);
File.SetLastWriteTime(fileInfo.FullName, fileInfo.LastWriteTime);
@ -15,8 +14,7 @@ internal abstract class Index
private static string GetJsonSpecial(string result, string jsonFileFullName, FileInfo fileInfo)
{
if (fileInfo is null)
fileInfo = new FileInfo(jsonFileFullName);
fileInfo ??= new FileInfo(jsonFileFullName);
result = result.Replace("/u0", "\\u0");
File.WriteAllText(fileInfo.FullName, result);
File.SetLastWriteTime(fileInfo.FullName, fileInfo.LastWriteTime);

View File

@ -10,15 +10,11 @@ internal abstract class Item
List<string> collection = new();
foreach (Models.Item item in itemsA)
{
if (item.ImageFileHolder is null)
continue;
results.Add(item);
collection.Add(item.ImageFileHolder.FullName);
}
foreach (Models.Item item in itemsB)
{
if (item.ImageFileHolder is null)
continue;
if (collection.Contains(item.ImageFileHolder.FullName))
continue;
result++;

View File

@ -1,3 +1,10 @@
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;
namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract class Property
@ -85,7 +92,46 @@ internal abstract class Property
return new(result, results);
}
internal static List<DateTime> GetDateTimes(DateTime creationTime, DateTime lastWriteTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeOriginal, DateTime? gpsDateStamp)
internal static DateTime? GetDateTimeFromName(Models.FileHolder fileHolder)
{
DateTime? result = null;
int length;
string format;
string fullFormat;
StringBuilder value = new();
string[][] dateFormats = new string[][]
{
new string[] { string.Empty, "yyyyMMdd_HHmmss", string.Empty },
new string[] { string.Empty, "yyyy-MM-dd HH.mm.ss", string.Empty },
new string[] { string.Empty, "yyyyMMdd_HHmmss", "_LLS" },
new string[] { string.Empty, "yyyyMMdd_HHmmss", "_HDR" },
new string[] { "IMG_", "yyyyMMdd_HHmmss", string.Empty },
new string[] { "IMG#####-", "yyyyMMdd-HHmm", string.Empty },
new string[] { "CameraZOOM-", "yyyyMMddHHmmss", string.Empty },
new string[] { "VideoCapture_", "yyyyMMdd-HHmmss ", string.Empty }
};
foreach (string[] dateFormat in dateFormats)
{
_ = value.Clear();
fullFormat = string.Join(string.Empty, dateFormat);
if (fileHolder.NameWithoutExtension.Length != fullFormat.Length)
continue;
format = dateFormat[1];
length = dateFormat[0].Length + dateFormat[1].Length;
for (int i = dateFormat[0].Length; i < length; i++)
_ = value.Append(fileHolder.NameWithoutExtension[i]);
if (value.Length != format.Length)
continue;
if (DateTime.TryParseExact(value.ToString(), format, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime checkDateTime))
{
result = checkDateTime;
break;
}
}
return result;
}
internal static List<DateTime> GetDateTimes(DateTime creationTime, DateTime lastWriteTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeFromName, DateTime? dateTimeOriginal, DateTime? gpsDateStamp)
{
List<DateTime> results = new()
{
@ -96,6 +142,8 @@ internal abstract class Property
results.Add(dateTime.Value);
if (dateTimeDigitized.HasValue)
results.Add(dateTimeDigitized.Value);
if (dateTimeFromName.HasValue)
results.Add(dateTimeFromName.Value);
if (dateTimeOriginal.HasValue)
results.Add(dateTimeOriginal.Value);
if (gpsDateStamp.HasValue)
@ -119,6 +167,8 @@ internal abstract class Property
dateTimes.Add(property.DateTime.Value);
if (property.DateTimeDigitized.HasValue)
dateTimes.Add(property.DateTimeDigitized.Value);
if (property.DateTimeFromName.HasValue)
dateTimes.Add(property.DateTimeFromName.Value);
if (property.DateTimeOriginal.HasValue)
dateTimes.Add(property.DateTimeOriginal.Value);
if (property.GPSDateStamp.HasValue)
@ -269,4 +319,119 @@ internal abstract class Property
return result;
}
internal static List<DateTime> GetMetadataDateTimesByPattern(string dateTimeFormat, string sourceDirectoryFile)
{
List<DateTime> results = new();
try
{
DateTime checkDateTime;
DateTime kristy = new(1976, 3, 8);
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(sourceDirectoryFile);
foreach (MetadataExtractor.Directory directory in directories)
{
foreach (MetadataExtractor.Tag tag in directory.Tags)
{
if (string.IsNullOrEmpty(tag.Description) || tag.Description.Length != dateTimeFormat.Length)
continue;
if (!DateTime.TryParseExact(tag.Description, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
continue;
if (checkDateTime < kristy)
continue;
results.Add(checkDateTime);
}
}
}
catch (Exception) { }
return results;
}
#pragma warning disable CA1416
internal static (DateTime?, int?, string?) Get(Models.FileHolder fileHolder)
{
byte[] bytes;
string value;
int? id = null;
DateTime checkDateTime;
string? message = null;
DateTime? dateTime = null;
PropertyItem? propertyItem;
DateTime? gpsDateStamp = null;
DateTime? dateTimeOriginal = null;
DateTime? dateTimeDigitized = null;
ASCIIEncoding asciiEncoding = new();
string dateTimeFormat = IProperty.DateTimeFormat();
try
{
using Image image = Image.FromFile(fileHolder.FullName);
using Bitmap bitmap = new(image);
Rectangle rectangle = new(0, 0, image.Width, image.Height);
BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
IntPtr intPtr = bitmapData.Scan0;
int length = bitmapData.Stride * bitmap.Height;
bytes = new byte[length];
Marshal.Copy(intPtr, bytes, 0, length);
bitmap.UnlockBits(bitmapData);
id = IProperty.GetDeterministicHashCode(bytes);
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTime))
{
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTime);
if (propertyItem?.Value is not null)
{
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
dateTime = checkDateTime;
}
}
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeDigitized))
{
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeDigitized);
if (propertyItem?.Value is not null)
{
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
dateTimeDigitized = checkDateTime;
}
}
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeOriginal))
{
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeOriginal);
if (propertyItem?.Value is not null)
{
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
dateTimeOriginal = checkDateTime;
}
}
if (image.PropertyIdList.Contains((int)IExif.Tags.GPSDateStamp))
{
propertyItem = image.GetPropertyItem((int)IExif.Tags.GPSDateStamp);
if (propertyItem?.Value is not null)
{
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
gpsDateStamp = checkDateTime;
}
}
bitmap.Dispose();
image.Dispose();
}
catch (Exception)
{
message = string.Concat(new StackFrame().GetMethod()?.Name, " <", fileHolder.FullName, ">");
}
DateTime?[] dateTimes = new DateTime?[] { fileHolder.LastWriteTime, fileHolder.CreationTime, dateTime, dateTimeDigitized, dateTimeOriginal, gpsDateStamp };
return new(dateTimes.Min(), id, message);
}
#pragma warning restore CA1416
}

View File

@ -1,4 +1,5 @@
#pragma warning disable SYSLIB0022
#pragma warning disable SYSLIB0041
using System.Security.Cryptography;
using System.Text;

View File

@ -4,7 +4,7 @@
<LangVersion>10.0</LangVersion>
<Nullable>enable</Nullable>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Shared</PackageId>
@ -33,8 +33,8 @@
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
<PackageReference Include="System.Text.Json" Version="6.0.0" />
<PackageReference Include="MetadataExtractor" Version="2.7.1" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
<PackageReference Include="MetadataExtractor" Version="2.7.2" />
</ItemGroup>
</Project>