fix up GPS more properly
This commit is contained in:
parent
0ca67f2cef
commit
c0ac67103f
112
Photo.cs
112
Photo.cs
@ -9,6 +9,88 @@ using System.Xml.Linq;
|
|||||||
|
|
||||||
namespace SemiColinGames;
|
namespace SemiColinGames;
|
||||||
|
|
||||||
|
// https://exiftool.org/TagNames/GPS.html
|
||||||
|
public struct GpsInfo {
|
||||||
|
public byte[] VersionId;
|
||||||
|
public string Status;
|
||||||
|
public string Datestamp;
|
||||||
|
public Rational[] Timestamp;
|
||||||
|
public Rational[] Latitude;
|
||||||
|
public string LatitudeRef;
|
||||||
|
public Rational[] Longitude;
|
||||||
|
public string LongitudeRef;
|
||||||
|
public Rational Altitude;
|
||||||
|
public byte AltitudeRef;
|
||||||
|
|
||||||
|
// GpsStatus? DateStamp and TimeStamp?
|
||||||
|
public static GpsInfo? ParseExif(ExifProfile exif) {
|
||||||
|
GpsInfo gps;
|
||||||
|
|
||||||
|
IExifValue<byte[]>? versionId;
|
||||||
|
IExifValue<string>? status;
|
||||||
|
IExifValue<string>? datestamp;
|
||||||
|
IExifValue<Rational[]>? timestamp;
|
||||||
|
IExifValue<Rational[]>? latitude;
|
||||||
|
IExifValue<string>? latitudeRef;
|
||||||
|
IExifValue<Rational[]>? longitude;
|
||||||
|
IExifValue<string>? longitudeRef;
|
||||||
|
IExifValue<Rational>? altitude;
|
||||||
|
IExifValue<byte>? altitudeRef;
|
||||||
|
|
||||||
|
if (!exif.TryGetValue(ExifTag.GPSVersionID, out versionId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
gps.VersionId = versionId.Value ?? throw new NullReferenceException();
|
||||||
|
|
||||||
|
if (!exif.TryGetValue(ExifTag.GPSStatus, out status)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
gps.Status = status.Value ?? throw new NullReferenceException();
|
||||||
|
|
||||||
|
if (!exif.TryGetValue(ExifTag.GPSDateStamp, out datestamp)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
gps.Datestamp = datestamp.Value ?? throw new NullReferenceException();
|
||||||
|
|
||||||
|
if (!exif.TryGetValue(ExifTag.GPSTimestamp, out timestamp)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
gps.Timestamp = timestamp.Value ?? throw new NullReferenceException();
|
||||||
|
|
||||||
|
if (!exif.TryGetValue(ExifTag.GPSLatitude, out latitude)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
gps.Latitude = latitude.Value ?? throw new NullReferenceException();
|
||||||
|
|
||||||
|
if (!exif.TryGetValue(ExifTag.GPSLatitudeRef, out latitudeRef)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
gps.LatitudeRef = latitudeRef.Value ?? throw new NullReferenceException();
|
||||||
|
|
||||||
|
if (!exif.TryGetValue(ExifTag.GPSLongitude, out longitude)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
gps.Longitude = longitude.Value ?? throw new NullReferenceException();
|
||||||
|
|
||||||
|
if (!exif.TryGetValue(ExifTag.GPSLongitudeRef, out longitudeRef)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
gps.LongitudeRef = longitudeRef.Value ?? throw new NullReferenceException();
|
||||||
|
|
||||||
|
if (!exif.TryGetValue(ExifTag.GPSAltitude, out altitude)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
gps.Altitude = altitude.Value;
|
||||||
|
|
||||||
|
if (!exif.TryGetValue(ExifTag.GPSAltitudeRef, out altitudeRef)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
gps.AltitudeRef = altitudeRef.Value;
|
||||||
|
|
||||||
|
return gps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class Photo {
|
public class Photo {
|
||||||
public string Filename;
|
public string Filename;
|
||||||
public bool Loaded = false;
|
public bool Loaded = false;
|
||||||
@ -24,8 +106,7 @@ public class Photo {
|
|||||||
public string IsoSpeed = "<unk>";
|
public string IsoSpeed = "<unk>";
|
||||||
public int Rating = 0;
|
public int Rating = 0;
|
||||||
public ushort Orientation = 1;
|
public ushort Orientation = 1;
|
||||||
public Rational[]? GpsLatitude = null;
|
public GpsInfo? Gps = null;
|
||||||
public Rational[]? GpsLongitude = null;
|
|
||||||
public Rectangle CropRectangle = Rectangle.Empty;
|
public Rectangle CropRectangle = Rectangle.Empty;
|
||||||
|
|
||||||
private static long touchCounter = 0;
|
private static long touchCounter = 0;
|
||||||
@ -93,7 +174,6 @@ public class Photo {
|
|||||||
string filename = System.IO.Path.Combine(directory, System.IO.Path.GetFileName(Filename));
|
string filename = System.IO.Path.Combine(directory, System.IO.Path.GetFileName(Filename));
|
||||||
Console.WriteLine("saving " + filename);
|
Console.WriteLine("saving " + filename);
|
||||||
// FIXME: add comments / captions as ImageDescription?
|
// FIXME: add comments / captions as ImageDescription?
|
||||||
// FIXME: strip some Exif tags for privacy reasons?
|
|
||||||
// FIXME: warn if the file already exists?
|
// FIXME: warn if the file already exists?
|
||||||
using (Image<Rgba32> image = await Image.LoadAsync<Rgba32>(Filename)) {
|
using (Image<Rgba32> image = await Image.LoadAsync<Rgba32>(Filename)) {
|
||||||
Util.RotateImageFromExif(image, Orientation);
|
Util.RotateImageFromExif(image, Orientation);
|
||||||
@ -112,8 +192,20 @@ public class Photo {
|
|||||||
"{0:D4}:{1:D2}:{2:D2} {3:D2}:{4:D2}:{5:D2}",
|
"{0:D4}:{1:D2}:{2:D2} {3:D2}:{4:D2}:{5:D2}",
|
||||||
now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second);
|
now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second);
|
||||||
exif.SetValue<string>(ExifTag.DateTime, datetime);
|
exif.SetValue<string>(ExifTag.DateTime, datetime);
|
||||||
exif.SetValue<Rational[]>(ExifTag.GPSLatitude, GpsLatitude);
|
|
||||||
exif.SetValue<Rational[]>(ExifTag.GPSLongitude, GpsLongitude);
|
if (Gps != null) {
|
||||||
|
GpsInfo gps = (GpsInfo) Gps;
|
||||||
|
exif.SetValue<byte[]>(ExifTag.GPSVersionID, gps.VersionId);
|
||||||
|
exif.SetValue<string>(ExifTag.GPSStatus, gps.Status);
|
||||||
|
exif.SetValue<string>(ExifTag.GPSDateStamp, gps.Datestamp);
|
||||||
|
exif.SetValue<Rational[]>(ExifTag.GPSTimestamp, gps.Timestamp);
|
||||||
|
exif.SetValue<Rational[]>(ExifTag.GPSLatitude, gps.Latitude);
|
||||||
|
exif.SetValue<string>(ExifTag.GPSLatitudeRef, gps.LatitudeRef);
|
||||||
|
exif.SetValue<Rational[]>(ExifTag.GPSLongitude, gps.Longitude);
|
||||||
|
exif.SetValue<string>(ExifTag.GPSLongitudeRef, gps.LongitudeRef);
|
||||||
|
exif.SetValue<Rational>(ExifTag.GPSAltitude, gps.Altitude);
|
||||||
|
exif.SetValue<byte>(ExifTag.GPSAltitudeRef, gps.AltitudeRef);
|
||||||
|
}
|
||||||
|
|
||||||
image.Metadata.XmpProfile = UpdateXmp(image.Metadata.XmpProfile);
|
image.Metadata.XmpProfile = UpdateXmp(image.Metadata.XmpProfile);
|
||||||
|
|
||||||
@ -272,15 +364,7 @@ public class Photo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IExifValue<Rational[]>? gpsLatitude;
|
Gps = GpsInfo.ParseExif(exifs);
|
||||||
if (exifs.TryGetValue(ExifTag.GPSLatitude, out gpsLatitude)) {
|
|
||||||
GpsLatitude = gpsLatitude.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
IExifValue<Rational[]>? gpsLongitude;
|
|
||||||
if (exifs.TryGetValue(ExifTag.GPSLongitude, out gpsLongitude)) {
|
|
||||||
GpsLongitude = gpsLongitude.Value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetShortLensModel(string lensModel) {
|
public string GetShortLensModel(string lensModel) {
|
||||||
|
22
Program.cs
22
Program.cs
@ -386,8 +386,8 @@ public class Game : GameWindow {
|
|||||||
geometry = new UiGeometry(nwSettings.Size, STAR_FILLED.Size.X);
|
geometry = new UiGeometry(nwSettings.Size, STAR_FILLED.Size.X);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string outputRoot = @"c:\users\colin\desktop\totte-output";
|
// private static string outputRoot = @"c:\users\colin\desktop\totte-output";
|
||||||
// private static string outputRoot = @"c:\users\colin\pictures\photos";
|
private static string outputRoot = @"c:\users\colin\pictures\photos";
|
||||||
|
|
||||||
private static Texture TEXTURE_WHITE = new(new Image<Rgba32>(1, 1, new Rgba32(255, 255, 255)));
|
private static Texture TEXTURE_WHITE = new(new Image<Rgba32>(1, 1, new Rgba32(255, 255, 255)));
|
||||||
private static Texture TEXTURE_BLACK = new(new Image<Rgba32>(1, 1, new Rgba32(0, 0, 0)));
|
private static Texture TEXTURE_BLACK = new(new Image<Rgba32>(1, 1, new Rgba32(0, 0, 0)));
|
||||||
@ -687,8 +687,8 @@ public class Game : GameWindow {
|
|||||||
// string[] files = Directory.GetFiles(@"c:\users\colin\desktop\photos-test\");
|
// string[] files = Directory.GetFiles(@"c:\users\colin\desktop\photos-test\");
|
||||||
// string[] files = Directory.GetFiles(@"c:\users\colin\pictures\photos\2023\07\14\");
|
// string[] files = Directory.GetFiles(@"c:\users\colin\pictures\photos\2023\07\14\");
|
||||||
// string[] files = Directory.GetFiles(@"c:\users\colin\pictures\photos\2023\07\23\");
|
// string[] files = Directory.GetFiles(@"c:\users\colin\pictures\photos\2023\07\23\");
|
||||||
string[] files = Directory.GetFiles(@"G:\DCIM\100EOSR6\");
|
// string[] files = Directory.GetFiles(@"G:\DCIM\100EOSR6\");
|
||||||
// string[] files = Directory.GetFiles(@"c:\users\colin\desktop\totte-output\2023\07\31");
|
string[] files = Directory.GetFiles(@"c:\users\colin\desktop\totte-output\2023\08\29");
|
||||||
// string[] files = Directory.GetFiles(@"c:\users\colin\desktop\import");
|
// string[] files = Directory.GetFiles(@"c:\users\colin\desktop\import");
|
||||||
// string[] files = Directory.GetFiles(@"C:\Users\colin\Pictures\photos\2018\06\23");
|
// string[] files = Directory.GetFiles(@"C:\Users\colin\Pictures\photos\2018\06\23");
|
||||||
// string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\Germany all\104D7000");
|
// string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\Germany all\104D7000");
|
||||||
@ -705,17 +705,15 @@ public class Game : GameWindow {
|
|||||||
allPhotos.Sort(ComparePhotosByDate);
|
allPhotos.Sort(ComparePhotosByDate);
|
||||||
|
|
||||||
// Fix up photos with missing GPS.
|
// Fix up photos with missing GPS.
|
||||||
Rational[]? lastLatitude = null;
|
GpsInfo? lastGps = null;
|
||||||
Rational[]? lastLongitude = null;
|
|
||||||
foreach (Photo p in allPhotos) {
|
foreach (Photo p in allPhotos) {
|
||||||
if (p.GpsLatitude != null && p.GpsLongitude != null) {
|
if (p.Gps != null) {
|
||||||
lastLatitude = p.GpsLatitude;
|
lastGps = p.Gps;
|
||||||
lastLongitude = p.GpsLongitude;
|
|
||||||
}
|
}
|
||||||
if (p.GpsLatitude == null || p.GpsLongitude == null) {
|
if (p.Gps == null) {
|
||||||
|
// FIXME: should we take from the photo immediately _before_, or after?
|
||||||
Console.WriteLine("fixing GPS for " + p.Filename);
|
Console.WriteLine("fixing GPS for " + p.Filename);
|
||||||
p.GpsLatitude = lastLatitude;
|
p.Gps = lastGps;
|
||||||
p.GpsLongitude = lastLongitude;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
photos = allPhotos;
|
photos = allPhotos;
|
||||||
|
Loading…
Reference in New Issue
Block a user