diff --git a/global.json b/global.json index 44d5d900f..f7f955356 100644 --- a/global.json +++ b/global.json @@ -3,6 +3,6 @@ "sdk": { "version": "1.0.0-rc1-final", "runtime": "coreclr", - "architecture": "x86" + "architecture": "x64" } } \ No newline at end of file diff --git a/src/ImageProcessor/Common/Helpers/ImageMaths.cs b/src/ImageProcessor/Common/Helpers/ImageMaths.cs index fc4c42040..7388e6cf5 100644 --- a/src/ImageProcessor/Common/Helpers/ImageMaths.cs +++ b/src/ImageProcessor/Common/Helpers/ImageMaths.cs @@ -133,6 +133,38 @@ namespace ImageProcessor }; } + /// + /// Calculates the new size after rotation. + /// + /// The width of the image. + /// The height of the image. + /// The angle of rotation. + /// The new size of the image + 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; + } + /// /// Ensures that any passed double is correctly rounded to zero /// diff --git a/src/ImageProcessor/Samplers/Resampler.cs b/src/ImageProcessor/Samplers/Resampler.cs index ae3c00950..c07c21f09 100644 --- a/src/ImageProcessor/Samplers/Resampler.cs +++ b/src/ImageProcessor/Samplers/Resampler.cs @@ -22,7 +22,7 @@ namespace ImageProcessor.Samplers /// /// The angle of rotation. /// - private double angle; + private double angle = 45; /// /// 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; + } } }