|
|
@ -142,8 +142,14 @@ void main() { |
|
|
|
|
|
|
|
// FIXME: this should probably be IDisposable?
|
|
|
|
public class Photo { |
|
|
|
public bool Loaded = false; |
|
|
|
public string File; |
|
|
|
public bool Loaded = false; |
|
|
|
public string? CameraModel; |
|
|
|
public string? LensModel; |
|
|
|
public string FNumber = "<unk>"; |
|
|
|
public string ExposureTime = "<unk>"; |
|
|
|
public string IsoSpeed = "<unk>"; |
|
|
|
|
|
|
|
private Texture texture; |
|
|
|
private Texture placeholder; |
|
|
|
private Image<Rgba32>? image = null; |
|
|
@ -158,11 +164,53 @@ public class Photo { |
|
|
|
image = await Image.LoadAsync<Rgba32>(File); |
|
|
|
ExifProfile? exifs = image.Metadata.ExifProfile; |
|
|
|
if (exifs != null) { |
|
|
|
foreach (IExifValue exif in exifs.Values) { |
|
|
|
if (exif.Tag.ToString() == "Model") { |
|
|
|
Console.WriteLine($"{File} {exif.Tag}: {exif.GetValue()}"); |
|
|
|
Console.WriteLine("--------------------------------------"); |
|
|
|
// FIXME: handle Orientation
|
|
|
|
IExifValue<string>? model; |
|
|
|
if (exifs.TryGetValue(ExifTag.Model, out model)) { |
|
|
|
CameraModel = model.Value; |
|
|
|
} |
|
|
|
IExifValue<string>? lensModel; |
|
|
|
if (exifs.TryGetValue(ExifTag.LensModel, out lensModel)) { |
|
|
|
LensModel = lensModel.Value; |
|
|
|
} |
|
|
|
|
|
|
|
IExifValue<Rational>? fNumber; |
|
|
|
if (exifs.TryGetValue(ExifTag.FNumber, out fNumber)) { |
|
|
|
Rational r = fNumber.Value; |
|
|
|
if (r.Denominator == 1) { |
|
|
|
FNumber = $"f/{r.Numerator}"; |
|
|
|
} else { |
|
|
|
// FIXME: assert that numerator is 10
|
|
|
|
if (r.Numerator % 10 == 0) { |
|
|
|
FNumber = $"f/{r.Numerator / 10}"; |
|
|
|
} else { |
|
|
|
FNumber= $"f/{r.Numerator / 10}.{r.Numerator % 10}"; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
IExifValue<Rational>? exposureTime; |
|
|
|
if (exifs.TryGetValue(ExifTag.ExposureTime, out exposureTime)) { |
|
|
|
Rational r = exposureTime.Value; |
|
|
|
if (r.Numerator == 1) { |
|
|
|
ExposureTime = $"1/{r.Denominator}"; |
|
|
|
} else if (r.Numerator == 10) { |
|
|
|
ExposureTime = $"1/{r.Denominator / 10}"; |
|
|
|
} else { |
|
|
|
Console.WriteLine("*** WARNING: unexpected ExposureTime numerator"); |
|
|
|
ExposureTime = r.ToString(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
IExifValue<ushort[]>? isoSpeed; |
|
|
|
if (exifs.TryGetValue(ExifTag.ISOSpeedRatings, out isoSpeed)) { |
|
|
|
ushort[] iso = isoSpeed.Value; |
|
|
|
IsoSpeed = $"ISO {iso[0]}"; |
|
|
|
} |
|
|
|
foreach (IExifValue exif in exifs.Values) { |
|
|
|
Console.WriteLine(exif.Tag.ToString() + " " + exif.GetValue().ToString()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -175,6 +223,15 @@ public class Photo { |
|
|
|
} |
|
|
|
return texture; |
|
|
|
} |
|
|
|
|
|
|
|
public string Description() { |
|
|
|
if (Loaded) { |
|
|
|
string shootingInfo = $"{FNumber} at {ExposureTime}, {IsoSpeed}"; |
|
|
|
return String.Format("{0,-30} {1,-50} {2}", shootingInfo, $"{CameraModel} {LensModel}", File); |
|
|
|
} else { |
|
|
|
return String.Format("{0,-81} {1}", "", File); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public class Texture : IDisposable { |
|
|
@ -293,7 +350,6 @@ public static class Util { |
|
|
|
image.Dispose(); |
|
|
|
return texture; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public class Game : GameWindow { |
|
|
@ -433,8 +489,8 @@ public class Game : GameWindow { |
|
|
|
GL.VertexAttribPointer(texCoordLocation, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float)); |
|
|
|
|
|
|
|
// Load textures from JPEGs.
|
|
|
|
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\desktop\photos-test\");
|
|
|
|
string[] files = Directory.GetFiles(@"c:\users\colin\pictures\photos\2023\07\14\"); |
|
|
|
// string[] files = Directory.GetFiles(@"C:\Users\colin\Pictures\photos\2018\06\23");
|
|
|
|
// string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\Germany all\104D7000");
|
|
|
|
|
|
|
@ -494,7 +550,7 @@ public class Game : GameWindow { |
|
|
|
} |
|
|
|
|
|
|
|
// Draw status box.
|
|
|
|
DrawText(activePhoto.File, geometry.StatusBox.Min.X + 80, geometry.StatusBox.Min.Y); |
|
|
|
DrawText(activePhoto.Description(), geometry.StatusBox.Min.X + 80, geometry.StatusBox.Min.Y); |
|
|
|
if (activePhoto.Loaded) { |
|
|
|
DrawText($"{(scale * 100):F1}%", geometry.StatusBox.Min.X, geometry.StatusBox.Min.Y); |
|
|
|
} |
|
|
|