cropping works! janky af for now, but it works
This commit is contained in:
parent
e5c1b01806
commit
473fac7a6f
57
Program.cs
57
Program.cs
@ -185,6 +185,7 @@ public class Photo {
|
||||
public string IsoSpeed = "<unk>";
|
||||
public int Rating = 0;
|
||||
public ushort Orientation = 1;
|
||||
public Rectangle CropRectangle = Rectangle.Empty;
|
||||
|
||||
private static long touchCounter = 0;
|
||||
private Texture texture;
|
||||
@ -237,6 +238,9 @@ public class Photo {
|
||||
// FIXME: warn if the file already exists?
|
||||
using (Image<Rgba32> image = await Image.LoadAsync<Rgba32>(Filename)) {
|
||||
Util.RotateImageFromExif(image, Orientation);
|
||||
if (CropRectangle != Rectangle.Empty) {
|
||||
image.Mutate(x => x.Crop(CropRectangle));
|
||||
}
|
||||
|
||||
ExifProfile exif = image.Metadata.ExifProfile ?? new();
|
||||
exif.SetValue<ushort>(ExifTag.Orientation, 1);
|
||||
@ -504,7 +508,7 @@ public class UiGeometry {
|
||||
ThumbnailBoxes.Add(box);
|
||||
}
|
||||
|
||||
int statusBoxHeight = 20;
|
||||
int statusBoxHeight = 40;
|
||||
int statusBoxPadding = 4;
|
||||
PhotoBox = new Box2i(0, 0, WindowSize.X - thumbnailWidth, WindowSize.Y - statusBoxHeight - statusBoxPadding);
|
||||
StatusBox = new Box2i(0, WindowSize.Y - statusBoxHeight, WindowSize.X - thumbnailWidth, WindowSize.Y);
|
||||
@ -609,6 +613,9 @@ public static class Util {
|
||||
public class Game : GameWindow {
|
||||
public Game(GameWindowSettings gwSettings, NativeWindowSettings nwSettings) : base(gwSettings, nwSettings) {}
|
||||
|
||||
private static string outputRoot = @"c:\users\colin\desktop\totte-output";
|
||||
// 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_BLACK = new(new Image<Rgba32>(1, 1, new Rgba32(0, 0, 0)));
|
||||
private static Texture STAR_FILLED = Util.RenderStar(20, true);
|
||||
@ -637,9 +644,11 @@ public class Game : GameWindow {
|
||||
readonly object loadedImagesLock = new();
|
||||
int photoIndex = 0;
|
||||
int ribbonIndex = 0;
|
||||
Vector2i mousePosition;
|
||||
Vector2i mouseDragStart;
|
||||
Vector2i mouseDragEnd;
|
||||
float activeScale = 1f;
|
||||
Vector2i activeOffset;
|
||||
Shader shader = new();
|
||||
Matrix4 projection;
|
||||
float zoomLevel = 0f;
|
||||
@ -662,7 +671,7 @@ public class Game : GameWindow {
|
||||
|
||||
int lastPhotoIndex = photoIndex;
|
||||
|
||||
Vector2i mousePosition = (Vector2i) MouseState.Position;
|
||||
mousePosition = (Vector2i) MouseState.Position;
|
||||
|
||||
// Look for mouse clicks on thumbnails or stars.
|
||||
//
|
||||
@ -970,8 +979,6 @@ public class Game : GameWindow {
|
||||
// FIXME: show a progress bar or something.
|
||||
private async void ExportPhotos() {
|
||||
JpegEncoder encoder = new JpegEncoder() { Quality = 100 };
|
||||
string outputRoot = @"c:\users\colin\desktop\totte-output";
|
||||
// string outputRoot = @"c:\users\colin\pictures\photos";
|
||||
foreach (Photo p in photos) {
|
||||
await Task.Run( () => { p.SaveAsJpegAsync(outputRoot, encoder); });
|
||||
}
|
||||
@ -1018,17 +1025,25 @@ public class Game : GameWindow {
|
||||
void ApplyCrop() {
|
||||
var (left, right, top, bottom) = GetCrop();
|
||||
int area = (right - left) * (bottom - top);
|
||||
if (area < 100) {
|
||||
if (area == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2i leftTop = ScreenToImage(left, top);
|
||||
Vector2i rightBottom = ScreenToImage(right, bottom);
|
||||
Rectangle crop = Rectangle.FromLTRB(leftTop.X, leftTop.Y, rightBottom.X, rightBottom.Y);
|
||||
Photo photo = photos[photoIndex];
|
||||
// FIXME: make sure this doesn't exceed image.Bounds.
|
||||
// FIXME: once set, display it properly in the PhotoBox.
|
||||
photo.CropRectangle = crop;
|
||||
Console.WriteLine(crop);
|
||||
}
|
||||
|
||||
void DrawCropBox() {
|
||||
var (left, right, top, bottom) = GetCrop();
|
||||
int area = (right - left) * (bottom - top);
|
||||
|
||||
if (area < 100) {
|
||||
if (area == 0) {
|
||||
return;
|
||||
}
|
||||
Color4 shadeColor = new Color4(0, 0, 0, 0.75f);
|
||||
@ -1060,8 +1075,8 @@ public class Game : GameWindow {
|
||||
|
||||
Vector2i renderSize = (Vector2i) (((Vector2) active.Size) * scale);
|
||||
Vector2i center = (Vector2i) geometry.PhotoBox.Center;
|
||||
// Box2i photoBox = Util.MakeBox(center.X - renderSize.X / 2, center.Y - renderSize.Y / 2, renderSize.X, renderSize.Y);
|
||||
Box2i photoBox = Util.MakeBox(0, 0, renderSize.X, renderSize.Y);
|
||||
Box2i photoBox = Util.MakeBox(center.X - renderSize.X / 2, center.Y - renderSize.Y / 2, renderSize.X, renderSize.Y);
|
||||
activeOffset = new(photoBox.Min.X, photoBox.Min.Y);
|
||||
DrawTexture(active, photoBox);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
Texture star = (activePhoto.Rating > i) ? STAR_FILLED : STAR_EMPTY;
|
||||
@ -1090,13 +1105,29 @@ public class Game : GameWindow {
|
||||
// Draw status box.
|
||||
int statusPadding = 2;
|
||||
DrawFilledBox(geometry.StatusBox, Color4.Black);
|
||||
DrawText(String.Format("{0,4}/{1,-4}", photoIndex + 1, photos.Count), geometry.StatusBox.Min.X + 72, geometry.StatusBox.Min.Y + statusPadding);
|
||||
DrawText(activePhoto.Description(), geometry.StatusBox.Min.X + 160, geometry.StatusBox.Min.Y + statusPadding);
|
||||
DrawText(String.Format("FPS: {0,2}", fpsCounter.Fps), geometry.StatusBox.Max.X - 66, geometry.StatusBox.Min.Y + statusPadding);
|
||||
|
||||
// First line.
|
||||
int y = geometry.StatusBox.Min.Y + statusPadding;
|
||||
DrawText(activePhoto.Description(), geometry.StatusBox.Min.X, y);
|
||||
// Second line.
|
||||
y += 20;
|
||||
DrawText(String.Format("{0,4}/{1,-4}", photoIndex + 1, photos.Count), geometry.StatusBox.Min.X + 72, y);
|
||||
DrawText(String.Format("FPS: {0,2}", fpsCounter.Fps), geometry.StatusBox.Max.X - 66, y);
|
||||
if (activePhoto.Loaded) {
|
||||
DrawText($"{(scale * 100):F1}%", geometry.StatusBox.Min.X, geometry.StatusBox.Min.Y + statusPadding);
|
||||
DrawText($"{(scale * 100):F1}%", geometry.StatusBox.Min.X, y);
|
||||
}
|
||||
DrawText($"({mousePosition.X}, {mousePosition.Y})", geometry.StatusBox.Min.X + 160, y);
|
||||
Vector2i imagePosition = ScreenToImage(mousePosition);
|
||||
DrawText($"({imagePosition.X}, {imagePosition.Y})", geometry.StatusBox.Min.X + 320, y);
|
||||
}
|
||||
|
||||
Vector2i ScreenToImage(int x, int y) {
|
||||
return new(
|
||||
(int) ((x - activeOffset.X) / activeScale),
|
||||
(int) ((y - activeOffset.Y) / activeScale));
|
||||
}
|
||||
|
||||
Vector2i ScreenToImage(Vector2i position) {
|
||||
return ScreenToImage(position.X, position.Y);
|
||||
}
|
||||
|
||||
void DrawTexture(Texture texture, int x, int y) {
|
||||
|
Loading…
Reference in New Issue
Block a user