Mike Phares be7a6abbf4 AppSettings and Configuration changes,
major changes to E_Distance and minor for D_Face
2022-08-19 21:37:36 -07:00

178 lines
7.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Drawing;
using System.Text.Json;
using View_by_Distance.Metadata.Models;
using View_by_Distance.Property.Models;
using View_by_Distance.Resize.Models;
using View_by_Distance.Shared.Models.Stateless;
namespace View_by_Distance.Instance.Models;
/// <summary>
// *.png
/// </summary>
internal class D2_FaceLandmarks
{
private readonly Serilog.ILogger? _Log;
private readonly Configuration _Configuration;
internal D2_FaceLandmarks(Configuration configuration)
{
_Configuration = configuration;
_Log = Serilog.Log.ForContext<D2_FaceLandmarks>();
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
#pragma warning disable CA1416
private static Bitmap RotateBitmap(Image image, float angle)
{
Bitmap result;
Bitmap bitmap = new(image);
result = D_Face.RotateBitmap(bitmap, angle);
if (bitmap is not null)
bitmap.Dispose();
return result;
}
private static void SaveFaceLandmarkImages(List<D_Face> faceCollections, List<string[]> imageFiles, int pointSize, FileHolder resizedFileHolder)
{
int x;
int y;
D_Face face;
int width;
int height;
string imageFileFullName;
Bitmap rotated;
string rotatedImageFileFullName;
Shared.Models.FacePoint[] facePoints;
for (int i = 0; i < faceCollections.Count; i++)
{
if (!faceCollections[i].Populated)
continue;
face = faceCollections[i];
imageFileFullName = imageFiles[i][0];
rotatedImageFileFullName = imageFiles[i][1];
try
{
using (Image image = Image.FromFile(resizedFileHolder.FullName))
{
using Graphics graphic = Graphics.FromImage(image);
if (face.FaceLandmarks is null || !face.FaceLandmarks.Any())
{
width = face.Location.Right - face.Location.Left;
height = face.Location.Bottom - face.Location.Top;
graphic.DrawEllipse(Pens.Red, face.Location.Left, face.Location.Top, width, height);
}
else
{
foreach (KeyValuePair<string, Shared.Models.FacePoint[]> keyValuePair in face.FaceLandmarks)
{
facePoints = keyValuePair.Value.ToArray();
foreach (Shared.Models.FacePoint facePoint in facePoints)
graphic.DrawEllipse(Pens.GreenYellow, face.Location.Left + facePoint.X - pointSize, face.Location.Top + facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
if (keyValuePair.Key == FacePart.Chin.ToString())
continue;
if (facePoints.Length < 3)
continue;
x = (int)(from l in facePoints select l.X).Average();
y = (int)(from l in facePoints select l.Y).Average();
graphic.DrawEllipse(Pens.Purple, face.Location.Left + x - pointSize, face.Location.Top + y - pointSize, pointSize * 2, pointSize * 2);
}
}
image.Save(imageFileFullName, System.Drawing.Imaging.ImageFormat.Png);
}
if (face.α.HasValue)
{
using Image image = Image.FromFile(resizedFileHolder.FullName);
rotated = RotateBitmap(image, (float)face.α.Value);
if (rotated is not null)
{
rotated.Save(rotatedImageFileFullName, System.Drawing.Imaging.ImageFormat.Png);
rotated.Dispose();
}
}
}
catch (Exception) { }
}
}
#pragma warning restore CA1416
internal void SaveFaceLandmarkImages(string d2ResultsFullGroupDirectory, string sourceDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<D_Face> faceCollections)
{
if (_Configuration.PropertyConfiguration is null)
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
if (item.ImageFileHolder is null)
throw new NullReferenceException(nameof(item.ImageFileHolder));
if (item.ResizedFileHolder is null)
throw new NullReferenceException(nameof(item.ResizedFileHolder));
FileInfo fileInfo;
bool check = false;
string parentCheck;
const int pointSize = 2;
FileInfo rotatedFileInfo;
DateTime? dateTime = null;
long ticks = DateTime.Now.Ticks;
List<string[]> imageFiles = new();
bool updateDateWhenMatches = false;
List<string> angleBracketCollection = new();
angleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(
_Configuration.PropertyConfiguration,
sourceDirectory,
d2ResultsFullGroupDirectory,
contentDescription: "n x 2 png file(s) for each face found",
singletonDescription: string.Empty,
collectionDescription: string.Empty,
converted: false));
string facesDirectory = Path.Combine(angleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
if (!Directory.Exists(facesDirectory))
_ = Directory.CreateDirectory(facesDirectory);
for (int i = 0; i < faceCollections.Count; i++)
{
if (!faceCollections[i].Populated)
{
imageFiles.Add(Array.Empty<string>());
continue;
}
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{i} - {item.ImageFileHolder.NameWithoutExtension}.png"));
if (!fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
throw new Exception();
parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
if (File.Exists(parentCheck))
File.Delete(parentCheck);
}
if (string.IsNullOrEmpty(fileInfo.DirectoryName))
continue;
rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, string.Concat(Path.GetFileNameWithoutExtension(fileInfo.FullName), " - ", i, " - R", Path.GetExtension(fileInfo.FullName))));
imageFiles.Add(new string[] { fileInfo.FullName, rotatedFileInfo.FullName });
if (check)
continue;
else if (_Configuration.OverrideForFaceLandmarkImages)
check = true;
else if (!fileInfo.Exists)
check = true;
else if (!rotatedFileInfo.Exists)
check = true;
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
check = true;
if (check && !updateDateWhenMatches)
{
updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
}
}
if (check)
SaveFaceLandmarkImages(faceCollections, imageFiles, pointSize, item.ResizedFileHolder);
}
}