straighten-and-crop kinda works

This commit is contained in:
Colin McMillen 2023-09-15 15:04:45 -04:00
parent b144da2399
commit 8b57464056

View File

@ -290,6 +290,36 @@ public class StraightenTool : ITool {
}
if (input.IsKeyPressed(Keys.Enter)) {
Matrix2 rotation = Matrix2.CreateRotation(MathHelper.DegreesToRadians(photo.RotationDegreeHundredths / 100f));
Vector2 center = new(photo.Size.X / 2f, photo.Size.Y / 2f);
float[] xCoords = new float[4];
float[] yCoords = new float[4];
List<Vector2i> corners = Util.RectangleCorners(new Rectangle(0, 0, photo.Size.X, photo.Size.Y));
for (int i = 0; i < 4; i++) {
Vector2i corner = corners[i];
Vector2 rotated = Util.RotateAboutCenter(corner, center, rotation);
xCoords[i] = rotated.X;
yCoords[i] = rotated.Y;
}
Array.Sort(xCoords);
Array.Sort(yCoords);
for (int i = 3; i >= 0; i--) {
xCoords[i] -= xCoords[0];
yCoords[i] -= yCoords[0];
}
// FIXME: we can get a bigger crop using a better algorithm -- this is
// too conservative. Also, preserve aspect ratio? Maybe we need to
// commit this as a separate crop immediately so that further crops are
// working on an image that isn't weirdly rotated. Or keep the
// straighten-crop as a separate operation from an ordinary crop.
int left = (int) Math.Ceiling(xCoords[1]);
int right = (int) Math.Floor(xCoords[2]);
int top = (int) Math.Ceiling(yCoords[1]);
int bottom = (int) Math.Floor(yCoords[2]);
photo.CropRectangle = Rectangle.FromLTRB(left, top, right, bottom);
return ToolStatus.Done;
}
@ -377,6 +407,12 @@ public static class Util {
return result;
}
public static Vector2 RotateAboutCenter(Vector2 vec, Vector2 center, Matrix2 transform) {
Vector2 centerRelative = vec - center;
centerRelative *= transform;
return centerRelative + center;
}
public static Image<Rgba32> MakeImage(float width, float height) {
return new((int) Math.Ceiling(width), (int) Math.Ceiling(height));
}
@ -1158,20 +1194,14 @@ public class Game : GameWindow {
GL.Viewport(0, 0, e.Width, e.Height);
}
private Vector2 RotateAboutCenter(Vector2 vec, Vector2 center, Matrix2 transform) {
Vector2 centerRelative = vec - center;
centerRelative *= transform;
return centerRelative + center;
}
private void SetVertices(float left, float top, float width, float height, float rotationDegrees) {
Matrix2 transform = Matrix2.CreateRotation(MathHelper.DegreesToRadians(rotationDegrees));
Vector2 center = new(left + width / 2, top + height / 2);
Vector2 topLeft = RotateAboutCenter(new Vector2(left, top), center, transform);
Vector2 topRight = RotateAboutCenter(new Vector2(left + width, top), center, transform);
Vector2 bottomRight = RotateAboutCenter(new Vector2(left + width, top + height), center, transform);
Vector2 bottomLeft = RotateAboutCenter(new Vector2(left, top + height), center, transform);
Vector2 topLeft = Util.RotateAboutCenter(new Vector2(left, top), center, transform);
Vector2 topRight = Util.RotateAboutCenter(new Vector2(left + width, top), center, transform);
Vector2 bottomRight = Util.RotateAboutCenter(new Vector2(left + width, top + height), center, transform);
Vector2 bottomLeft = Util.RotateAboutCenter(new Vector2(left, top + height), center, transform);
// top left
vertices[0] = topLeft.X;