|
|
@ -154,6 +154,7 @@ public class Photo { |
|
|
|
public string ExposureTime = "<unk>"; |
|
|
|
public string IsoSpeed = "<unk>"; |
|
|
|
public int Rating = 0; |
|
|
|
public ushort Orientation = 1; |
|
|
|
|
|
|
|
private Texture texture; |
|
|
|
private Texture placeholder; |
|
|
@ -170,85 +171,10 @@ public class Photo { |
|
|
|
// edit the image due to rotation (etc) and don't want to try generating
|
|
|
|
// a texture for it until that's already happened.
|
|
|
|
Image<Rgba32> tmpImage = await Image.LoadAsync<Rgba32>(File); |
|
|
|
ParseExif(tmpImage.Metadata.ExifProfile); |
|
|
|
TryParseRating(tmpImage.Metadata.XmpProfile, out Rating); |
|
|
|
ExifProfile? exifs = tmpImage.Metadata.ExifProfile; |
|
|
|
if (exifs != null) { |
|
|
|
// FIXME: when we write out images, we'll want to correct the Exif Orientation to 1.
|
|
|
|
// FIXME: handle date shot / edited (and sort by shot date?)
|
|
|
|
// FIXME: PixelXDimension & PixelYDimension hold the image geometry in Exif.
|
|
|
|
|
|
|
|
IExifValue<ushort>? orientation; |
|
|
|
if (exifs.TryGetValue(ExifTag.Orientation, out orientation)) { |
|
|
|
Util.RotateImageFromExif(tmpImage, orientation.Value); |
|
|
|
} |
|
|
|
|
|
|
|
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>? focalLength; |
|
|
|
if (exifs.TryGetValue(ExifTag.FocalLength, out focalLength)) { |
|
|
|
Rational r = focalLength.Value; |
|
|
|
FocalLength = $"{r.Numerator / r.Denominator}mm"; |
|
|
|
} |
|
|
|
|
|
|
|
IExifValue<Rational>? fNumber; |
|
|
|
if (exifs.TryGetValue(ExifTag.FNumber, out fNumber)) { |
|
|
|
Rational r = fNumber.Value; |
|
|
|
if (r.Denominator == 1) { |
|
|
|
FNumber = $"f/{r.Numerator}"; |
|
|
|
} else { |
|
|
|
if (r.Denominator != 10) { |
|
|
|
Console.WriteLine($"*** WARNING: unexpected FNumber denominator: {r.Denominator}"); |
|
|
|
} |
|
|
|
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 if (r.Denominator == 1) { |
|
|
|
ExposureTime = $"{r.Numerator }\"";
|
|
|
|
} else if (r.Denominator == 10) { |
|
|
|
ExposureTime = $"{r.Numerator / 10}.{r.Numerator % 10}\"";
|
|
|
|
} else { |
|
|
|
Console.WriteLine($"*** WARNING: unexpected ExposureTime: {r.Numerator}/{r.Denominator}"); |
|
|
|
ExposureTime = r.ToString(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
IExifValue<ushort[]>? isoSpeed; |
|
|
|
if (exifs.TryGetValue(ExifTag.ISOSpeedRatings, out isoSpeed)) { |
|
|
|
ushort[]? iso = isoSpeed.Value; |
|
|
|
if (iso != null) { |
|
|
|
if (iso.Length != 1) { |
|
|
|
Console.WriteLine($"*** WARNING: unexpected ISOSpeedRatings array length: {iso.Length}"); |
|
|
|
} |
|
|
|
if (iso.Length >= 1) { |
|
|
|
IsoSpeed = $"ISO {iso[0]}"; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// foreach (IExifValue exif in exifs.Values) {
|
|
|
|
// Console.WriteLine(exif.Tag.ToString() + " " + exif.GetValue().ToString());
|
|
|
|
// }
|
|
|
|
image = tmpImage; |
|
|
|
} |
|
|
|
Util.RotateImageFromExif(tmpImage, Orientation); |
|
|
|
image = tmpImage; |
|
|
|
} |
|
|
|
|
|
|
|
private bool TryParseRating(XmpProfile? xmp, out int rating) { |
|
|
@ -274,6 +200,87 @@ public class Photo { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
private void ParseExif(ExifProfile? exifs) { |
|
|
|
if (exifs == null) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// FIXME: when we write out images, we'll want to correct the Exif Orientation to 1.
|
|
|
|
// FIXME: handle date shot / edited (and sort by shot date?)
|
|
|
|
// FIXME: PixelXDimension & PixelYDimension hold the image geometry in Exif.
|
|
|
|
|
|
|
|
IExifValue<ushort>? orientation; |
|
|
|
if (exifs.TryGetValue(ExifTag.Orientation, out orientation)) { |
|
|
|
Orientation = orientation.Value; |
|
|
|
} |
|
|
|
|
|
|
|
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>? focalLength; |
|
|
|
if (exifs.TryGetValue(ExifTag.FocalLength, out focalLength)) { |
|
|
|
Rational r = focalLength.Value; |
|
|
|
FocalLength = $"{r.Numerator / r.Denominator}mm"; |
|
|
|
} |
|
|
|
|
|
|
|
IExifValue<Rational>? fNumber; |
|
|
|
if (exifs.TryGetValue(ExifTag.FNumber, out fNumber)) { |
|
|
|
Rational r = fNumber.Value; |
|
|
|
if (r.Denominator == 1) { |
|
|
|
FNumber = $"f/{r.Numerator}"; |
|
|
|
} else { |
|
|
|
if (r.Denominator != 10) { |
|
|
|
Console.WriteLine($"*** WARNING: unexpected FNumber denominator: {r.Denominator}"); |
|
|
|
} |
|
|
|
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 if (r.Denominator == 1) { |
|
|
|
ExposureTime = $"{r.Numerator }\"";
|
|
|
|
} else if (r.Denominator == 10) { |
|
|
|
ExposureTime = $"{r.Numerator / 10}.{r.Numerator % 10}\"";
|
|
|
|
} else { |
|
|
|
Console.WriteLine($"*** WARNING: unexpected ExposureTime: {r.Numerator}/{r.Denominator}"); |
|
|
|
ExposureTime = r.ToString(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
IExifValue<ushort[]>? isoSpeed; |
|
|
|
if (exifs.TryGetValue(ExifTag.ISOSpeedRatings, out isoSpeed)) { |
|
|
|
ushort[]? iso = isoSpeed.Value; |
|
|
|
if (iso != null) { |
|
|
|
if (iso.Length != 1) { |
|
|
|
Console.WriteLine($"*** WARNING: unexpected ISOSpeedRatings array length: {iso.Length}"); |
|
|
|
} |
|
|
|
if (iso.Length >= 1) { |
|
|
|
IsoSpeed = $"ISO {iso[0]}"; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// foreach (IExifValue exif in exifs.Values) {
|
|
|
|
// Console.WriteLine(exif.Tag.ToString() + " " + exif.GetValue().ToString());
|
|
|
|
// }
|
|
|
|
} |
|
|
|
|
|
|
|
public Texture Texture() { |
|
|
|
if (texture == placeholder && image != null) { |
|
|
|
texture = new Texture(image); |
|
|
@ -578,6 +585,16 @@ public class Game : GameWindow { |
|
|
|
// string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\Germany all\104D7000");
|
|
|
|
// string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\many-birds\");
|
|
|
|
|
|
|
|
Console.WriteLine(DateTime.Now.ToString()); |
|
|
|
for (int i = 0; i < files.Count(); i++) { |
|
|
|
string file = files[i]; |
|
|
|
if (file.ToLower().EndsWith(".jpg")) { |
|
|
|
ImageInfo info = Image.Identify(file); |
|
|
|
Console.WriteLine(file + " " + i + " " + info.Size); |
|
|
|
} |
|
|
|
} |
|
|
|
Console.WriteLine(DateTime.Now.ToString()); |
|
|
|
|
|
|
|
for (int i = 0; i < files.Count(); i++) { |
|
|
|
string file = files[i]; |
|
|
|
if (file.ToLower().EndsWith(".jpg")) { |
|
|
|