ExportPhotos(): add progress on statusbar, skip if already exporting

This commit is contained in:
Colin McMillen 2023-08-30 17:57:01 -04:00
parent c1ed48b917
commit 5d70b4c54b

View File

@ -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)));
@ -410,8 +410,7 @@ public class Game : GameWindow {
int VertexBufferObject; int VertexBufferObject;
int ElementBufferObject; int ElementBufferObject;
int VertexArrayObject; int VertexArrayObject;
int numThumbnailsLoaded = 0;
readonly object numThumbnailsLoadedLock = new();
List<Photo> allPhotos = new(); List<Photo> allPhotos = new();
List<Photo> photos = new(); List<Photo> photos = new();
HashSet<Photo> loadedImages = new(); HashSet<Photo> loadedImages = new();
@ -431,6 +430,15 @@ public class Game : GameWindow {
float zoomLevel = 0f; float zoomLevel = 0f;
double timeSinceEvent = 0; double timeSinceEvent = 0;
// Variables that are protected by locks:
readonly object numThumbnailsLoadedLock = new();
int numThumbnailsLoaded = 0;
readonly object exportPhotosLock = new(); // locks the entire ExportPhotos() function.
int numPhotosToExport = 0;
readonly object numPhotosExportedLock = new();
int numPhotosExported = 0;
protected override void OnUpdateFrame(FrameEventArgs e) { protected override void OnUpdateFrame(FrameEventArgs e) {
base.OnUpdateFrame(e); base.OnUpdateFrame(e);
toast.Update(e.Time); toast.Update(e.Time);
@ -684,7 +692,7 @@ public class Game : GameWindow {
false, 5 * sizeof(float), 3 * sizeof(float)); false, 5 * sizeof(float), 3 * sizeof(float));
// Load photos from a directory. // Load photos from a directory.
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\");
@ -692,7 +700,7 @@ public class Game : GameWindow {
// 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");
// string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\many-birds\"); string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\many-birds\");
for (int i = 0; i < files.Count(); i++) { for (int i = 0; i < files.Count(); i++) {
string file = files[i]; string file = files[i];
@ -793,7 +801,7 @@ public class Game : GameWindow {
p.LoadThumbnailAsync(geometry.ThumbnailSize); p.LoadThumbnailAsync(geometry.ThumbnailSize);
lock (numThumbnailsLoadedLock) { lock (numThumbnailsLoadedLock) {
numThumbnailsLoaded++; numThumbnailsLoaded++;
toast.Set($"Loading thumbnails: {numThumbnailsLoaded}/{allPhotos.Count}"); toast.Set($"[{numThumbnailsLoaded}/{allPhotos.Count}] Loading thumbnails");
} }
})); }));
} }
@ -802,13 +810,31 @@ public class Game : GameWindow {
// To find the JPEG compression level of a file from the command line: // To find the JPEG compression level of a file from the command line:
// $ identify -verbose image.jpg | grep Quality: // $ identify -verbose image.jpg | grep Quality:
// FIXME: don't ExportPhotos() if another export is already active.
// FIXME: show a progress bar or something.
private async void ExportPhotos() { private async void ExportPhotos() {
JpegEncoder encoder = new JpegEncoder() { Quality = 100 }; List<Task> tasks = new();
foreach (Photo p in photos) { lock (exportPhotosLock) {
await Task.Run( () => { p.SaveAsJpegAsync(outputRoot, encoder); }); // Don't ExportPhotos() if one is already active.
lock (numPhotosExportedLock) {
if (numPhotosToExport > 0 && numPhotosExported != numPhotosToExport) {
Console.WriteLine("ExportPhotos: skipping because another export is already in progress.");
return;
}
}
JpegEncoder encoder = new JpegEncoder() { Quality = 100 };
numPhotosToExport = photos.Count;
numPhotosExported = 0;
foreach (Photo p in photos) {
tasks.Add(Task.Run( () => {
p.SaveAsJpegAsync(outputRoot, encoder);
lock (numPhotosExportedLock) {
numPhotosExported++;
toast.Set($"[{numPhotosExported}/{numPhotosToExport}] Exported {outputRoot}/{p.Filename}");
}
}));
}
} }
await Task.WhenAll(tasks).ContinueWith(t => { toast.Set("Exporting photos: done!"); });
} }
protected override void OnRenderFrame(FrameEventArgs e) { protected override void OnRenderFrame(FrameEventArgs e) {