start of Exif orientation handling

This commit is contained in:
Colin McMillen 2023-07-25 14:28:57 -04:00
parent 98cae0e9c1
commit c461d55101

View File

@ -27,6 +27,7 @@ public class CameraInfo {
public static readonly CameraInfo IPHONE_12_MINI = new(new Vector2i(4032, 3024)); public static readonly CameraInfo IPHONE_12_MINI = new(new Vector2i(4032, 3024));
} }
// FIXME: switch to immediate mode??
public class Shader : IDisposable { public class Shader : IDisposable {
public int Handle; public int Handle;
private bool init = false; private bool init = false;
@ -165,14 +166,22 @@ public class Photo {
} }
public async void Load() { public async void Load() {
image = await Image.LoadAsync<Rgba32>(File); // We don't assign to this.image until Load() is done, because we might
TryParseRating(image.Metadata.XmpProfile, out Rating); // edit the image due to rotation (etc) and don't want to try generating
ExifProfile? exifs = image.Metadata.ExifProfile; // a texture for it until that's already happened.
Image<Rgba32> tmpImage = await Image.LoadAsync<Rgba32>(File);
TryParseRating(tmpImage.Metadata.XmpProfile, out Rating);
ExifProfile? exifs = tmpImage.Metadata.ExifProfile;
if (exifs != null) { if (exifs != null) {
// FIXME: handle Orientation // 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: handle date shot / edited (and sort by shot date?)
// FIXME: PixelXDimension & PixelYDimension hold the image geometry in Exif. // 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; IExifValue<string>? model;
if (exifs.TryGetValue(ExifTag.Model, out model)) { if (exifs.TryGetValue(ExifTag.Model, out model)) {
CameraModel = model.Value ?? ""; CameraModel = model.Value ?? "";
@ -238,6 +247,7 @@ public class Photo {
// foreach (IExifValue exif in exifs.Values) { // foreach (IExifValue exif in exifs.Values) {
// Console.WriteLine(exif.Tag.ToString() + " " + exif.GetValue().ToString()); // Console.WriteLine(exif.Tag.ToString() + " " + exif.GetValue().ToString());
// } // }
image = tmpImage;
} }
} }
@ -374,6 +384,16 @@ public static class Util {
return new((int) Math.Ceiling(width), (int) Math.Ceiling(height)); return new((int) Math.Ceiling(width), (int) Math.Ceiling(height));
} }
// https://sirv.com/help/articles/rotate-photos-to-be-upright/
public static void RotateImageFromExif(Image<Rgba32> image, ushort orientation) {
if (orientation == 1) {
return;
}
if (orientation == 8) {
image.Mutate(x => x.RotateFlip(RotateMode.Rotate270, FlipMode.None));
}
}
public static Texture RenderText(string text) { public static Texture RenderText(string text) {
return RenderText(text, 16); return RenderText(text, 16);
} }
@ -542,8 +562,8 @@ public class Game : GameWindow {
// Load textures from JPEGs. // Load textures from JPEGs.
// 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(@"G:\DCIM\100EOSR6\"); string[] files = Directory.GetFiles(@"G:\DCIM\100EOSR6\");
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");
// string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\many-birds\"); // string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\many-birds\");