Browse Source

Make rotation nearly work.

Former-commit-id: 43d3750d95462d1d81378b30aba36f17722f0be3
Former-commit-id: 3cafad31a2ed4936a79fef9304bcde1178624c20
Former-commit-id: bc27be7dce944472e548d0de50b23fd0bb04aae5
pull/17/head
James Jackson-South 10 years ago
parent
commit
d0421f9cb5
  1. 2
      global.json
  2. 32
      src/ImageProcessor/Common/Helpers/ImageMaths.cs
  3. 30
      src/ImageProcessor/Samplers/Resampler.cs

2
global.json

@ -3,6 +3,6 @@
"sdk": {
"version": "1.0.0-rc1-final",
"runtime": "coreclr",
"architecture": "x86"
"architecture": "x64"
}
}

32
src/ImageProcessor/Common/Helpers/ImageMaths.cs

@ -133,6 +133,38 @@ namespace ImageProcessor
};
}
/// <summary>
/// Calculates the new size after rotation.
/// </summary>
/// <param name="width">The width of the image.</param>
/// <param name="height">The height of the image.</param>
/// <param name="angleInDegrees">The angle of rotation.</param>
/// <returns>The new size of the image</returns>
public static Rectangle GetBoundingRotatedRectangle(int width, int height, float angleInDegrees)
{
// Check first clockwise.
double radians = DegreesToRadians(angleInDegrees);
double radiansSin = Math.Sin(radians);
double radiansCos = Math.Cos(radians);
double width1 = (height * radiansSin) + (width * radiansCos);
double height1 = (width * radiansSin) + (height * radiansCos);
// Find dimensions in the other direction
radiansSin = Math.Sin(-radians);
radiansCos = Math.Cos(-radians);
double width2 = (height * radiansSin) + (width * radiansCos);
double height2 = (width * radiansSin) + (height * radiansCos);
// Get the external vertex for the rotation
Rectangle result = new Rectangle(
0,
0,
Convert.ToInt32(Math.Max(Math.Abs(width1), Math.Abs(width2))),
Convert.ToInt32(Math.Max(Math.Abs(height1), Math.Abs(height2))));
return result;
}
/// <summary>
/// Ensures that any passed double is correctly rounded to zero
/// </summary>

30
src/ImageProcessor/Samplers/Resampler.cs

@ -22,7 +22,7 @@ namespace ImageProcessor.Samplers
/// <summary>
/// The angle of rotation.
/// </summary>
private double angle;
private double angle = 45;
/// <summary>
/// The horizontal weights.
@ -95,6 +95,10 @@ namespace ImageProcessor.Samplers
Point centre = Rectangle.Center(sourceRectangle);
bool rotate = this.angle > 0 && this.angle < 360;
int sourceBottom = sourceRectangle.Bottom;
int maxY = sourceBottom - 1;
int maxX = endX - 1;
Parallel.For(
startY,
endY,
@ -128,14 +132,14 @@ namespace ImageProcessor.Samplers
{
// Rotating at the centre point
Point rotated = ImageMaths.RotatePoint(new Point(originX, originY), this.angle, centre);
originX = rotated.X;
originY = rotated.Y;
int rotatedX = rotated.X;
int rotatedY = rotated.Y;
// TODO: This can't work. We're not normalising properly since weights are skipped.
// Also... This is so slow!
if (sourceRectangle.Contains(originX, originY))
if (sourceRectangle.Contains(rotatedX, rotatedY))
{
sourceColor = Color.InverseCompand(source[originX, originY]);
sourceColor = Color.InverseCompand(source[rotatedX, rotatedY]);
weight = (yw.Value / verticalSum) * (xw.Value / horizontalSum);
destination.R += sourceColor.R * weight;
@ -144,14 +148,16 @@ namespace ImageProcessor.Samplers
destination.A += sourceColor.A * weight;
}
}
else
{
sourceColor = Color.InverseCompand(source[originX, originY]);
weight = (yw.Value / verticalSum) * (xw.Value / horizontalSum);
sourceColor = Color.InverseCompand(source[originX, originY]);
weight = (yw.Value / verticalSum) * (xw.Value / horizontalSum);
destination.R += sourceColor.R * weight;
destination.G += sourceColor.G * weight;
destination.B += sourceColor.B * weight;
destination.A += sourceColor.A * weight;
destination.R += sourceColor.R * weight;
destination.G += sourceColor.G * weight;
destination.B += sourceColor.B * weight;
destination.A += sourceColor.A * weight;
}
}
}

Loading…
Cancel
Save