diff --git a/tests/ImageSharp.Tests/Processing/Transforms/TransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/TransformTests.cs index 9cb7890fe2..ac1e3812dc 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/TransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/TransformTests.cs @@ -16,6 +16,9 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { private readonly ITestOutputHelper Output; + /// + /// angleDeg, sx, sy, tx, ty + /// public static readonly TheoryData TransformValues = new TheoryData { @@ -51,6 +54,15 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms nameof(KnownResamplers.Welch), }; + public static readonly TheoryData Transform_DoesNotCreateEdgeArtifacts_ResamplerNames = + new TheoryData + { + nameof(KnownResamplers.NearestNeighbor), + nameof(KnownResamplers.Triangle), + nameof(KnownResamplers.Bicubic), + nameof(KnownResamplers.Lanczos8), + }; + public TransformTests(ITestOutputHelper output) { this.Output = output; @@ -60,10 +72,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms /// The output of an "all white" image should be "all white" or transparent, regardless of the transformation and the resampler. /// [Theory] - [WithSolidFilledImages(5, 5, 255, 255, 255, 255, PixelTypes.Rgba32, nameof(KnownResamplers.NearestNeighbor))] - [WithSolidFilledImages(5, 5, 255, 255, 255, 255, PixelTypes.Rgba32, nameof(KnownResamplers.Triangle))] - [WithSolidFilledImages(5, 5, 255, 255, 255, 255, PixelTypes.Rgba32, nameof(KnownResamplers.Bicubic))] - [WithSolidFilledImages(5, 5, 255, 255, 255, 255, PixelTypes.Rgba32, nameof(KnownResamplers.Lanczos8))] + [WithSolidFilledImages(nameof(Transform_DoesNotCreateEdgeArtifacts_ResamplerNames), 5, 5, 255, 255, 255, 255, PixelTypes.Rgba32)] public void Transform_DoesNotCreateEdgeArtifacts(TestImageProvider provider, string resamplerName) where TPixel : struct, IPixel { @@ -115,19 +124,36 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { using (Image image = provider.GetImage()) { - Matrix3x2 rotate = Matrix3x2Extensions.CreateRotationDegrees(angleDeg); - Vector2 toCenter = 0.5f * new Vector2(image.Width, image.Height); - var translate = Matrix3x2.CreateTranslation(-toCenter); - var translateBack = Matrix3x2.CreateTranslation(toCenter); - var scale = Matrix3x2.CreateScale(s); + Matrix3x2 m = this.MakeManuallyCenteredMatrix(angleDeg, s, image); - Matrix3x2 m = translate * rotate * scale * translateBack; + image.Mutate(i => i.Transform(m, KnownResamplers.Bicubic)); + image.DebugSave(provider, $"R({angleDeg})_S({s})"); + } + } - this.PrintMatrix(m); + public static readonly TheoryData Transform_IntoRectangle_Data = + new TheoryData + { + { 0, 0, 10, 10 }, + { 0, 0, 5, 10 }, + { 0, 0, 10, 5 }, + {-5,-5, 15, 15 } + }; - Rectangle destBounds = image.Bounds(); - image.Mutate(i => i.Transform(m, KnownResamplers.Bicubic, destBounds)); - image.DebugSave(provider, $"R({angleDeg})_S({s})"); + [Theory] + [WithSolidFilledImages(nameof(Transform_IntoRectangle_Data), 10, 10, nameof(Rgba32.Red), PixelTypes.Rgba32)] + public void Transform_IntoRectangle(TestImageProvider provider, int x0, int y0, int w, int h) + where TPixel : struct, IPixel + { + var rectangle = new Rectangle(x0, y0, w, h); + + using (Image image = provider.GetImage()) + { + Matrix3x2 m = this.MakeManuallyCenteredMatrix(45, 0.8f, image); + + image.Mutate(i => i.Transform(m, KnownResamplers.Spline, rectangle)); + string testDetails = $"({x0},{y0}-W{w},H{h})"; + image.DebugSave(provider, testDetails); } } @@ -142,13 +168,27 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms Matrix3x2 rotate = Matrix3x2Extensions.CreateRotationDegrees(50); Matrix3x2 scale = Matrix3x2Extensions.CreateScale(new SizeF(.5F, .5F)); var translate = Matrix3x2.CreateTranslation(75, 0); - - + image.Mutate(i => i.Transform(rotate * scale * translate, sampler)); image.DebugSave(provider, resamplerName); } } + private Matrix3x2 MakeManuallyCenteredMatrix(float angleDeg, float s, Image image) + where TPixel : struct, IPixel + { + Matrix3x2 rotate = Matrix3x2Extensions.CreateRotationDegrees(angleDeg); + Vector2 toCenter = 0.5f * new Vector2(image.Width, image.Height); + var translate = Matrix3x2.CreateTranslation(-toCenter); + var translateBack = Matrix3x2.CreateTranslation(toCenter); + var scale = Matrix3x2.CreateScale(s); + + Matrix3x2 m = translate * rotate * scale * translateBack; + + this.PrintMatrix(m); + return m; + } + private static IResampler GetResampler(string name) { PropertyInfo property = typeof(KnownResamplers).GetTypeInfo().GetProperty(name); diff --git a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithSolidFilledImagesAttribute.cs b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithSolidFilledImagesAttribute.cs index f787a35916..991f7108fe 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithSolidFilledImagesAttribute.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithSolidFilledImagesAttribute.cs @@ -6,6 +6,8 @@ using System.Reflection; namespace SixLabors.ImageSharp.Tests { + using SixLabors.ImageSharp.PixelFormats; + /// /// Triggers passing instances which produce an image of size width * height filled with the requested color. /// One instance will be passed for each the pixel format defined by the pixelTypes parameter @@ -56,14 +58,88 @@ namespace SixLabors.ImageSharp.Tests byte a, PixelTypes pixelTypes, params object[] additionalParameters) - : base(width, height, pixelTypes, additionalParameters) + : this(null, width, height, r, g, b, a, pixelTypes, additionalParameters) + { + } + + /// + /// Triggers passing instances which produce an image of size width * height filled with the requested color. + /// One instance will be passed for each the pixel format defined by the pixelTypes parameter + /// + /// The member data to apply to theories + /// The width of the requested image + /// The height of the requested image + /// Red + /// Green + /// Blue + /// /// Alpha + /// The requested pixel types + /// Additional theory parameter values + public WithSolidFilledImagesAttribute( + string memberData, + int width, + int height, + byte r, + byte g, + byte b, + byte a, + PixelTypes pixelTypes, + params object[] additionalParameters) + : base(memberData, width, height, pixelTypes, additionalParameters) { this.R = r; this.G = g; this.B = b; this.A = a; } - + + /// + /// Triggers passing instances which produce an image of size width * height filled with the requested color. + /// One instance will be passed for each the pixel format defined by the pixelTypes parameter + /// + /// The width of the requested image + /// The height of the requested image + /// The referenced color name (name of property in + /// The requested pixel types + /// Additional theory parameter values + public WithSolidFilledImagesAttribute( + int width, + int height, + string colorName, + PixelTypes pixelTypes, + params object[] additionalParameters) + : this(null, width, height, colorName, pixelTypes, additionalParameters) + { + } + + /// + /// Triggers passing instances which produce an image of size width * height filled with the requested color. + /// One instance will be passed for each the pixel format defined by the pixelTypes parameter + /// + /// The member data to apply to theories + /// The width of the requested image + /// The height of the requested image + /// The referenced color name (name of property in + /// The requested pixel types + /// Additional theory parameter values + public WithSolidFilledImagesAttribute( + string memberData, + int width, + int height, + string colorName, + PixelTypes pixelTypes, + params object[] additionalParameters) + : base(memberData, width, height, pixelTypes, additionalParameters) + { + Guard.NotNull(colorName, nameof(colorName)); + + var c = (Rgba32)typeof(Rgba32).GetTypeInfo().GetField(colorName).GetValue(null); + this.R = c.R; + this.G = c.G; + this.B = c.B; + this.A = c.A; + } + /// /// Red /// diff --git a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithTestPatternImageAttribute.cs b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithTestPatternImageAttribute.cs index 585bb8f066..7c659c64fc 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithTestPatternImageAttribute.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithTestPatternImageAttribute.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.Tests /// The requested parameter /// Additional theory parameter values public WithTestPatternImagesAttribute(int width, int height, PixelTypes pixelTypes, params object[] additionalParameters) - : this(null, width, height, pixelTypes,additionalParameters) + : this(null, width, height, pixelTypes, additionalParameters) { }