-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMediaMetadataService.cs
More file actions
86 lines (74 loc) · 2.41 KB
/
MediaMetadataService.cs
File metadata and controls
86 lines (74 loc) · 2.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
namespace FileOrganizer;
internal static class MediaMetadataService
{
private static readonly int[] ExifDatePropertyIds =
{
0x9003,
0x9004,
0x0132
};
public static string ResolveImageBaseName(FileInfo file, string invalidCharacterReplacement)
{
var originalName = Path.GetFileNameWithoutExtension(file.Name);
try
{
using var image = Image.FromFile(file.FullName);
var dateTaken = TryGetImageDateTaken(image) ?? file.CreationTime;
var safeName = SanitizeBaseName(originalName, invalidCharacterReplacement);
return $"{dateTaken:yyyy-MM-dd}_{safeName}";
}
catch
{
return originalName;
}
}
private static DateTime? TryGetImageDateTaken(Image image)
{
foreach (var propertyId in ExifDatePropertyIds)
{
var property = image.PropertyItems.FirstOrDefault(item => item.Id == propertyId);
var bytes = property?.Value;
if (bytes is not { Length: > 0 })
{
continue;
}
try
{
var raw = Encoding.ASCII.GetString(bytes).Trim('\0', ' ', '\t', '\r', '\n');
if (string.IsNullOrWhiteSpace(raw))
{
continue;
}
if (DateTime.TryParseExact(raw, "yyyy:MM:dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out var exact))
{
return exact;
}
if (DateTime.TryParse(raw, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out var parsed))
{
return parsed;
}
}
catch
{
// Ignore malformed metadata and continue.
}
}
return null;
}
private static string SanitizeBaseName(string name, string replacement)
{
var result = name;
foreach (var invalidChar in Path.GetInvalidFileNameChars())
{
result = result.Replace(invalidChar.ToString(), replacement, StringComparison.Ordinal);
}
result = result.Trim().TrimEnd('.');
return string.IsNullOrWhiteSpace(result) ? "image" : result;
}
}