358 lines
20 KiB
C#
358 lines
20 KiB
C#
using MetadataExtractor;
|
|
using MetadataExtractor.Formats.Exif;
|
|
using System.Globalization;
|
|
|
|
namespace View_by_Distance.Metadata.Models.Stateless;
|
|
|
|
internal abstract class Exif
|
|
{
|
|
|
|
private static DateTime? GetDateTime(string? value)
|
|
{
|
|
DateTime? result;
|
|
string dateTimeFormat = "yyyy:MM:dd HH:mm:ss";
|
|
string alternateFormat = "ddd MMM dd HH:mm:ss yyyy";
|
|
if (value is not null && DateTime.TryParse(value, out DateTime dateTime))
|
|
result = dateTime;
|
|
else if (value is not null && value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
|
result = dateTime;
|
|
else if (value is not null && value.Length == alternateFormat.Length && DateTime.TryParseExact(value, alternateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
|
result = dateTime;
|
|
else
|
|
result = null;
|
|
return result;
|
|
}
|
|
|
|
private static Shared.Models.AviDirectory GetAviDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
{
|
|
Shared.Models.AviDirectory result;
|
|
MetadataExtractor.Formats.Avi.AviDirectory? aviDirectory = directories.OfType<MetadataExtractor.Formats.Avi.AviDirectory>().FirstOrDefault();
|
|
if (aviDirectory is null)
|
|
result = new(null, null, null, null);
|
|
else
|
|
{
|
|
DateTime? dateTimeOriginal;
|
|
string? duration = aviDirectory.GetDescription(MetadataExtractor.Formats.Avi.AviDirectory.TagDuration);
|
|
string? height = aviDirectory.GetDescription(MetadataExtractor.Formats.Avi.AviDirectory.TagHeight);
|
|
string? width = aviDirectory.GetDescription(MetadataExtractor.Formats.Avi.AviDirectory.TagWidth);
|
|
if (aviDirectory.TryGetDateTime(MetadataExtractor.Formats.Avi.AviDirectory.TagDateTimeOriginal, out DateTime checkDateTime))
|
|
dateTimeOriginal = checkDateTime;
|
|
else
|
|
dateTimeOriginal = GetDateTime(aviDirectory.GetString(MetadataExtractor.Formats.Avi.AviDirectory.TagDateTimeOriginal));
|
|
result = new(dateTimeOriginal, duration, height, width);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static Shared.Models.ExifDirectoryBase GetExifDirectoryBase(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
{
|
|
Shared.Models.ExifDirectoryBase result;
|
|
ExifDirectoryBase? exifDirectoryBase = directories.OfType<ExifDirectoryBase>().FirstOrDefault();
|
|
if (exifDirectoryBase is null)
|
|
result = new(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
|
|
else
|
|
{
|
|
DateTime? dateTime;
|
|
DateTime checkDateTime;
|
|
DateTime? dateTimeOriginal;
|
|
DateTime? dateTimeDigitized;
|
|
string? aperture = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagAperture);
|
|
string? applicationNotes = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagApplicationNotes);
|
|
string? artist = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagArtist);
|
|
string? bitsPerSample = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagBitsPerSample);
|
|
string? bodySerialNumber = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagBodySerialNumber);
|
|
string? cameraOwnerName = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagCameraOwnerName);
|
|
string? compressedAverageBitsPerPixel = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagCompressedAverageBitsPerPixel);
|
|
string? compression = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagCompression);
|
|
string? copyright = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagCopyright);
|
|
string? documentName = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagDocumentName);
|
|
string? exifVersion = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagExifVersion);
|
|
string? exposureTime = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagExposureTime);
|
|
string? fileSource = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagFileSource);
|
|
string? imageDescription = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagImageDescription);
|
|
string? imageHeight = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagImageHeight);
|
|
string? imageNumber = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagImageNumber);
|
|
string? imageUniqueId = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagImageUniqueId);
|
|
string? imageWidth = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagImageWidth);
|
|
string? isoSpeed = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagIsoSpeed);
|
|
string? lensMake = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagLensMake);
|
|
string? lensModel = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagLensModel);
|
|
string? lensSerialNumber = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagLensSerialNumber);
|
|
string? make = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagMake);
|
|
string? makerNote = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagMakernote);
|
|
string? model = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagModel);
|
|
string? orientation = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagOrientation);
|
|
int? orientationValue = orientation is null ? null : exifDirectoryBase.GetInt32(ExifDirectoryBase.TagOrientation);
|
|
string? rating = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagRating);
|
|
string? ratingPercent = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagRatingPercent);
|
|
string? securityClassification = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagSecurityClassification);
|
|
string? shutterSpeed = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagShutterSpeed);
|
|
string? software = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagSoftware);
|
|
string? timeZone = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagTimeZone);
|
|
string? timeZoneDigitized = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagTimeZoneDigitized);
|
|
string? timeZoneOriginal = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagTimeZoneOriginal);
|
|
string? userComment = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagUserComment);
|
|
string? winAuthor = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagWinAuthor);
|
|
string? winComment = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagWinComment);
|
|
string? winKeywords = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagWinKeywords);
|
|
string? winSubject = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagWinSubject);
|
|
string? winTitle = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagWinTitle);
|
|
string? xResolution = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagXResolution);
|
|
string? yResolution = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagYResolution);
|
|
if (exifDirectoryBase.TryGetDateTime(ExifDirectoryBase.TagDateTime, out checkDateTime))
|
|
dateTime = checkDateTime;
|
|
else
|
|
dateTime = GetDateTime(exifDirectoryBase.GetString(ExifDirectoryBase.TagDateTime));
|
|
if (exifDirectoryBase.TryGetDateTime(ExifDirectoryBase.TagDateTimeOriginal, out checkDateTime))
|
|
dateTimeOriginal = checkDateTime;
|
|
else
|
|
dateTimeOriginal = GetDateTime(exifDirectoryBase.GetString(ExifDirectoryBase.TagDateTimeOriginal));
|
|
if (exifDirectoryBase.TryGetDateTime(ExifDirectoryBase.TagDateTimeDigitized, out checkDateTime))
|
|
dateTimeDigitized = checkDateTime;
|
|
else
|
|
dateTimeDigitized = GetDateTime(exifDirectoryBase.GetString(ExifDirectoryBase.TagDateTimeDigitized));
|
|
result = new(aperture,
|
|
applicationNotes,
|
|
artist,
|
|
bitsPerSample,
|
|
bodySerialNumber,
|
|
cameraOwnerName,
|
|
compressedAverageBitsPerPixel,
|
|
compression,
|
|
copyright,
|
|
dateTime,
|
|
dateTimeDigitized,
|
|
dateTimeOriginal,
|
|
documentName,
|
|
exifVersion,
|
|
exposureTime,
|
|
fileSource,
|
|
imageDescription,
|
|
imageHeight,
|
|
imageNumber,
|
|
imageUniqueId,
|
|
imageWidth,
|
|
isoSpeed,
|
|
lensMake,
|
|
lensModel,
|
|
lensSerialNumber,
|
|
make,
|
|
makerNote,
|
|
model,
|
|
orientation,
|
|
orientationValue,
|
|
rating,
|
|
ratingPercent,
|
|
securityClassification,
|
|
shutterSpeed,
|
|
software,
|
|
timeZone,
|
|
timeZoneDigitized,
|
|
timeZoneOriginal,
|
|
userComment,
|
|
winAuthor,
|
|
winComment,
|
|
winKeywords,
|
|
winSubject,
|
|
winTitle,
|
|
xResolution,
|
|
yResolution);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static Shared.Models.FileMetadataDirectory GetFileMetadataDirectory(string file, IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
{
|
|
Shared.Models.FileMetadataDirectory result;
|
|
MetadataExtractor.Formats.FileSystem.FileMetadataDirectory? fileMetadataDirectory = directories.OfType<MetadataExtractor.Formats.FileSystem.FileMetadataDirectory>().FirstOrDefault();
|
|
if (fileMetadataDirectory is null)
|
|
result = new(null, null, null);
|
|
else
|
|
{
|
|
DateTime? fileModifiedDate;
|
|
string? fileName = fileMetadataDirectory.GetDescription(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileName);
|
|
string? fileSize = fileMetadataDirectory.GetDescription(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileSize);
|
|
if (fileMetadataDirectory.TryGetDateTime(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileModifiedDate, out DateTime checkDateTime))
|
|
fileModifiedDate = checkDateTime;
|
|
else
|
|
fileModifiedDate = GetDateTime(fileMetadataDirectory.GetString(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileModifiedDate));
|
|
if (fileName is null || !file.EndsWith(fileName))
|
|
throw new NotSupportedException($"!{file}.EndsWith({fileName})");
|
|
result = new(fileModifiedDate, fileName, fileSize);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static Shared.Models.GifHeaderDirectory GetGifHeaderDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
{
|
|
Shared.Models.GifHeaderDirectory result;
|
|
MetadataExtractor.Formats.Gif.GifHeaderDirectory? gifHeaderDirectory = directories.OfType<MetadataExtractor.Formats.Gif.GifHeaderDirectory>().FirstOrDefault();
|
|
if (gifHeaderDirectory is null)
|
|
result = new(null, null);
|
|
else
|
|
{
|
|
string? imageHeight = gifHeaderDirectory.GetDescription(MetadataExtractor.Formats.Gif.GifHeaderDirectory.TagImageHeight);
|
|
string? imageWidth = gifHeaderDirectory.GetDescription(MetadataExtractor.Formats.Gif.GifHeaderDirectory.TagImageWidth);
|
|
result = new(imageHeight, imageWidth);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static Shared.Models.PhotoshopDirectory GetPhotoshopDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
{
|
|
Shared.Models.PhotoshopDirectory result;
|
|
MetadataExtractor.Formats.Photoshop.PhotoshopDirectory? PhotoshopDirectory = directories.OfType<MetadataExtractor.Formats.Photoshop.PhotoshopDirectory>().FirstOrDefault();
|
|
if (PhotoshopDirectory is null)
|
|
result = new(null, null);
|
|
else
|
|
{
|
|
string? jpegQuality = PhotoshopDirectory.GetDescription(MetadataExtractor.Formats.Photoshop.PhotoshopDirectory.TagJpegQuality);
|
|
string? url = PhotoshopDirectory.GetDescription(MetadataExtractor.Formats.Photoshop.PhotoshopDirectory.TagUrl);
|
|
result = new(jpegQuality, url);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static Shared.Models.GpsDirectory GetGpsDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
{
|
|
Shared.Models.GpsDirectory result;
|
|
GpsDirectory? gpsDirectory = directories.OfType<GpsDirectory>().FirstOrDefault();
|
|
if (gpsDirectory is null)
|
|
result = new(null, null, null, null, null, null);
|
|
else
|
|
{
|
|
DateTime? timeStamp;
|
|
string? altitude = gpsDirectory.GetDescription(GpsDirectory.TagAltitude);
|
|
string? latitude = gpsDirectory.GetDescription(GpsDirectory.TagLatitude);
|
|
string? latitudeRef = gpsDirectory.GetDescription(GpsDirectory.TagLatitudeRef);
|
|
string? longitude = gpsDirectory.GetDescription(GpsDirectory.TagLongitude);
|
|
string? longitudeRef = gpsDirectory.GetDescription(GpsDirectory.TagLongitudeRef);
|
|
if (gpsDirectory.TryGetDateTime(GpsDirectory.TagTimeStamp, out DateTime checkDateTime))
|
|
timeStamp = checkDateTime;
|
|
else
|
|
timeStamp = GetDateTime(gpsDirectory.GetString(GpsDirectory.TagTimeStamp));
|
|
result = new(altitude,
|
|
latitude,
|
|
latitudeRef,
|
|
longitude,
|
|
longitudeRef,
|
|
timeStamp);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static Shared.Models.JpegDirectory GetJpegDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
{
|
|
Shared.Models.JpegDirectory result;
|
|
MetadataExtractor.Formats.Jpeg.JpegDirectory? jpegDirectory = directories.OfType<MetadataExtractor.Formats.Jpeg.JpegDirectory>().FirstOrDefault();
|
|
if (jpegDirectory is null)
|
|
result = new(null, null);
|
|
else
|
|
{
|
|
string? imageHeight = jpegDirectory.GetDescription(MetadataExtractor.Formats.Jpeg.JpegDirectory.TagImageHeight);
|
|
string? imageWidth = jpegDirectory.GetDescription(MetadataExtractor.Formats.Jpeg.JpegDirectory.TagImageWidth);
|
|
result = new(imageHeight, imageWidth);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static Shared.Models.PngDirectory GetPngDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
{
|
|
Shared.Models.PngDirectory result;
|
|
MetadataExtractor.Formats.Png.PngDirectory? pngDirectory = directories.OfType<MetadataExtractor.Formats.Png.PngDirectory>().FirstOrDefault();
|
|
if (pngDirectory is null)
|
|
result = new(null, null);
|
|
else
|
|
{
|
|
string? imageHeight = pngDirectory.GetDescription(MetadataExtractor.Formats.Png.PngDirectory.TagImageHeight);
|
|
string? imageWidth = pngDirectory.GetDescription(MetadataExtractor.Formats.Png.PngDirectory.TagImageWidth);
|
|
result = new(imageHeight, imageWidth);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static Shared.Models.QuickTimeMovieHeaderDirectory GetQuickTimeMovieHeaderDirectoryDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
{
|
|
Shared.Models.QuickTimeMovieHeaderDirectory result;
|
|
MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory? aviDirectory = directories.OfType<MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory>().FirstOrDefault();
|
|
if (aviDirectory is null)
|
|
result = new(null);
|
|
else
|
|
{
|
|
DateTime? created;
|
|
if (aviDirectory.TryGetDateTime(MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory.TagCreated, out DateTime checkDateTime))
|
|
created = checkDateTime;
|
|
else
|
|
created = GetDateTime(aviDirectory.GetString(MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory.TagCreated));
|
|
result = new(created);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static Shared.Models.QuickTimeTrackHeaderDirectory GetQuickTimeTrackHeaderDirectoryDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
{
|
|
Shared.Models.QuickTimeTrackHeaderDirectory result;
|
|
MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory? aviDirectory = directories.OfType<MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory>().FirstOrDefault();
|
|
if (aviDirectory is null)
|
|
result = new(null);
|
|
else
|
|
{
|
|
DateTime? created;
|
|
if (aviDirectory.TryGetDateTime(MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory.TagCreated, out DateTime checkDateTime))
|
|
created = checkDateTime;
|
|
else
|
|
created = GetDateTime(aviDirectory.GetString(MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory.TagCreated));
|
|
result = new(created);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static Shared.Models.WebPDirectory GetWebPDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
{
|
|
Shared.Models.WebPDirectory result;
|
|
MetadataExtractor.Formats.WebP.WebPDirectory? WebPDirectory = directories.OfType<MetadataExtractor.Formats.WebP.WebPDirectory>().FirstOrDefault();
|
|
if (WebPDirectory is null)
|
|
result = new(null, null);
|
|
else
|
|
{
|
|
string? imageHeight = WebPDirectory.GetDescription(MetadataExtractor.Formats.WebP.WebPDirectory.TagImageHeight);
|
|
string? imageWidth = WebPDirectory.GetDescription(MetadataExtractor.Formats.WebP.WebPDirectory.TagImageWidth);
|
|
result = new(imageHeight, imageWidth);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal static Shared.Models.ExifDirectory Covert(Shared.Models.FilePath filePath, Shared.Models.DeterministicHashCode deterministicHashCode, FileInfo fileInfo, System.Drawing.Size? size, IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
{
|
|
Shared.Models.ExifDirectory results;
|
|
Shared.Models.AviDirectory aviDirectory = GetAviDirectory(directories);
|
|
Shared.Models.GpsDirectory gpsDirectory = GetGpsDirectory(directories);
|
|
Shared.Models.PngDirectory pngDirectory = GetPngDirectory(directories);
|
|
Shared.Models.JpegDirectory jpegDirectory = GetJpegDirectory(directories);
|
|
Shared.Models.WebPDirectory webPDirectory = GetWebPDirectory(directories);
|
|
Shared.Models.ExifDirectoryBase exifDirectoryBase = GetExifDirectoryBase(directories);
|
|
Shared.Models.GifHeaderDirectory gifHeaderDirectory = GetGifHeaderDirectory(directories);
|
|
Shared.Models.PhotoshopDirectory photoshopDirectory = GetPhotoshopDirectory(directories);
|
|
Shared.Models.FileMetadataDirectory fileMetadataDirectory = GetFileMetadataDirectory(filePath.FullName, directories);
|
|
Shared.Models.QuickTimeMovieHeaderDirectory quickTimeMovieHeaderDirectory = GetQuickTimeMovieHeaderDirectoryDirectory(directories);
|
|
Shared.Models.QuickTimeTrackHeaderDirectory quickTimeTrackHeaderDirectory = GetQuickTimeTrackHeaderDirectoryDirectory(directories);
|
|
results = new(aviDirectory,
|
|
exifDirectoryBase,
|
|
filePath.FullName,
|
|
fileMetadataDirectory,
|
|
gifHeaderDirectory,
|
|
gpsDirectory,
|
|
size?.Height,
|
|
deterministicHashCode.Id ?? filePath.Id,
|
|
fileInfo.FullName,
|
|
jpegDirectory,
|
|
photoshopDirectory,
|
|
pngDirectory,
|
|
quickTimeMovieHeaderDirectory,
|
|
quickTimeTrackHeaderDirectory,
|
|
webPDirectory,
|
|
size?.Width);
|
|
return results;
|
|
}
|
|
|
|
} |