diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs index 554de10bec..a1c83415bf 100644 --- a/src/ImageSharp/Common/Helpers/ImageMaths.cs +++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs @@ -162,10 +162,10 @@ namespace SixLabors.ImageSharp float maxX = MathF.Max(tl.X, MathF.Max(tr.X, MathF.Max(bl.X, br.X))); float minY = MathF.Min(tl.Y, MathF.Min(tr.Y, MathF.Min(bl.Y, br.Y))); float maxY = MathF.Max(tl.Y, MathF.Max(tr.Y, MathF.Max(bl.Y, br.Y))); - float sizeX = maxX - minX; - float sizeY = maxY - minY; + float sizeX = maxX - minX + .5F; + float sizeY = maxY - minY + .5F; - return new Rectangle((int)MathF.Floor(minX), (int)MathF.Floor(minY), (int)MathF.Ceiling(sizeX), (int)MathF.Ceiling(sizeY)); + return new Rectangle((int)(MathF.Ceiling(minX) - .5F), (int)(MathF.Ceiling(minY) - .5F), (int)MathF.Floor(sizeX), (int)MathF.Floor(sizeY)); } /// diff --git a/src/ImageSharp/Processing/Processors/Transforms/AffineProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/AffineProcessor.cs index f2e74abd1b..c9a4b2aeaf 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/AffineProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/AffineProcessor.cs @@ -127,10 +127,10 @@ namespace SixLabors.ImageSharp.Processing.Processors Vector2 minXY = point - radius; var extents = new Vector4( - MathF.Ceiling(maxXY.X), - MathF.Ceiling(maxXY.Y), - MathF.Floor(minXY.X), - MathF.Floor(minXY.Y)); + MathF.Floor(maxXY.X + .5F), + MathF.Floor(maxXY.Y + .5F), + MathF.Ceiling(minXY.X - .5F), + MathF.Ceiling(minXY.Y - .5F)); int right = (int)extents.X; int bottom = (int)extents.Y; @@ -154,23 +154,17 @@ namespace SixLabors.ImageSharp.Processing.Processors // since they can be at sub-pixel positions on both axis. // I've optimized where I can but am always open to suggestions. // - // Create and normalize the y-weights - if (yScale > 1) + // TODO: If we can somehow improve edge pixel handling that would be most beneficial. + // Currently the interpolated edge non-alpha components are altered which causes slight darkening of edges. + // Ideally the edge pixels should represent the nearest sample with altered alpha component only. + if (yScale > 1 && xScale > 1) { CalculateWeightsDown(top, bottom, minY, maxY, point.Y, sampler, yScale, ySpan); - } - else - { - CalculateWeightsScaleUp(minY, maxY, point.Y, sampler, ySpan); - } - - // Create and normalize the x-weights - if (xScale > 1) - { CalculateWeightsDown(left, right, minX, maxX, point.X, sampler, xScale, xSpan); } else { + CalculateWeightsScaleUp(minY, maxY, point.Y, sampler, ySpan); CalculateWeightsScaleUp(minX, maxX, point.X, sampler, xSpan); } diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/SkewTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/SkewTest.cs index 8e57327be0..17bf3def26 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/SkewTest.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/SkewTest.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms }; [Theory] - [WithFileCollection(nameof(DefaultFiles), nameof(SkewValues), DefaultPixelType)] + [WithTestPatternImages(nameof(SkewValues), 100, 50, DefaultPixelType)] public void ImageShouldSkew(TestImageProvider provider, float x, float y) where TPixel : struct, IPixel { @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } [Theory] - [WithFileCollection(nameof(DefaultFiles), nameof(SkewValues), DefaultPixelType)] + [WithTestPatternImages(nameof(SkewValues), 100, 50, DefaultPixelType)] public void ImageShouldSkewWithSampler(TestImageProvider provider, float x, float y) where TPixel : struct, IPixel {