From 82fae083e1ff562faa4484bd178c453aeee2db7a Mon Sep 17 00:00:00 2001 From: Sverre Rekvin Date: Sat, 2 Jul 2016 00:39:30 +0200 Subject: [PATCH] rotate Former-commit-id: b47614eda6c4bf9f50968bd324f27dcec5f685bb Former-commit-id: 8a1a1b13359ba260906d8439f131d0f07ce81cba Former-commit-id: 9ce6a4e24ec11eb2e0a90f9e12ea103c4dbacd8c --- .../Samplers/Processors/RotateProcessor.cs | 62 +++++-------------- 1 file changed, 14 insertions(+), 48 deletions(-) diff --git a/src/ImageProcessorCore/Samplers/Processors/RotateProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/RotateProcessor.cs index 33c31bf9c..0b6dd1a11 100644 --- a/src/ImageProcessorCore/Samplers/Processors/RotateProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/RotateProcessor.cs @@ -16,7 +16,6 @@ namespace ImageProcessorCore /// /// The image used for storing the first pass pixels. /// - private Image firstPass; /// /// The angle of rotation in degrees. @@ -38,24 +37,10 @@ namespace ImageProcessorCore set { - if (value > 360) - { - value -= 360; - } - - if (value < 0) - { - value += 360; - } - this.angle = value; } } - /// - /// Gets or sets the center point. - /// - public Point Center { get; set; } /// /// Gets or sets a value indicating whether to expand the canvas to fit the rotated image. @@ -65,57 +50,39 @@ namespace ImageProcessorCore /// protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) { - // If we are expanding we need to pad the bounds of the source rectangle. - // We can use the resizer in nearest neighbor mode to do this fairly quickly. if (this.Expand) { // First find out how big the target rectangle should be. - Point centre = this.Center == Point.Empty ? Rectangle.Center(sourceRectangle) : this.Center; + Point centre = Rectangle.Center(sourceRectangle); Matrix3x2 rotation = Point.CreateRotation(centre, -this.angle); Rectangle rectangle = ImageMaths.GetBoundingRectangle(sourceRectangle, rotation); - ResizeOptions options = new ResizeOptions - { - Size = new Size(rectangle.Width, rectangle.Height), - Mode = ResizeMode.BoxPad - }; - - // Get the padded bounds and resize the image. - Rectangle bounds = ResizeHelper.CalculateTargetLocationAndBounds(source, options); - this.firstPass = new Image(rectangle.Width, rectangle.Height); target.SetPixels(rectangle.Width, rectangle.Height, new float[rectangle.Width * rectangle.Height * 4]); - new ResizeProcessor(new NearestNeighborResampler()).Apply(this.firstPass, source, rectangle.Width, rectangle.Height, bounds, sourceRectangle); - } - else - { - // Just clone the pixels across. - this.firstPass = new Image(source.Width, source.Height); - this.firstPass.ClonePixels(source.Width, source.Height, source.Pixels); } } /// protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) { - int height = this.firstPass.Height; - int startX = 0; - int endX = this.firstPass.Width; - Point centre = this.Center == Point.Empty ? Rectangle.Center(this.firstPass.Bounds) : this.Center; - Matrix3x2 rotation = Point.CreateRotation(centre, -this.angle); - - // Since we are not working in parallel we use full height and width - // of the first pass image. + + Matrix3x2 rotation = Point.CreateRotation(new Point(0, 0), -this.angle); + Matrix3x2 tran = Matrix3x2.CreateTranslation(-target.Width / 2f, -target.Height / 2f); + rotation = tran * rotation; + Matrix3x2 tran2 = Matrix3x2.CreateTranslation(source.Width / 2f, source.Height / 2f); + rotation = rotation * tran2; + + Parallel.For( 0, - height, + target.Height, y => { - for (int x = startX; x < endX; x++) + for (int x = 0; x < target.Width; x++) { // Rotate at the centre point Point rotated = Point.Rotate(new Point(x, y), rotation); - if (this.firstPass.Bounds.Contains(rotated.X, rotated.Y)) + if (source.Bounds.Contains(rotated.X, rotated.Y)) { - target[x, y] = this.firstPass[rotated.X, rotated.Y]; + target[x, y] = source[rotated.X, rotated.Y]; } } @@ -126,8 +93,7 @@ namespace ImageProcessorCore /// protected override void AfterApply(ImageBase source, ImageBase target, Rectangle targetRectangle, Rectangle sourceRectangle) { - // Cleanup. - this.firstPass.Dispose(); + } } } \ No newline at end of file