From f6457ba3aac2e4e2e1fa93d63b7c4b2ecd80a871 Mon Sep 17 00:00:00 2001 From: Sverre Rekvin Date: Wed, 22 Jun 2016 21:40:05 +0200 Subject: [PATCH] Removed first pass Former-commit-id: ae4c65acb9d7eb7b5d2840b6a268ee8483d226b1 Former-commit-id: ac8bb1c013bf432f990487d01b3e797578ce29b0 Former-commit-id: 9965e32b231efe13d189ecb6d6f594d9809b6d93 --- NuGet.config | 2 +- .../Samplers/Processors/SkewProcessor.cs | 83 ++++++++++--------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/NuGet.config b/NuGet.config index 554c2f634..18aee5e9d 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,4 +1,4 @@ - + diff --git a/src/ImageProcessorCore/Samplers/Processors/SkewProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/SkewProcessor.cs index 1bfcfb7e2..d7498d286 100644 --- a/src/ImageProcessorCore/Samplers/Processors/SkewProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/SkewProcessor.cs @@ -3,6 +3,8 @@ // Licensed under the Apache License, Version 2.0. // +using System; + namespace ImageProcessorCore { using System.Numerics; @@ -13,11 +15,7 @@ namespace ImageProcessorCore /// public class SkewProcessor : ImageSampler { - /// - /// The image used for storing the first pass pixels. - /// - private Image firstPass; - + /// /// The angle of rotation along the x-axis. /// @@ -112,53 +110,60 @@ namespace ImageProcessorCore // 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); + target.SetPixels(rectangle.Width, rectangle.Height, new float[rectangle.Width * rectangle.Height * 4]); } } /// 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 skew = Point.CreateSkew(centre, -this.angleX, -this.angleY); - - // Since we are not working in parallel we use full height and width - // of the first pass image. - Parallel.For( - 0, - height, - y => + + int skewMaxX = target.Width - source.Width; + int skewMaxY = target.Height - source.Height; + + int[] deltaX = new int[source.Height]; + for (int i = 0; i < deltaX.Length; i++) + { + deltaX[i] = GetSkewDelta(i, angleX); + if (angleX < 0) { - for (int x = startX; x < endX; x++) - { - // Skew at the centre point - Point skewed = Point.Skew(new Point(x, y), skew); - if (this.firstPass.Bounds.Contains(skewed.X, skewed.Y)) - { - target[x, y] = this.firstPass[skewed.X, skewed.Y]; - } - } - - this.OnRowProcessed(); - }); + deltaX[i] += skewMaxX; + } + } + + + Parallel.For( + 0, + source.Width, + sx => + { + int deltaY = GetSkewDelta(sx, angleY); + if (AngleY < 0) + { + deltaY += skewMaxY; + } + for (int sy = 0; sy < source.Height; sy++) + { + target[deltaX[sy] + sx, deltaY + sy] = source[sx, sy]; + } + this.OnRowProcessed(); + }); } + private int GetSkewDelta(int sy, float angle) + { + float radians = ImageMaths.DegreesToRadians(angle); + double delta = Math.Tan(radians); + delta = delta * sy; + return ((int)delta); + } + + + /// protected override void AfterApply(ImageBase source, ImageBase target, Rectangle targetRectangle, Rectangle sourceRectangle) { // Cleanup. - this.firstPass.Dispose(); } } } \ No newline at end of file