diff --git a/src/ImageSharp/Formats/Jpeg/itu-t81.pdf b/src/ImageSharp/Formats/Jpeg/itu-t81.pdf new file mode 100644 index 000000000..83fba254b Binary files /dev/null and b/src/ImageSharp/Formats/Jpeg/itu-t81.pdf differ diff --git a/src/ImageSharp/Image/ImageBase{TPixel}.cs b/src/ImageSharp/Image/ImageBase{TPixel}.cs index 508c73eb2..647d60075 100644 --- a/src/ImageSharp/Image/ImageBase{TPixel}.cs +++ b/src/ImageSharp/Image/ImageBase{TPixel}.cs @@ -11,7 +11,7 @@ namespace ImageSharp using ImageSharp.Memory; using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; /// /// The base class of all images. Encapsulates the basic properties and methods required to manipulate diff --git a/src/ImageSharp/Image/ImageProcessingExtensions.cs b/src/ImageSharp/Image/ImageProcessingExtensions.cs index c9577ac15..8eed103d1 100644 --- a/src/ImageSharp/Image/ImageProcessingExtensions.cs +++ b/src/ImageSharp/Image/ImageProcessingExtensions.cs @@ -7,7 +7,7 @@ namespace ImageSharp { using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; /// /// Extension methods for the type. diff --git a/src/ImageSharp/Image/Image{TPixel}.cs b/src/ImageSharp/Image/Image{TPixel}.cs index 092706e41..059ccb9a0 100644 --- a/src/ImageSharp/Image/Image{TPixel}.cs +++ b/src/ImageSharp/Image/Image{TPixel}.cs @@ -15,7 +15,7 @@ namespace ImageSharp using Formats; using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; /// /// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes. diff --git a/src/ImageSharp/Processing/ColorMatrix/BlackWhite.cs b/src/ImageSharp/Processing/ColorMatrix/BlackWhite.cs index 76977455a..de543f2cd 100644 --- a/src/ImageSharp/Processing/ColorMatrix/BlackWhite.cs +++ b/src/ImageSharp/Processing/ColorMatrix/BlackWhite.cs @@ -9,7 +9,7 @@ namespace ImageSharp using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// diff --git a/src/ImageSharp/Processing/ColorMatrix/ColorBlindness.cs b/src/ImageSharp/Processing/ColorMatrix/ColorBlindness.cs index d012d6fe2..c48a86293 100644 --- a/src/ImageSharp/Processing/ColorMatrix/ColorBlindness.cs +++ b/src/ImageSharp/Processing/ColorMatrix/ColorBlindness.cs @@ -9,7 +9,7 @@ namespace ImageSharp using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// diff --git a/src/ImageSharp/Processing/ColorMatrix/Grayscale.cs b/src/ImageSharp/Processing/ColorMatrix/Grayscale.cs index 8700b63e8..daddf106c 100644 --- a/src/ImageSharp/Processing/ColorMatrix/Grayscale.cs +++ b/src/ImageSharp/Processing/ColorMatrix/Grayscale.cs @@ -5,11 +5,9 @@ namespace ImageSharp { - using System; - using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// @@ -17,6 +15,18 @@ namespace ImageSharp /// public static partial class ImageExtensions { + /// + /// Applies Grayscale toning to the image. + /// + /// The pixel format. + /// The image this method extends. + /// The . + public static Image Grayscale(this Image source) + where TPixel : struct, IPixel + { + return Grayscale(source, GrayscaleMode.Bt709); + } + /// /// Applies Grayscale toning to the image. /// @@ -24,23 +34,41 @@ namespace ImageSharp /// The image this method extends. /// The formula to apply to perform the operation. /// The . - public static Image Grayscale(this Image source, GrayscaleMode mode = GrayscaleMode.Bt709) + public static Image Grayscale(this Image source, GrayscaleMode mode) where TPixel : struct, IPixel { - return Grayscale(source, source.Bounds, mode); + return Grayscale(source, mode, source.Bounds); } /// - /// Applies Grayscale toning to the image. + /// Applies Grayscale toning to the image. /// /// The pixel format. /// The image this method extends. /// /// The structure that specifies the portion of the image object to alter. /// + /// The . + public static Image Grayscale(this Image source, Rectangle rectangle) + where TPixel : struct, IPixel + { + IImageProcessor processor = new GrayscaleBt709Processor(); + + source.ApplyProcessor(processor, rectangle); + return source; + } + + /// + /// Applies Grayscale toning to the image. + /// + /// The pixel format. + /// The image this method extends. /// The formula to apply to perform the operation. + /// + /// The structure that specifies the portion of the image object to alter. + /// /// The . - public static Image Grayscale(this Image source, Rectangle rectangle, GrayscaleMode mode = GrayscaleMode.Bt709) + public static Image Grayscale(this Image source, GrayscaleMode mode, Rectangle rectangle) where TPixel : struct, IPixel { IImageProcessor processor = mode == GrayscaleMode.Bt709 diff --git a/src/ImageSharp/Processing/ColorMatrix/Hue.cs b/src/ImageSharp/Processing/ColorMatrix/Hue.cs index 8dbc55530..bcaf68d9a 100644 --- a/src/ImageSharp/Processing/ColorMatrix/Hue.cs +++ b/src/ImageSharp/Processing/ColorMatrix/Hue.cs @@ -9,7 +9,7 @@ namespace ImageSharp using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// diff --git a/src/ImageSharp/Processing/ColorMatrix/Kodachrome.cs b/src/ImageSharp/Processing/ColorMatrix/Kodachrome.cs index 13a71a71e..a302bb2e9 100644 --- a/src/ImageSharp/Processing/ColorMatrix/Kodachrome.cs +++ b/src/ImageSharp/Processing/ColorMatrix/Kodachrome.cs @@ -9,7 +9,7 @@ namespace ImageSharp using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// diff --git a/src/ImageSharp/Processing/ColorMatrix/Lomograph.cs b/src/ImageSharp/Processing/ColorMatrix/Lomograph.cs index 937dca9ba..cbfeb7d05 100644 --- a/src/ImageSharp/Processing/ColorMatrix/Lomograph.cs +++ b/src/ImageSharp/Processing/ColorMatrix/Lomograph.cs @@ -9,7 +9,7 @@ namespace ImageSharp using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// diff --git a/src/ImageSharp/Processing/ColorMatrix/Polaroid.cs b/src/ImageSharp/Processing/ColorMatrix/Polaroid.cs index f1a573c05..ac9f7391f 100644 --- a/src/ImageSharp/Processing/ColorMatrix/Polaroid.cs +++ b/src/ImageSharp/Processing/ColorMatrix/Polaroid.cs @@ -9,7 +9,7 @@ namespace ImageSharp using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// diff --git a/src/ImageSharp/Processing/ColorMatrix/Saturation.cs b/src/ImageSharp/Processing/ColorMatrix/Saturation.cs index c41f304b4..ffe336c62 100644 --- a/src/ImageSharp/Processing/ColorMatrix/Saturation.cs +++ b/src/ImageSharp/Processing/ColorMatrix/Saturation.cs @@ -9,7 +9,7 @@ namespace ImageSharp using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// diff --git a/src/ImageSharp/Processing/ColorMatrix/Sepia.cs b/src/ImageSharp/Processing/ColorMatrix/Sepia.cs index 39eca4e8e..8488dcfe5 100644 --- a/src/ImageSharp/Processing/ColorMatrix/Sepia.cs +++ b/src/ImageSharp/Processing/ColorMatrix/Sepia.cs @@ -9,7 +9,7 @@ namespace ImageSharp using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// diff --git a/src/ImageSharp/Processing/Convolution/DetectEdges.cs b/src/ImageSharp/Processing/Convolution/DetectEdges.cs index 3aa1d0b51..368688f62 100644 --- a/src/ImageSharp/Processing/Convolution/DetectEdges.cs +++ b/src/ImageSharp/Processing/Convolution/DetectEdges.cs @@ -9,7 +9,7 @@ namespace ImageSharp using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// diff --git a/src/ImageSharp/Processing/Convolution/GaussianBlur.cs b/src/ImageSharp/Processing/Convolution/GaussianBlur.cs index 72abec6df..0b8c5383c 100644 --- a/src/ImageSharp/Processing/Convolution/GaussianBlur.cs +++ b/src/ImageSharp/Processing/Convolution/GaussianBlur.cs @@ -9,7 +9,7 @@ namespace ImageSharp using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// diff --git a/src/ImageSharp/Processing/Convolution/GaussianSharpen.cs b/src/ImageSharp/Processing/Convolution/GaussianSharpen.cs index 2ed99ea26..1a5d3c2df 100644 --- a/src/ImageSharp/Processing/Convolution/GaussianSharpen.cs +++ b/src/ImageSharp/Processing/Convolution/GaussianSharpen.cs @@ -9,7 +9,7 @@ namespace ImageSharp using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// diff --git a/src/ImageSharp/Processing/Effects/OilPainting.cs b/src/ImageSharp/Processing/Effects/OilPainting.cs index d4528b55b..fd65542e0 100644 --- a/src/ImageSharp/Processing/Effects/OilPainting.cs +++ b/src/ImageSharp/Processing/Effects/OilPainting.cs @@ -16,6 +16,35 @@ namespace ImageSharp /// public static partial class ImageExtensions { + /// + /// Alters the colors of the image recreating an oil painting effect with levels and brushSize + /// set to 10 and 15 respectively. + /// + /// The pixel format. + /// The image this method extends. + /// The . + public static Image OilPaint(this Image source) + where TPixel : struct, IPixel + { + return OilPaint(source, 10, 15); + } + + /// + /// Alters the colors of the image recreating an oil painting effect with levels and brushSize + /// set to 10 and 15 respectively. + /// + /// The pixel format. + /// The image this method extends. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// The . + public static Image OilPaint(this Image source, Rectangle rectangle) + where TPixel : struct, IPixel + { + return OilPaint(source, 10, 15, rectangle); + } + /// /// Alters the colors of the image recreating an oil painting effect. /// @@ -24,8 +53,8 @@ namespace ImageSharp /// The number of intensity levels. Higher values result in a broader range of color intensities forming part of the result image. /// The number of neighboring pixels used in calculating each individual pixel value. /// The . - public static Image OilPaint(this Image source, int levels = 10, int brushSize = 15) - where TPixel : struct, IPixel + public static Image OilPaint(this Image source, int levels, int brushSize) + where TPixel : struct, IPixel { return OilPaint(source, levels, brushSize, source.Bounds); } diff --git a/src/ImageSharp/Processing/Overlays/Glow.cs b/src/ImageSharp/Processing/Overlays/Glow.cs index 587bbe610..04c85e00c 100644 --- a/src/ImageSharp/Processing/Overlays/Glow.cs +++ b/src/ImageSharp/Processing/Overlays/Glow.cs @@ -5,8 +5,6 @@ namespace ImageSharp { - using System; - using ImageSharp.PixelFormats; using Processing.Processors; @@ -158,7 +156,7 @@ namespace ImageSharp public static Image Glow(this Image source, TPixel color, float radius, Rectangle rectangle, GraphicsOptions options) where TPixel : struct, IPixel { - GlowProcessor processor = new GlowProcessor(color, options) { Radius = radius, }; + var processor = new GlowProcessor(color, options) { Radius = radius, }; source.ApplyProcessor(processor, rectangle); return source; } diff --git a/src/ImageSharp/Processing/Overlays/Vignette.cs b/src/ImageSharp/Processing/Overlays/Vignette.cs index 2eaf2e1ef..c04e88718 100644 --- a/src/ImageSharp/Processing/Overlays/Vignette.cs +++ b/src/ImageSharp/Processing/Overlays/Vignette.cs @@ -5,8 +5,6 @@ namespace ImageSharp { - using System; - using ImageSharp.PixelFormats; using Processing.Processors; @@ -162,7 +160,7 @@ namespace ImageSharp public static Image Vignette(this Image source, TPixel color, float radiusX, float radiusY, Rectangle rectangle, GraphicsOptions options) where TPixel : struct, IPixel { - VignetteProcessor processor = new VignetteProcessor(color, options) { RadiusX = radiusX, RadiusY = radiusY }; + var processor = new VignetteProcessor(color, options) { RadiusX = radiusX, RadiusY = radiusY }; source.ApplyProcessor(processor, rectangle); return source; } diff --git a/src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs index a43f77a1c..37cc8a9d9 100644 --- a/src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs @@ -97,17 +97,7 @@ namespace ImageSharp.Processing.Processors int fyr = fy - radius; int offsetY = y + fyr; - // Skip the current row - if (offsetY < minY) - { - continue; - } - - // Outwith the current bounds so break. - if (offsetY >= maxY) - { - break; - } + offsetY = offsetY.Clamp(0, maxY); Span sourceOffsetRow = source.GetRowSpan(offsetY); @@ -115,34 +105,25 @@ namespace ImageSharp.Processing.Processors { int fxr = fx - radius; int offsetX = x + fxr; + offsetX = offsetX.Clamp(0, maxX); - // Skip the column - if (offsetX < 0) - { - continue; - } + var vector = sourceOffsetRow[offsetX].ToVector4(); - if (offsetX < maxX) - { - // ReSharper disable once AccessToDisposedClosure - var vector = sourceOffsetRow[offsetX].ToVector4(); + float sourceRed = vector.X; + float sourceBlue = vector.Z; + float sourceGreen = vector.Y; - float sourceRed = vector.X; - float sourceBlue = vector.Z; - float sourceGreen = vector.Y; + int currentIntensity = (int)MathF.Round((sourceBlue + sourceGreen + sourceRed) / 3F * (levels - 1)); - int currentIntensity = (int)MathF.Round((sourceBlue + sourceGreen + sourceRed) / 3F * (levels - 1)); + intensityBin[currentIntensity] += 1; + blueBin[currentIntensity] += sourceBlue; + greenBin[currentIntensity] += sourceGreen; + redBin[currentIntensity] += sourceRed; - intensityBin[currentIntensity] += 1; - blueBin[currentIntensity] += sourceBlue; - greenBin[currentIntensity] += sourceGreen; - redBin[currentIntensity] += sourceRed; - - if (intensityBin[currentIntensity] > maxIntensity) - { - maxIntensity = intensityBin[currentIntensity]; - maxIndex = currentIntensity; - } + if (intensityBin[currentIntensity] > maxIntensity) + { + maxIntensity = intensityBin[currentIntensity]; + maxIndex = currentIntensity; } } diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.Weights.cs b/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.Weights.cs index b5266c9bd..8aef87ec8 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.Weights.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.Weights.cs @@ -27,31 +27,52 @@ namespace ImageSharp.Processing.Processors public int Left; /// - /// The span of weights pointing to . + /// The length of the weights window /// - public Span Span; + public int Length; + + /// + /// The index in the destination buffer + /// + private readonly int flatStartIndex; + + /// + /// The buffer containing the weights values. + /// + private readonly Buffer buffer; /// /// Initializes a new instance of the struct. /// + /// The destination index in the buffer /// The local left index - /// The span + /// The span + /// The length of the window [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal WeightsWindow(int left, Span span) + internal WeightsWindow(int index, int left, Buffer2D buffer, int length) { + this.flatStartIndex = (index * buffer.Width) + left; this.Left = left; - this.Span = span; + this.buffer = buffer; + this.Length = length; } /// - /// Gets an unsafe float* pointer to the beginning of . + /// Gets a reference to the first item of the window. /// - public ref float Ptr => ref this.Span.DangerousGetPinnableReference(); + /// The reference to the first item of the window + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref float GetStartReference() + { + return ref this.buffer[this.flatStartIndex]; + } /// - /// Gets the lenghth of the weights window + /// Gets the span representing the portion of the that this window covers /// - public int Length => this.Span.Length; + /// The + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Span GetWindowSpan() => this.buffer.Slice(this.flatStartIndex, this.Length); /// /// Computes the sum of vectors in 'rowSpan' weighted by weight values, pointed by this instance. @@ -62,7 +83,7 @@ namespace ImageSharp.Processing.Processors [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4 ComputeWeightedRowSum(Span rowSpan, int sourceX) { - ref float horizontalValues = ref this.Ptr; + ref float horizontalValues = ref this.GetStartReference(); int left = this.Left; ref Vector4 vecPtr = ref Unsafe.Add(ref rowSpan.DangerousGetPinnableReference(), left + sourceX); @@ -89,7 +110,7 @@ namespace ImageSharp.Processing.Processors [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4 ComputeExpandedWeightedRowSum(Span rowSpan, int sourceX) { - ref float horizontalValues = ref this.Ptr; + ref float horizontalValues = ref this.GetStartReference(); int left = this.Left; ref Vector4 vecPtr = ref Unsafe.Add(ref rowSpan.DangerousGetPinnableReference(), left + sourceX); @@ -117,7 +138,7 @@ namespace ImageSharp.Processing.Processors [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4 ComputeWeightedColumnSum(Buffer2D firstPassPixels, int x, int sourceY) { - ref float verticalValues = ref this.Ptr; + ref float verticalValues = ref this.GetStartReference(); int left = this.Left; // Destination color components @@ -139,7 +160,7 @@ namespace ImageSharp.Processing.Processors /// internal class WeightsBuffer : IDisposable { - private Buffer2D dataBuffer; + private readonly Buffer2D dataBuffer; /// /// Initializes a new instance of the class. @@ -174,8 +195,7 @@ namespace ImageSharp.Processing.Processors /// The weights public WeightsWindow GetWeightsWindow(int destIdx, int leftIdx, int rightIdx) { - Span span = this.dataBuffer.GetRowSpan(destIdx).Slice(leftIdx, rightIdx - leftIdx + 1); - return new WeightsWindow(leftIdx, span); + return new WeightsWindow(destIdx, leftIdx, this.dataBuffer, rightIdx - leftIdx + 1); } } } diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs index 757b0889a..7245b961f 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs @@ -112,7 +112,7 @@ namespace ImageSharp.Processing.Processors WeightsWindow ws = result.GetWeightsWindow(i, left, right); result.Weights[i] = ws; - ref float weights = ref ws.Ptr; + ref float weightsBaseRef = ref ws.GetStartReference(); for (int j = left; j <= right; j++) { @@ -120,7 +120,7 @@ namespace ImageSharp.Processing.Processors sum += weight; // weights[j - left] = weight: - Unsafe.Add(ref weights, j - left) = weight; + Unsafe.Add(ref weightsBaseRef, j - left) = weight; } // Normalise, best to do it here rather than in the pixel loop later on. @@ -129,7 +129,7 @@ namespace ImageSharp.Processing.Processors for (int w = 0; w < ws.Length; w++) { // weights[w] = weights[w] / sum: - ref float wRef = ref Unsafe.Add(ref weights, w); + ref float wRef = ref Unsafe.Add(ref weightsBaseRef, w); wRef = wRef / sum; } } diff --git a/src/ImageSharp/Processing/Transforms/AutoOrient.cs b/src/ImageSharp/Processing/Transforms/AutoOrient.cs index f9d3a60aa..07e5d5bc9 100644 --- a/src/ImageSharp/Processing/Transforms/AutoOrient.cs +++ b/src/ImageSharp/Processing/Transforms/AutoOrient.cs @@ -5,12 +5,9 @@ namespace ImageSharp { - using System; - using ImageSharp.PixelFormats; - using Processing; - using Processing.Processors; + using ImageSharp.Processing; /// /// Extension methods for the type. @@ -80,7 +77,7 @@ namespace ImageSharp return Orientation.Unknown; } - Orientation orientation = (Orientation)value.Value; + var orientation = (Orientation)value.Value; source.MetaData.ExifProfile.SetValue(ExifTag.Orientation, (ushort)Orientation.TopLeft); diff --git a/src/ImageSharp/Processing/Transforms/Flip.cs b/src/ImageSharp/Processing/Transforms/Flip.cs index 342b4dd46..1c8baebf1 100644 --- a/src/ImageSharp/Processing/Transforms/Flip.cs +++ b/src/ImageSharp/Processing/Transforms/Flip.cs @@ -9,7 +9,7 @@ namespace ImageSharp using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// diff --git a/src/ImageSharp/Processing/Transforms/Options/ResizeHelper.cs b/src/ImageSharp/Processing/Transforms/Options/ResizeHelper.cs index c87688266..712efec12 100644 --- a/src/ImageSharp/Processing/Transforms/Options/ResizeHelper.cs +++ b/src/ImageSharp/Processing/Transforms/Options/ResizeHelper.cs @@ -5,7 +5,6 @@ namespace ImageSharp.Processing { - using System; using System.Linq; using ImageSharp.PixelFormats; @@ -86,17 +85,17 @@ namespace ImageSharp.Processing if (options.CenterCoordinates.Any()) { - float center = -(ratio * sourceHeight) * options.CenterCoordinates.First(); - destinationY = (int)center + (height / 2); + float center = -(ratio * sourceHeight) * options.CenterCoordinates.ToArray()[1]; + destinationY = (int)MathF.Round(center + (height / 2F)); if (destinationY > 0) { destinationY = 0; } - if (destinationY < (int)(height - (sourceHeight * ratio))) + if (destinationY < (int)MathF.Round(height - (sourceHeight * ratio))) { - destinationY = (int)(height - (sourceHeight * ratio)); + destinationY = (int)MathF.Round(height - (sourceHeight * ratio)); } } else @@ -111,10 +110,10 @@ namespace ImageSharp.Processing case AnchorPosition.Bottom: case AnchorPosition.BottomLeft: case AnchorPosition.BottomRight: - destinationY = (int)(height - (sourceHeight * ratio)); + destinationY = (int)MathF.Round(height - (sourceHeight * ratio)); break; default: - destinationY = (int)((height - (sourceHeight * ratio)) / 2); + destinationY = (int)MathF.Round((height - (sourceHeight * ratio)) / 2F); break; } } @@ -127,17 +126,17 @@ namespace ImageSharp.Processing if (options.CenterCoordinates.Any()) { - float center = -(ratio * sourceWidth) * options.CenterCoordinates.ToArray()[1]; - destinationX = (int)center + (width / 2); + float center = -(ratio * sourceWidth) * options.CenterCoordinates.First(); + destinationX = (int)MathF.Round(center + (width / 2F)); if (destinationX > 0) { destinationX = 0; } - if (destinationX < (int)(width - (sourceWidth * ratio))) + if (destinationX < (int)MathF.Round(width - (sourceWidth * ratio))) { - destinationX = (int)(width - (sourceWidth * ratio)); + destinationX = (int)MathF.Round(width - (sourceWidth * ratio)); } } else @@ -152,10 +151,10 @@ namespace ImageSharp.Processing case AnchorPosition.Right: case AnchorPosition.TopRight: case AnchorPosition.BottomRight: - destinationX = (int)(width - (sourceWidth * ratio)); + destinationX = (int)MathF.Round(width - (sourceWidth * ratio)); break; default: - destinationX = (int)((width - (sourceWidth * ratio)) / 2); + destinationX = (int)MathF.Round((width - (sourceWidth * ratio)) / 2F); break; } } @@ -202,7 +201,7 @@ namespace ImageSharp.Processing if (percentHeight < percentWidth) { ratio = percentHeight; - destinationWidth = Convert.ToInt32(sourceWidth * percentHeight); + destinationWidth = (int)MathF.Round(sourceWidth * percentHeight); switch (options.Position) { @@ -214,17 +213,17 @@ namespace ImageSharp.Processing case AnchorPosition.Right: case AnchorPosition.TopRight: case AnchorPosition.BottomRight: - destinationX = (int)(width - (sourceWidth * ratio)); + destinationX = (int)MathF.Round(width - (sourceWidth * ratio)); break; default: - destinationX = Convert.ToInt32((width - (sourceWidth * ratio)) / 2); + destinationX = (int)MathF.Round((width - (sourceWidth * ratio)) / 2F); break; } } else { ratio = percentWidth; - destinationHeight = Convert.ToInt32(sourceHeight * percentWidth); + destinationHeight = (int)MathF.Round(sourceHeight * percentWidth); switch (options.Position) { @@ -236,10 +235,10 @@ namespace ImageSharp.Processing case AnchorPosition.Bottom: case AnchorPosition.BottomLeft: case AnchorPosition.BottomRight: - destinationY = (int)(height - (sourceHeight * ratio)); + destinationY = (int)MathF.Round(height - (sourceHeight * ratio)); break; default: - destinationY = (int)((height - (sourceHeight * ratio)) / 2); + destinationY = (int)MathF.Round((height - (sourceHeight * ratio)) / 2F); break; } } @@ -274,8 +273,8 @@ namespace ImageSharp.Processing float percentHeight = MathF.Abs(height / (float)sourceHeight); float percentWidth = MathF.Abs(width / (float)sourceWidth); - int boxPadHeight = height > 0 ? height : Convert.ToInt32(sourceHeight * percentWidth); - int boxPadWidth = width > 0 ? width : Convert.ToInt32(sourceWidth * percentHeight); + int boxPadHeight = height > 0 ? height : (int)MathF.Round(sourceHeight * percentWidth); + int boxPadWidth = width > 0 ? width : (int)MathF.Round(sourceWidth * percentHeight); // Only calculate if upscaling. if (sourceWidth < boxPadWidth && sourceHeight < boxPadHeight) @@ -356,17 +355,17 @@ namespace ImageSharp.Processing float percentWidth = MathF.Abs(width / (float)source.Width); // Integers must be cast to floats to get needed precision - float ratio = (float)options.Size.Height / options.Size.Width; - float sourceRatio = (float)source.Height / source.Width; + float ratio = options.Size.Height / (float)options.Size.Width; + float sourceRatio = source.Height / (float)source.Width; if (sourceRatio < ratio) { - destinationHeight = Convert.ToInt32(source.Height * percentWidth); + destinationHeight = (int)MathF.Round(source.Height * percentWidth); height = destinationHeight; } else { - destinationWidth = Convert.ToInt32(source.Width * percentHeight); + destinationWidth = (int)MathF.Round(source.Width * percentHeight); width = destinationWidth; } @@ -389,38 +388,54 @@ namespace ImageSharp.Processing { int width = options.Size.Width; int height = options.Size.Height; + int sourceWidth = source.Width; + int sourceHeight = source.Height; int destinationWidth; int destinationHeight; // Don't upscale - if (width > source.Width || height > source.Height) + if (width > sourceWidth || height > sourceHeight) { - options.Size = new Size(source.Width, source.Height); - return new Rectangle(0, 0, source.Width, source.Height); + options.Size = new Size(sourceWidth, sourceHeight); + return new Rectangle(0, 0, sourceWidth, sourceHeight); } - float sourceRatio = (float)source.Height / source.Width; + // Fractional variants for preserving aspect ratio. + float percentHeight = MathF.Abs(height / (float)sourceHeight); + float percentWidth = MathF.Abs(width / (float)sourceWidth); + + float sourceRatio = (float)sourceHeight / sourceWidth; // Find the shortest distance to go. - int widthDiff = source.Width - width; - int heightDiff = source.Height - height; + int widthDiff = sourceWidth - width; + int heightDiff = sourceHeight - height; if (widthDiff < heightDiff) { - destinationHeight = Convert.ToInt32(width * sourceRatio); + destinationHeight = (int)MathF.Round(width * sourceRatio); height = destinationHeight; destinationWidth = width; } else if (widthDiff > heightDiff) { - destinationWidth = Convert.ToInt32(height / sourceRatio); + destinationWidth = (int)MathF.Round(height / sourceRatio); destinationHeight = height; width = destinationWidth; } else { - destinationWidth = width; - destinationHeight = height; + if (height > width) + { + destinationWidth = width; + destinationHeight = (int)MathF.Round(sourceHeight * percentWidth); + height = destinationHeight; + } + else + { + destinationHeight = height; + destinationWidth = (int)MathF.Round(sourceWidth * percentHeight); + width = destinationWidth; + } } // Replace the size to match the rectangle. @@ -428,4 +443,4 @@ namespace ImageSharp.Processing return new Rectangle(0, 0, destinationWidth, destinationHeight); } } -} +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Transforms/Pad.cs b/src/ImageSharp/Processing/Transforms/Pad.cs index 42851e205..4bded0772 100644 --- a/src/ImageSharp/Processing/Transforms/Pad.cs +++ b/src/ImageSharp/Processing/Transforms/Pad.cs @@ -9,7 +9,7 @@ namespace ImageSharp using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// diff --git a/src/ImageSharp/Processing/Transforms/Resize.cs b/src/ImageSharp/Processing/Transforms/Resize.cs index 543b98297..3399ff0e3 100644 --- a/src/ImageSharp/Processing/Transforms/Resize.cs +++ b/src/ImageSharp/Processing/Transforms/Resize.cs @@ -5,11 +5,9 @@ namespace ImageSharp { - using System; - using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// @@ -31,12 +29,12 @@ namespace ImageSharp // Ensure size is populated across both dimensions. if (options.Size.Width == 0 && options.Size.Height > 0) { - options.Size = new Size(source.Width * options.Size.Height / source.Height, options.Size.Height); + options.Size = new Size((int)MathF.Round(source.Width * options.Size.Height / (float)source.Height), options.Size.Height); } if (options.Size.Height == 0 && options.Size.Width > 0) { - options.Size = new Size(options.Size.Width, source.Height * options.Size.Width / source.Width); + options.Size = new Size(options.Size.Width, (int)MathF.Round(source.Height * options.Size.Width / (float)source.Width)); } Rectangle targetRectangle = ResizeHelper.CalculateTargetLocationAndBounds(source, options); @@ -58,6 +56,21 @@ namespace ImageSharp return Resize(source, size.Width, size.Height, new BicubicResampler(), false); } + /// + /// Resizes an image to the given . + /// + /// The pixel format. + /// The image to resize. + /// The target image size. + /// Whether to compress and expand the image color-space to gamma correct the image during processing. + /// The + /// Passing zero for one of height or width will automatically preserve the aspect ratio of the original image + public static Image Resize(this Image source, Size size, bool compand) + where TPixel : struct, IPixel + { + return Resize(source, size.Width, size.Height, new BicubicResampler(), compand); + } + /// /// Resizes an image to the given width and height. /// @@ -140,26 +153,25 @@ namespace ImageSharp /// Whether to compress and expand the image color-space to gamma correct the image during processing. /// The /// Passing zero for one of height or width will automatically preserve the aspect ratio of the original image - public static Image Resize(this Image source, int width, int height, IResampler sampler, Rectangle sourceRectangle, Rectangle targetRectangle, bool compand = false) + public static Image Resize(this Image source, int width, int height, IResampler sampler, Rectangle sourceRectangle, Rectangle targetRectangle, bool compand) where TPixel : struct, IPixel { if (width == 0 && height > 0) { - width = source.Width * height / source.Height; + width = (int)MathF.Round(source.Width * height / (float)source.Height); targetRectangle.Width = width; } if (height == 0 && width > 0) { - height = source.Height * width / source.Width; + height = (int)MathF.Round(source.Height * width / (float)source.Width); targetRectangle.Height = height; } Guard.MustBeGreaterThan(width, 0, nameof(width)); Guard.MustBeGreaterThan(height, 0, nameof(height)); - ResizeProcessor processor = - new ResizeProcessor(sampler, width, height, targetRectangle) { Compand = compand }; + var processor = new ResizeProcessor(sampler, width, height, targetRectangle) { Compand = compand }; source.ApplyProcessor(processor, sourceRectangle); return source; diff --git a/src/ImageSharp/Processing/Transforms/Rotate.cs b/src/ImageSharp/Processing/Transforms/Rotate.cs index de9dbdc3b..af7c06a27 100644 --- a/src/ImageSharp/Processing/Transforms/Rotate.cs +++ b/src/ImageSharp/Processing/Transforms/Rotate.cs @@ -9,7 +9,7 @@ namespace ImageSharp using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; using Processing.Processors; /// diff --git a/src/ImageSharp/Processing/Transforms/RotateFlip.cs b/src/ImageSharp/Processing/Transforms/RotateFlip.cs index 460d004cb..805deb8d1 100644 --- a/src/ImageSharp/Processing/Transforms/RotateFlip.cs +++ b/src/ImageSharp/Processing/Transforms/RotateFlip.cs @@ -9,7 +9,7 @@ namespace ImageSharp using ImageSharp.PixelFormats; - using Processing; + using ImageSharp.Processing; /// /// Extension methods for the type. diff --git a/tests/ImageSharp.Benchmarks/Samplers/DetectEdges.cs b/tests/ImageSharp.Benchmarks/Samplers/DetectEdges.cs index d4920ff08..e77716ec8 100644 --- a/tests/ImageSharp.Benchmarks/Samplers/DetectEdges.cs +++ b/tests/ImageSharp.Benchmarks/Samplers/DetectEdges.cs @@ -9,7 +9,7 @@ namespace ImageSharp.Benchmarks using BenchmarkDotNet.Attributes; - using Processing; + using ImageSharp.Processing; using CoreImage = ImageSharp.Image; diff --git a/tests/ImageSharp.Sandbox46/Program.cs b/tests/ImageSharp.Sandbox46/Program.cs index 7ea459aae..b882de0cc 100644 --- a/tests/ImageSharp.Sandbox46/Program.cs +++ b/tests/ImageSharp.Sandbox46/Program.cs @@ -10,6 +10,7 @@ namespace ImageSharp.Sandbox46 using ImageSharp.Tests; using ImageSharp.Tests.Colors; + using ImageSharp.Tests.Processing.Transforms; using Xunit.Abstractions; diff --git a/tests/ImageSharp.Tests/Drawing/BlendedShapes.cs b/tests/ImageSharp.Tests/Drawing/BlendedShapes.cs index 6c742c2e0..23f0569e7 100644 --- a/tests/ImageSharp.Tests/Drawing/BlendedShapes.cs +++ b/tests/ImageSharp.Tests/Drawing/BlendedShapes.cs @@ -18,7 +18,7 @@ namespace ImageSharp.Tests.Drawing .Select(x=> new object[] { x }); [Theory] - [WithBlankImages(nameof(modes), 100, 100, PixelTypes.StandardImageClass)] + [WithBlankImages(nameof(modes), 100, 100, PixelTypes.Rgba32)] public void DrawBlendedValues(TestImageProvider provider, PixelBlenderMode mode) where TPixel : struct, IPixel { @@ -34,7 +34,7 @@ namespace ImageSharp.Tests.Drawing } [Theory] - [WithBlankImages(nameof(modes), 100, 100, PixelTypes.StandardImageClass)] + [WithBlankImages(nameof(modes), 100, 100, PixelTypes.Rgba32)] public void DrawBlendedValues_transparent(TestImageProvider provider, PixelBlenderMode mode) where TPixel : struct, IPixel { diff --git a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs index 030034a8f..42353a2aa 100644 --- a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs +++ b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs @@ -12,7 +12,7 @@ namespace ImageSharp.Tests public class DrawImageTest : FileTestBase { - private const PixelTypes PixelTypes = Tests.PixelTypes.StandardImageClass; + private const PixelTypes PixelTypes = Tests.PixelTypes.Rgba32; public static readonly string[] TestFiles = { TestImages.Jpeg.Baseline.Calliphora, diff --git a/tests/ImageSharp.Tests/Drawing/Paths/Extensions.cs b/tests/ImageSharp.Tests/Drawing/Paths/Extensions.cs index a18dd90bc..24f2a6bd8 100644 --- a/tests/ImageSharp.Tests/Drawing/Paths/Extensions.cs +++ b/tests/ImageSharp.Tests/Drawing/Paths/Extensions.cs @@ -5,7 +5,7 @@ namespace ImageSharp.Tests.Drawing.Paths using System.IO; using ImageSharp; using ImageSharp.Drawing.Brushes; - using Processing; + using ImageSharp.Processing; using System.Collections.Generic; using Xunit; using ImageSharp.Drawing; diff --git a/tests/ImageSharp.Tests/Drawing/Paths/ProcessorWatchingImage.cs b/tests/ImageSharp.Tests/Drawing/Paths/ProcessorWatchingImage.cs index c1d34a112..039216078 100644 --- a/tests/ImageSharp.Tests/Drawing/Paths/ProcessorWatchingImage.cs +++ b/tests/ImageSharp.Tests/Drawing/Paths/ProcessorWatchingImage.cs @@ -4,7 +4,7 @@ namespace ImageSharp.Tests.Drawing.Paths using System; using System.IO; using ImageSharp; - using Processing; + using ImageSharp.Processing; using System.Collections.Generic; using ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/Drawing/Paths/ShapePathTests.cs b/tests/ImageSharp.Tests/Drawing/Paths/ShapePathTests.cs index 78d49d35f..e791a2bfb 100644 --- a/tests/ImageSharp.Tests/Drawing/Paths/ShapePathTests.cs +++ b/tests/ImageSharp.Tests/Drawing/Paths/ShapePathTests.cs @@ -5,7 +5,7 @@ namespace ImageSharp.Tests.Drawing.Paths using System.IO; using ImageSharp; using ImageSharp.Drawing.Brushes; - using Processing; + using ImageSharp.Processing; using System.Collections.Generic; using Xunit; using ImageSharp.Drawing; diff --git a/tests/ImageSharp.Tests/Drawing/Paths/ShapeRegionTests.cs b/tests/ImageSharp.Tests/Drawing/Paths/ShapeRegionTests.cs index 6275ffd1c..7765436f7 100644 --- a/tests/ImageSharp.Tests/Drawing/Paths/ShapeRegionTests.cs +++ b/tests/ImageSharp.Tests/Drawing/Paths/ShapeRegionTests.cs @@ -5,7 +5,7 @@ namespace ImageSharp.Tests.Drawing.Paths using System.IO; using ImageSharp; using ImageSharp.Drawing.Brushes; - using Processing; + using ImageSharp.Processing; using System.Collections.Generic; using Xunit; using ImageSharp.Drawing; diff --git a/tests/ImageSharp.Tests/Drawing/Text/OutputText.cs b/tests/ImageSharp.Tests/Drawing/Text/OutputText.cs index bb9cd264e..21646b03f 100644 --- a/tests/ImageSharp.Tests/Drawing/Text/OutputText.cs +++ b/tests/ImageSharp.Tests/Drawing/Text/OutputText.cs @@ -5,7 +5,7 @@ namespace ImageSharp.Tests.Drawing.Text using System.IO; using ImageSharp; using ImageSharp.Drawing.Brushes; - using Processing; + using ImageSharp.Processing; using System.Collections.Generic; using Xunit; using ImageSharp.Drawing; diff --git a/tests/ImageSharp.Tests/FileTestBase.cs b/tests/ImageSharp.Tests/FileTestBase.cs index 12c7d5154..51a1562f5 100644 --- a/tests/ImageSharp.Tests/FileTestBase.cs +++ b/tests/ImageSharp.Tests/FileTestBase.cs @@ -12,6 +12,54 @@ namespace ImageSharp.Tests /// public abstract class FileTestBase : TestBase { + /// + /// A collection made up of one file for each image format + /// + public static IEnumerable DefaultFiles = + new[] + { + TestImages.Bmp.Car, + TestImages.Jpeg.Baseline.Calliphora, + TestImages.Png.Splash, + TestImages.Gif.Trans + }; + + /// + /// A collection of all the bmp test images + /// + public static IEnumerable AllBmpFiles = TestImages.Bmp.All; + + /// + /// A collection of all the jpeg test images + /// + public static IEnumerable AllJpegFiles = TestImages.Jpeg.All; + + /// + /// A collection of all the png test images + /// + public static IEnumerable AllPngFiles = TestImages.Png.All; + + /// + /// A collection of all the gif test images + /// + public static IEnumerable AllGifFiles = TestImages.Gif.All; + + /// + /// The standard pixel format enumeration + /// + public const PixelTypes DefaultPixelType = PixelTypes.Rgba32; + + public static class Extensions + { + public const string Bmp = "bmp"; + + public const string Jpeg = "jpg"; + + public const string Png = "png"; + + public const string Gif = "gif"; + } + /// /// The collection of image files to test against. /// diff --git a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs index b47df8395..ec1a8c465 100644 --- a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs +++ b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs @@ -13,22 +13,16 @@ namespace ImageSharp.Tests public class GeneralFormatTests : FileTestBase { - [Fact] - public void ResolutionShouldChange() + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ResolutionShouldChange(TestImageProvider provider) + where TPixel : struct, IPixel { - string path = this.CreateOutputDirectory("Resolution"); - - foreach (TestFile file in Files) + using (Image image = provider.GetImage()) { - using (Image image = file.CreateImage()) - { - using (FileStream output = File.OpenWrite($"{path}/{file.FileName}")) - { - image.MetaData.VerticalResolution = 150; - image.MetaData.HorizontalResolution = 150; - image.Save(output); - } - } + image.MetaData.VerticalResolution = 150; + image.MetaData.HorizontalResolution = 150; + image.DebugSave(provider, null, Extensions.Bmp); } } diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs index a5fc92901..89df2d086 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs @@ -14,7 +14,7 @@ namespace ImageSharp.Tests public class GifDecoderTests { - private const PixelTypes PixelTypes = Tests.PixelTypes.StandardImageClass | Tests.PixelTypes.RgbaVector | Tests.PixelTypes.Argb32; + private const PixelTypes PixelTypes = Tests.PixelTypes.Rgba32 | Tests.PixelTypes.RgbaVector | Tests.PixelTypes.Argb32; public static readonly string[] TestFiles = { TestImages.Gif.Giphy, TestImages.Gif.Rings, TestImages.Gif.Trans }; diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs index b0ffaaf85..70cc8e2ba 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs @@ -13,7 +13,7 @@ namespace ImageSharp.Tests public class GifEncoderTests { - private const PixelTypes PixelTypes = Tests.PixelTypes.StandardImageClass | Tests.PixelTypes.RgbaVector | Tests.PixelTypes.Argb32; + private const PixelTypes PixelTypes = Tests.PixelTypes.Rgba32 | Tests.PixelTypes.RgbaVector | Tests.PixelTypes.Argb32; [Theory] [WithTestPatternImages(100, 100, PixelTypes)] diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs index a6d6d31f3..446c5e96a 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs @@ -26,7 +26,7 @@ namespace ImageSharp.Tests public static string[] ProgressiveTestJpegs = TestImages.Jpeg.Progressive.All; [Theory] - [WithFileCollection(nameof(BaselineTestJpegs), PixelTypes.Rgba32 | PixelTypes.StandardImageClass | PixelTypes.Argb32)] + [WithFileCollection(nameof(BaselineTestJpegs), PixelTypes.Rgba32 | PixelTypes.Rgba32 | PixelTypes.Argb32)] public void OpenBaselineJpeg_SaveBmp(TestImageProvider provider) where TPixel : struct, IPixel { @@ -37,7 +37,7 @@ namespace ImageSharp.Tests } [Theory] - [WithFileCollection(nameof(ProgressiveTestJpegs), PixelTypes.Rgba32 | PixelTypes.StandardImageClass | PixelTypes.Argb32)] + [WithFileCollection(nameof(ProgressiveTestJpegs), PixelTypes.Rgba32 | PixelTypes.Rgba32 | PixelTypes.Argb32)] public void OpenProgressiveJpeg_SaveBmp(TestImageProvider provider) where TPixel : struct, IPixel { @@ -48,11 +48,11 @@ namespace ImageSharp.Tests } [Theory] - [WithSolidFilledImages(16, 16, 255, 0, 0, PixelTypes.StandardImageClass, JpegSubsample.Ratio420, 75)] - [WithSolidFilledImages(16, 16, 255, 0, 0, PixelTypes.StandardImageClass, JpegSubsample.Ratio420, 100)] - [WithSolidFilledImages(16, 16, 255, 0, 0, PixelTypes.StandardImageClass, JpegSubsample.Ratio444, 75)] - [WithSolidFilledImages(16, 16, 255, 0, 0, PixelTypes.StandardImageClass, JpegSubsample.Ratio444, 100)] - [WithSolidFilledImages(8, 8, 255, 0, 0, PixelTypes.StandardImageClass, JpegSubsample.Ratio444, 100)] + [WithSolidFilledImages(16, 16, 255, 0, 0, PixelTypes.Rgba32, JpegSubsample.Ratio420, 75)] + [WithSolidFilledImages(16, 16, 255, 0, 0, PixelTypes.Rgba32, JpegSubsample.Ratio420, 100)] + [WithSolidFilledImages(16, 16, 255, 0, 0, PixelTypes.Rgba32, JpegSubsample.Ratio444, 75)] + [WithSolidFilledImages(16, 16, 255, 0, 0, PixelTypes.Rgba32, JpegSubsample.Ratio444, 100)] + [WithSolidFilledImages(8, 8, 255, 0, 0, PixelTypes.Rgba32, JpegSubsample.Ratio444, 100)] public void DecodeGenerated_SaveBmp( TestImageProvider provider, JpegSubsample subsample, @@ -79,7 +79,7 @@ namespace ImageSharp.Tests } [Theory] - [WithSolidFilledImages(42, 88, 255, 0, 0, PixelTypes.StandardImageClass)] + [WithSolidFilledImages(42, 88, 255, 0, 0, PixelTypes.Rgba32)] public void DecodeGenerated_MetadataOnly( TestImageProvider provider) where TPixel : struct, IPixel diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs index 1b4f3ea78..ab81c69b4 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs @@ -28,10 +28,10 @@ namespace ImageSharp.Tests } [Theory] - [WithFile(TestImages.Jpeg.Baseline.Snake, PixelTypes.StandardImageClass, 75, JpegSubsample.Ratio420)] - [WithFile(TestImages.Jpeg.Baseline.Lake, PixelTypes.StandardImageClass, 75, JpegSubsample.Ratio420)] - [WithFile(TestImages.Jpeg.Baseline.Snake, PixelTypes.StandardImageClass, 75, JpegSubsample.Ratio444)] - [WithFile(TestImages.Jpeg.Baseline.Lake, PixelTypes.StandardImageClass, 75, JpegSubsample.Ratio444)] + [WithFile(TestImages.Jpeg.Baseline.Snake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio420)] + [WithFile(TestImages.Jpeg.Baseline.Lake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio420)] + [WithFile(TestImages.Jpeg.Baseline.Snake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio444)] + [WithFile(TestImages.Jpeg.Baseline.Lake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio444)] public void LoadResizeSave(TestImageProvider provider, int quality, JpegSubsample subsample) where TPixel : struct, IPixel { @@ -49,8 +49,8 @@ namespace ImageSharp.Tests } [Theory] - [WithFileCollection(nameof(AllBmpFiles), PixelTypes.Rgba32 | PixelTypes.StandardImageClass | PixelTypes.Argb32, JpegSubsample.Ratio420, 75)] - [WithFileCollection(nameof(AllBmpFiles), PixelTypes.Rgba32 | PixelTypes.StandardImageClass | PixelTypes.Argb32, JpegSubsample.Ratio444, 75)] + [WithFileCollection(nameof(AllBmpFiles), PixelTypes.Rgba32 | PixelTypes.Rgba32 | PixelTypes.Argb32, JpegSubsample.Ratio420, 75)] + [WithFileCollection(nameof(AllBmpFiles), PixelTypes.Rgba32 | PixelTypes.Rgba32 | PixelTypes.Argb32, JpegSubsample.Ratio444, 75)] public void OpenBmp_SaveJpeg(TestImageProvider provider, JpegSubsample subSample, int quality) where TPixel : struct, IPixel { diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs index b41826e2f..aac3f4611 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs @@ -72,7 +72,7 @@ namespace ImageSharp.Tests Image[] testImages = testFiles.Select( - tf => TestImageProvider.File(tf, pixelTypeOverride: PixelTypes.StandardImageClass).GetImage()) + tf => TestImageProvider.File(tf, pixelTypeOverride: PixelTypes.Rgba32).GetImage()) .ToArray(); using (MemoryStream ms = new MemoryStream()) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegUtilsTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegUtilsTests.cs index f242faf12..f681e1d8f 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegUtilsTests.cs @@ -40,7 +40,7 @@ namespace ImageSharp.Tests } [Theory] - [WithMemberFactory(nameof(CreateTestImage), PixelTypes.Rgba32| PixelTypes.StandardImageClass | PixelTypes.Argb32)] + [WithMemberFactory(nameof(CreateTestImage), PixelTypes.Rgba32| PixelTypes.Rgba32 | PixelTypes.Argb32)] public void CopyStretchedRGBTo_FromOrigo(TestImageProvider provider) where TPixel : struct, IPixel { @@ -62,7 +62,7 @@ namespace ImageSharp.Tests } [Theory] - [WithMemberFactory(nameof(CreateTestImage), PixelTypes.Rgba32| PixelTypes.StandardImageClass | PixelTypes.Argb32)] + [WithMemberFactory(nameof(CreateTestImage), PixelTypes.Rgba32| PixelTypes.Rgba32 | PixelTypes.Argb32)] public void CopyStretchedRGBTo_WithOffset(TestImageProvider provider) where TPixel : struct, IPixel { diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs index cf5c1cfa9..195a8dcb3 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs @@ -13,12 +13,12 @@ namespace ImageSharp.Tests public class PngDecoderTests { - private const PixelTypes PixelTypes = Tests.PixelTypes.StandardImageClass | Tests.PixelTypes.RgbaVector | Tests.PixelTypes.Argb32; + private const PixelTypes PixelTypes = Tests.PixelTypes.Rgba32 | Tests.PixelTypes.RgbaVector | Tests.PixelTypes.Argb32; public static readonly string[] TestFiles = { TestImages.Png.Splash, TestImages.Png.Indexed, TestImages.Png.Interlaced, TestImages.Png.FilterVar, - TestImages.Png.ChunkLength1, TestImages.Png.ChunkLength2 + TestImages.Png.Bad.ChunkLength1, TestImages.Png.Bad.ChunkLength2 }; [Theory] diff --git a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs index 195eaba10..02edf7688 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs @@ -18,7 +18,7 @@ namespace ImageSharp.Tests public class PngEncoderTests : FileTestBase { - private const PixelTypes PixelTypes = Tests.PixelTypes.StandardImageClass | Tests.PixelTypes.RgbaVector | Tests.PixelTypes.Argb32; + private const PixelTypes PixelTypes = Tests.PixelTypes.Rgba32 | Tests.PixelTypes.RgbaVector | Tests.PixelTypes.Argb32; [Theory] [WithTestPatternImages(100, 100, PixelTypes, PngColorType.RgbWithAlpha)] diff --git a/tests/ImageSharp.Tests/Formats/Png/PngSmokeTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngSmokeTests.cs index 22bb0b244..90f994f36 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngSmokeTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngSmokeTests.cs @@ -20,7 +20,7 @@ namespace ImageSharp.Tests.Formats.Png public class PngSmokeTests { [Theory] - [WithTestPatternImages(300, 300, PixelTypes.StandardImageClass)] + [WithTestPatternImages(300, 300, PixelTypes.Rgba32)] public void GeneralTest(TestImageProvider provider) where TPixel : struct, IPixel { @@ -41,7 +41,7 @@ namespace ImageSharp.Tests.Formats.Png } [Theory] - [WithTestPatternImages(100, 100, PixelTypes.StandardImageClass)] + [WithTestPatternImages(100, 100, PixelTypes.Rgba32)] public void CanSaveIndexedPng(TestImageProvider provider) where TPixel : struct, IPixel { @@ -105,7 +105,7 @@ namespace ImageSharp.Tests.Formats.Png //} [Theory] - [WithTestPatternImages(300, 300, PixelTypes.StandardImageClass)] + [WithTestPatternImages(300, 300, PixelTypes.Rgba32)] public void Resize(TestImageProvider provider) where TPixel : struct, IPixel { diff --git a/tests/ImageSharp.Tests/ImageComparer.cs b/tests/ImageSharp.Tests/ImageComparer.cs index d339dc83d..9a30cc363 100644 --- a/tests/ImageSharp.Tests/ImageComparer.cs +++ b/tests/ImageSharp.Tests/ImageComparer.cs @@ -1,4 +1,9 @@ -namespace ImageSharp.Tests +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests { using System; using ImageSharp; @@ -12,9 +17,41 @@ /// public static class ImageComparer { - const int DefaultScalingFactor = 32; // this is means the images get scaled into a 32x32 image to sample pixels - const int DefaultSegmentThreshold = 3; // the greyscale difference between 2 segements my be > 3 before it influances the overall difference - const float DefaultImageThreshold = 0.000f; // after segment threasholds the images must have no differences + const int DefaultScalingFactor = 32; // This is means the images get scaled into a 32x32 image to sample pixels + const int DefaultSegmentThreshold = 3; // The greyscale difference between 2 segements my be > 3 before it influences the overall difference + const float DefaultImageThreshold = 0.000F; // After segment thresholds the images must have no differences + + /// + /// Fills the bounded area with a solid color and does a visual comparison between 2 images asserting the difference outwith + /// that area is less then a configurable threshold. + /// + /// The color of the expected image + /// The color type fo the the actual image + /// The expected image + /// The actual image + /// The bounds within the image has been altered + /// + /// The threshold for the percentage difference where the images are asumed to be the same. + /// The default/undefined value is + /// + /// + /// The threshold of the individual segments before it acumulates towards the overall difference. + /// The default undefined value is + /// + /// + /// This is a sampling factor we sample a grid of average pixels width by high + /// The default undefined value is + /// + public static void EnsureProcessorChangesAreConstrained(Image expected, Image actual, Rectangle bounds, float imageTheshold = DefaultImageThreshold, byte segmentThreshold = DefaultSegmentThreshold, int scalingFactor = DefaultScalingFactor) + where TPixelA : struct, IPixel + where TPixelB : struct, IPixel + { + // Draw identical shapes over the bounded and compare to ensure changes are constrained. + expected.Fill(NamedColors.HotPink, bounds); + actual.Fill(NamedColors.HotPink, bounds); + + CheckSimilarity(expected, actual, imageTheshold, segmentThreshold, scalingFactor); + } /// /// Does a visual comparison between 2 images and then asserts the difference is less then a configurable threshold @@ -25,15 +62,15 @@ /// The actual image /// /// The threshold for the percentage difference where the images are asumed to be the same. - /// The default/undefined value is + /// The default/undefined value is /// /// - /// The threashold of the individual segments before it acumulates towards the overall difference. - /// The default undefined value is + /// The threshold of the individual segments before it acumulates towards the overall difference. + /// The default undefined value is /// /// /// This is a sampling factor we sample a grid of average pixels width by high - /// The default undefined value is + /// The default undefined value is /// public static void CheckSimilarity(Image expected, Image actual, float imageTheshold = DefaultImageThreshold, byte segmentThreshold = DefaultSegmentThreshold, int scalingFactor = DefaultScalingFactor) where TPixelA : struct, IPixel @@ -52,14 +89,14 @@ /// The source image /// The target image /// - /// The threashold of the individual segments before it acumulates towards the overall difference. - /// The default undefined value is + /// The threshold of the individual segments before it acumulates towards the overall difference. + /// The default undefined value is /// /// /// This is a sampling factor we sample a grid of average pixels width by high /// The default undefined value is /// - /// Returns a number from 0 - 1 which represents the diference focter between the images. + /// Returns a number from 0 - 1 which represents the difference focter between the images. public static float PercentageDifference(this Image source, Image target, byte segmentThreshold = DefaultSegmentThreshold, int scalingFactor = DefaultScalingFactor) where TPixelA : struct, IPixel where TPixelB : struct, IPixel @@ -74,14 +111,14 @@ if (b > segmentThreshold) { diffPixels++; } } - return (float)diffPixels / (float)(scalingFactor * scalingFactor); + return diffPixels / (float)(scalingFactor * scalingFactor); } private static Fast2DArray GetDifferences(Image source, Image target, int scalingFactor) where TPixelA : struct, IPixel where TPixelB : struct, IPixel { - Fast2DArray differences = new Fast2DArray(scalingFactor, scalingFactor); + var differences = new Fast2DArray(scalingFactor, scalingFactor); Fast2DArray firstGray = source.GetGrayScaleValues(scalingFactor); Fast2DArray secondGray = target.GetGrayScaleValues(scalingFactor); @@ -89,7 +126,7 @@ { for (int x = 0; x < scalingFactor; x++) { - var diff = firstGray[x, y] - secondGray[x, y]; + int diff = firstGray[x, y] - secondGray[x, y]; differences[x, y] = (byte)Math.Abs(diff); } } @@ -100,18 +137,18 @@ private static Fast2DArray GetGrayScaleValues(this Image source, int scalingFactor) where TPixelA : struct, IPixel { - byte[] buffer = new byte[4]; + byte[] buffer = new byte[3]; using (Image img = new Image(source).Resize(scalingFactor, scalingFactor).Grayscale()) { using (PixelAccessor pixels = img.Lock()) { - Fast2DArray grayScale = new Fast2DArray(scalingFactor, scalingFactor); + var grayScale = new Fast2DArray(scalingFactor, scalingFactor); for (int y = 0; y < scalingFactor; y++) { for (int x = 0; x < scalingFactor; x++) { pixels[x, y].ToXyzBytes(buffer, 0); - grayScale[x, y] = buffer[1]; + grayScale[x, y] = buffer[0]; } } diff --git a/tests/ImageSharp.Tests/Processing/Binarization/BinaryThresholdTest.cs b/tests/ImageSharp.Tests/Processing/Binarization/BinaryThresholdTest.cs new file mode 100644 index 000000000..e792de22f --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Binarization/BinaryThresholdTest.cs @@ -0,0 +1,51 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Binarization +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class BinaryThresholdTest : FileTestBase + { + public static readonly TheoryData BinaryThresholdValues + = new TheoryData + { + .25F, + .75F + }; + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(BinaryThresholdValues), DefaultPixelType)] + public void ImageShouldApplyBinaryThresholdFilter(TestImageProvider provider, float value) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.BinaryThreshold(value) + .DebugSave(provider, value, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(BinaryThresholdValues), DefaultPixelType)] + public void ImageShouldApplyBinaryThresholdInBox(TestImageProvider provider, float value) + where TPixel : struct, IPixel + { + + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.BinaryThreshold(value, bounds) + .DebugSave(provider, value, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Binarization/DitherTest.cs b/tests/ImageSharp.Tests/Processing/Binarization/DitherTest.cs new file mode 100644 index 000000000..2948c1046 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Binarization/DitherTest.cs @@ -0,0 +1,92 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Binarization +{ + using ImageSharp.Dithering; + using ImageSharp.Dithering.Ordered; + using ImageSharp.PixelFormats; + + using Xunit; + + public class DitherTest : FileTestBase + { + public static readonly TheoryData Ditherers = new TheoryData + { + { "Ordered", new Ordered() }, + { "Bayer", new Bayer() } + }; + + public static readonly TheoryData ErrorDiffusers = new TheoryData + { + { "Atkinson", new Atkinson() }, + { "Burks", new Burks() }, + { "FloydSteinberg", new FloydSteinberg() }, + { "JarvisJudiceNinke", new JarvisJudiceNinke() }, + { "Sierra2", new Sierra2() }, + { "Sierra3", new Sierra3() }, + { "SierraLite", new SierraLite() }, + { "Stucki", new Stucki() }, + }; + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(Ditherers), DefaultPixelType)] + public void ImageShouldApplyDitherFilter(TestImageProvider provider, string name, IOrderedDither ditherer) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Dither(ditherer) + .DebugSave(provider, name, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(Ditherers), DefaultPixelType)] + public void ImageShouldApplyDitherFilterInBox(TestImageProvider provider, string name, IOrderedDither ditherer) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.Dither(ditherer, bounds) + .DebugSave(provider, name, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(ErrorDiffusers), DefaultPixelType)] + public void ImageShouldApplyDiffusionFilter(TestImageProvider provider, string name, IErrorDiffuser diffuser) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Dither(diffuser, .5F) + .DebugSave(provider, name, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(ErrorDiffusers), DefaultPixelType)] + public void ImageShouldApplyDiffusionFilterInBox(TestImageProvider provider, string name, IErrorDiffuser diffuser) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.Dither(diffuser,.5F, bounds) + .DebugSave(provider, name, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/ColorMatrix/BlackWhiteTest.cs b/tests/ImageSharp.Tests/Processing/ColorMatrix/BlackWhiteTest.cs new file mode 100644 index 000000000..d825b4993 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/ColorMatrix/BlackWhiteTest.cs @@ -0,0 +1,43 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.ColorMatrix +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class BlackWhiteTest : FileTestBase + { + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyBlackWhiteFilter(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.BlackWhite() + .DebugSave(provider, null, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyBlackWhiteFilterInBox(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.BlackWhite(bounds) + .DebugSave(provider, null, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/ColorMatrix/ColorBlindnessTest.cs b/tests/ImageSharp.Tests/Processing/ColorMatrix/ColorBlindnessTest.cs new file mode 100644 index 000000000..b56ec3471 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/ColorMatrix/ColorBlindnessTest.cs @@ -0,0 +1,57 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.ColorMatrix +{ + using ImageSharp.PixelFormats; + using ImageSharp.Processing; + + using Xunit; + + public class ColorBlindnessTest : FileTestBase + { + public static readonly TheoryData ColorBlindnessFilters + = new TheoryData + { + ColorBlindness.Achromatomaly, + ColorBlindness.Achromatopsia, + ColorBlindness.Deuteranomaly, + ColorBlindness.Deuteranopia, + ColorBlindness.Protanomaly, + ColorBlindness.Protanopia, + ColorBlindness.Tritanomaly, + ColorBlindness.Tritanopia + }; + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(ColorBlindnessFilters), DefaultPixelType)] + public void ImageShouldApplyColorBlindnessFilter(TestImageProvider provider, ColorBlindness colorBlindness) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.ColorBlindness(colorBlindness) + .DebugSave(provider, colorBlindness.ToString(), Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(ColorBlindnessFilters), DefaultPixelType)] + public void ImageShouldApplyColorBlindnessFilterInBox(TestImageProvider provider, ColorBlindness colorBlindness) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.ColorBlindness(colorBlindness, bounds) + .DebugSave(provider, colorBlindness.ToString(), Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/GrayscaleTest.cs b/tests/ImageSharp.Tests/Processing/ColorMatrix/GrayscaleTest.cs similarity index 61% rename from tests/ImageSharp.Tests/Processors/Filters/GrayscaleTest.cs rename to tests/ImageSharp.Tests/Processing/ColorMatrix/GrayscaleTest.cs index 2e82191ec..89a388e4d 100644 --- a/tests/ImageSharp.Tests/Processors/Filters/GrayscaleTest.cs +++ b/tests/ImageSharp.Tests/Processing/ColorMatrix/GrayscaleTest.cs @@ -3,21 +3,27 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageSharp.Tests +namespace ImageSharp.Tests.Processing.ColorMatrix { - using Xunit; + using ImageSharp.PixelFormats; using ImageSharp.Processing; - using ImageSharp.PixelFormats; + using Xunit; public class GrayscaleTest : FileTestBase { + public static readonly TheoryData GrayscaleModeTypes + = new TheoryData + { + GrayscaleMode.Bt601, + GrayscaleMode.Bt709 + }; + /// /// Use test patterns over loaded images to save decode time. /// [Theory] - [WithTestPatternImages(50, 50, PixelTypes.StandardImageClass, GrayscaleMode.Bt709)] - [WithTestPatternImages(50, 50, PixelTypes.StandardImageClass, GrayscaleMode.Bt601)] + [WithTestPatternImages(nameof(GrayscaleModeTypes), 50, 50, DefaultPixelType)] public void ImageShouldApplyGrayscaleFilterAll(TestImageProvider provider, GrayscaleMode value) where TPixel : struct, IPixel { @@ -37,22 +43,18 @@ namespace ImageSharp.Tests } [Theory] - [WithTestPatternImages(50, 50, PixelTypes.StandardImageClass, GrayscaleMode.Bt709)] - [WithTestPatternImages(50, 50, PixelTypes.StandardImageClass, GrayscaleMode.Bt601)] + [WithTestPatternImages(nameof(GrayscaleModeTypes), 50, 50, DefaultPixelType)] public void ImageShouldApplyGrayscaleFilterInBox(TestImageProvider provider, GrayscaleMode value) where TPixel : struct, IPixel { using (Image source = provider.GetImage()) - using (Image image = new Image(source)) + using (var image = new Image(source)) { - Rectangle rect = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2); - image.Grayscale(rect, value) + var bounds = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2); + image.Grayscale(value, bounds) .DebugSave(provider, value.ToString()); - // Let's draw identical shapes over the greyed areas and ensure that it didn't change the outer area - image.Fill(NamedColors.HotPink, rect); - source.Fill(NamedColors.HotPink, rect); - ImageComparer.CheckSimilarity(image, source); + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); } } } diff --git a/tests/ImageSharp.Tests/Processing/ColorMatrix/HueTest.cs b/tests/ImageSharp.Tests/Processing/ColorMatrix/HueTest.cs new file mode 100644 index 000000000..b71905374 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/ColorMatrix/HueTest.cs @@ -0,0 +1,50 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.ColorMatrix +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class HueTest : FileTestBase + { + public static readonly TheoryData HueValues + = new TheoryData + { + 180, + -180 + }; + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(HueValues), DefaultPixelType)] + public void ImageShouldApplyHueFilter(TestImageProvider provider, int value) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Hue(value) + .DebugSave(provider, value, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(HueValues), DefaultPixelType)] + public void ImageShouldApplyHueFilterInBox(TestImageProvider provider, int value) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.Hue(value, bounds) + .DebugSave(provider, value, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/ColorMatrix/KodachromeTest.cs b/tests/ImageSharp.Tests/Processing/ColorMatrix/KodachromeTest.cs new file mode 100644 index 000000000..3a5d4f0d3 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/ColorMatrix/KodachromeTest.cs @@ -0,0 +1,43 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.ColorMatrix +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class KodachromeTest : FileTestBase + { + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyKodachromeFilter(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Kodachrome() + .DebugSave(provider, null, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyKodachromeFilterInBox(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.Kodachrome(bounds) + .DebugSave(provider, null, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/ColorMatrix/LomographTest.cs b/tests/ImageSharp.Tests/Processing/ColorMatrix/LomographTest.cs new file mode 100644 index 000000000..bfa37eef4 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/ColorMatrix/LomographTest.cs @@ -0,0 +1,45 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests +{ + using System.IO; + + using ImageSharp.PixelFormats; + + using Xunit; + + public class LomographTest : FileTestBase + { + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyLomographFilter(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Lomograph() + .DebugSave(provider, null, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyLomographFilterInBox(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.Lomograph(bounds) + .DebugSave(provider, null, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/ColorMatrix/PolaroidTest.cs b/tests/ImageSharp.Tests/Processing/ColorMatrix/PolaroidTest.cs new file mode 100644 index 000000000..2bf1c3698 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/ColorMatrix/PolaroidTest.cs @@ -0,0 +1,43 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.ColorMatrix +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class PolaroidTest : FileTestBase + { + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyPolaroidFilter(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Polaroid() + .DebugSave(provider, null, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyPolaroidFilterInBox(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.Polaroid(bounds) + .DebugSave(provider, null, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/ColorMatrix/SaturationTest.cs b/tests/ImageSharp.Tests/Processing/ColorMatrix/SaturationTest.cs new file mode 100644 index 000000000..9212c09e8 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/ColorMatrix/SaturationTest.cs @@ -0,0 +1,50 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.ColorMatrix +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class SaturationTest : FileTestBase + { + public static readonly TheoryData SaturationValues + = new TheoryData + { + 50 , + -50 , + }; + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(SaturationValues), DefaultPixelType)] + public void ImageShouldApplySaturationFilter(TestImageProvider provider, int value) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Saturation(value) + .DebugSave(provider, value, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(SaturationValues), DefaultPixelType)] + public void ImageShouldApplySaturationFilterInBox(TestImageProvider provider, int value) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.Saturation(value, bounds) + .DebugSave(provider, value, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/ColorMatrix/SepiaTest.cs b/tests/ImageSharp.Tests/Processing/ColorMatrix/SepiaTest.cs new file mode 100644 index 000000000..de536050b --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/ColorMatrix/SepiaTest.cs @@ -0,0 +1,43 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.ColorMatrix +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class SepiaTest : FileTestBase + { + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplySepiaFilter(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Sepia() + .DebugSave(provider, null, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplySepiaFilterInBox(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.Sepia(bounds) + .DebugSave(provider, null, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Convolution/BoxBlurTest.cs b/tests/ImageSharp.Tests/Processing/Convolution/BoxBlurTest.cs new file mode 100644 index 000000000..b5ee876de --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Convolution/BoxBlurTest.cs @@ -0,0 +1,50 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Convolution +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class BoxBlurTest : FileTestBase + { + public static readonly TheoryData BoxBlurValues + = new TheoryData + { + 3, + 5 + }; + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(BoxBlurValues), DefaultPixelType)] + public void ImageShouldApplyBoxBlurFilter(TestImageProvider provider, int value) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.BoxBlur(value) + .DebugSave(provider, value, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(BoxBlurValues), DefaultPixelType)] + public void ImageShouldApplyBoxBlurFilterInBox(TestImageProvider provider, int value) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.BoxBlur(value, bounds) + .DebugSave(provider, value, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Convolution/DetectEdgesTest.cs b/tests/ImageSharp.Tests/Processing/Convolution/DetectEdgesTest.cs new file mode 100644 index 000000000..220c0f466 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Convolution/DetectEdgesTest.cs @@ -0,0 +1,59 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Convolution +{ + using ImageSharp.PixelFormats; + using ImageSharp.Processing; + + using Xunit; + + public class DetectEdgesTest : FileTestBase + { + public static readonly TheoryData DetectEdgesFilters + = new TheoryData + { + EdgeDetection.Kayyali, + EdgeDetection.Kirsch, + EdgeDetection.Lapacian3X3, + EdgeDetection.Lapacian5X5, + EdgeDetection.LaplacianOfGaussian, + EdgeDetection.Prewitt, + EdgeDetection.RobertsCross, + EdgeDetection.Robinson, + EdgeDetection.Scharr, + EdgeDetection.Sobel + }; + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(DetectEdgesFilters), DefaultPixelType)] + public void ImageShouldApplyDetectEdgesFilter(TestImageProvider provider, EdgeDetection detector) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.DetectEdges(detector) + .DebugSave(provider, detector.ToString(), Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(DetectEdgesFilters), DefaultPixelType)] + public void ImageShouldApplyDetectEdgesFilterInBox(TestImageProvider provider, EdgeDetection detector) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.DetectEdges(detector, bounds) + .DebugSave(provider, detector.ToString(), Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/GaussianBlurTest.cs b/tests/ImageSharp.Tests/Processing/Convolution/GaussianBlurTest.cs similarity index 50% rename from tests/ImageSharp.Tests/Processors/Filters/GaussianBlurTest.cs rename to tests/ImageSharp.Tests/Processing/Convolution/GaussianBlurTest.cs index 4b2ac8b7c..dbaed9290 100644 --- a/tests/ImageSharp.Tests/Processors/Filters/GaussianBlurTest.cs +++ b/tests/ImageSharp.Tests/Processing/Convolution/GaussianBlurTest.cs @@ -3,49 +3,47 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageSharp.Tests +namespace ImageSharp.Tests.Processing.Convolution { - using System.IO; using ImageSharp.PixelFormats; + using Xunit; - public class GaussianBlurTest + public class GaussianBlurTest : FileTestBase { public static readonly TheoryData GaussianBlurValues = new TheoryData { - 3 , - 5 , + 3, + 5 }; [Theory] - [WithTestPatternImages(nameof(GaussianBlurValues), 320, 240, PixelTypes.StandardImageClass)] + [WithFileCollection(nameof(DefaultFiles), nameof(GaussianBlurValues), DefaultPixelType)] public void ImageShouldApplyGaussianBlurFilter(TestImageProvider provider, int value) where TPixel : struct, IPixel { using (Image image = provider.GetImage()) { image.GaussianBlur(value) - .DebugSave(provider, value.ToString()); + .DebugSave(provider, value, Extensions.Bmp); } } [Theory] - [WithTestPatternImages(nameof(GaussianBlurValues), 320, 240, PixelTypes.StandardImageClass)] + [WithFileCollection(nameof(DefaultFiles), nameof(GaussianBlurValues), DefaultPixelType)] public void ImageShouldApplyGaussianBlurFilterInBox(TestImageProvider provider, int value) where TPixel : struct, IPixel { using (Image source = provider.GetImage()) - using (Image image = new Image(source)) + using (var image = new Image(source)) { - Rectangle rect = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2); - image.GaussianBlur(value, rect) - .DebugSave(provider, value.ToString()); + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.GaussianBlur(value, bounds) + .DebugSave(provider, value, Extensions.Bmp); - // lets draw identical shapes over the blured areas and ensure that it didn't change the outer area - image.Fill(NamedColors.HotPink, rect); - source.Fill(NamedColors.HotPink, rect); - ImageComparer.CheckSimilarity(image, source); + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); } } } diff --git a/tests/ImageSharp.Tests/Processors/Filters/GaussianSharpenTest.cs b/tests/ImageSharp.Tests/Processing/Convolution/GaussianSharpenTest.cs similarity index 50% rename from tests/ImageSharp.Tests/Processors/Filters/GaussianSharpenTest.cs rename to tests/ImageSharp.Tests/Processing/Convolution/GaussianSharpenTest.cs index 1fa1ae15c..44296d975 100644 --- a/tests/ImageSharp.Tests/Processors/Filters/GaussianSharpenTest.cs +++ b/tests/ImageSharp.Tests/Processing/Convolution/GaussianSharpenTest.cs @@ -3,10 +3,10 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageSharp.Tests +namespace ImageSharp.Tests.Processing.Convolution { - using System.IO; using ImageSharp.PixelFormats; + using Xunit; public class GaussianSharpenTest : FileTestBase @@ -14,38 +14,36 @@ namespace ImageSharp.Tests public static readonly TheoryData GaussianSharpenValues = new TheoryData { - 3 , - 5 , + 3, + 5 }; [Theory] - [WithTestPatternImages(nameof(GaussianSharpenValues), 320, 240, PixelTypes.StandardImageClass)] + [WithFileCollection(nameof(DefaultFiles), nameof(GaussianSharpenValues), DefaultPixelType)] public void ImageShouldApplyGaussianSharpenFilter(TestImageProvider provider, int value) where TPixel : struct, IPixel { using (Image image = provider.GetImage()) { image.GaussianSharpen(value) - .DebugSave(provider, value.ToString()); + .DebugSave(provider, value, Extensions.Bmp); } } [Theory] - [WithTestPatternImages(nameof(GaussianSharpenValues), 320, 240, PixelTypes.StandardImageClass)] + [WithFileCollection(nameof(DefaultFiles), nameof(GaussianSharpenValues), DefaultPixelType)] public void ImageShouldApplyGaussianSharpenFilterInBox(TestImageProvider provider, int value) - where TPixel : struct, IPixel + where TPixel : struct, IPixel { using (Image source = provider.GetImage()) - using (Image image = new Image(source)) + using (var image = new Image(source)) { - Rectangle rect = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2); - image.GaussianSharpen(value, rect) - .DebugSave(provider, value.ToString()); + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.GaussianSharpen(value, bounds) + .DebugSave(provider, value, Extensions.Bmp); - // lets draw identical shapes over the Sharpened areas and ensure that it didn't change the outer area - image.Fill(NamedColors.HotPink, rect); - source.Fill(NamedColors.HotPink, rect); - ImageComparer.CheckSimilarity(image, source); + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); } } } diff --git a/tests/ImageSharp.Tests/Processing/Effects/AlphaTest.cs b/tests/ImageSharp.Tests/Processing/Effects/AlphaTest.cs new file mode 100644 index 000000000..63366dc1d --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Effects/AlphaTest.cs @@ -0,0 +1,50 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Effects +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class AlphaTest : FileTestBase + { + public static readonly TheoryData AlphaValues + = new TheoryData + { + 20/100F, + 80/100F + }; + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(AlphaValues), DefaultPixelType)] + public void ImageShouldApplyAlphaFilter(TestImageProvider provider, float value) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Alpha(value) + .DebugSave(provider, value, Extensions.Png); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(AlphaValues), DefaultPixelType)] + public void ImageShouldApplyAlphaFilterInBox(TestImageProvider provider, float value) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.Alpha(value, bounds) + .DebugSave(provider, value, Extensions.Png); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Effects/BackgroundColorTest.cs b/tests/ImageSharp.Tests/Processing/Effects/BackgroundColorTest.cs new file mode 100644 index 000000000..c3fda4cd4 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Effects/BackgroundColorTest.cs @@ -0,0 +1,43 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Effects +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class BackgroundColorTest : FileTestBase + { + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyBackgroundColorFilter(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.BackgroundColor(NamedColors.HotPink) + .DebugSave(provider, null, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyBackgroundColorFilterInBox(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.BackgroundColor(NamedColors.HotPink, bounds) + .DebugSave(provider, null, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Effects/BrightnessTest.cs b/tests/ImageSharp.Tests/Processing/Effects/BrightnessTest.cs new file mode 100644 index 000000000..4c0217fed --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Effects/BrightnessTest.cs @@ -0,0 +1,50 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Effects +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class BrightnessTest : FileTestBase + { + public static readonly TheoryData BrightnessValues + = new TheoryData + { + 50, + -50 + }; + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(BrightnessValues), DefaultPixelType)] + public void ImageShouldApplyBrightnessFilter(TestImageProvider provider, int value) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Brightness(value) + .DebugSave(provider, value, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(BrightnessValues), DefaultPixelType)] + public void ImageShouldApplyBrightnessFilterInBox(TestImageProvider provider, int value) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.Brightness(value, bounds) + .DebugSave(provider, value, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); ; + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Effects/ContrastTest.cs b/tests/ImageSharp.Tests/Processing/Effects/ContrastTest.cs new file mode 100644 index 000000000..ac217e9f6 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Effects/ContrastTest.cs @@ -0,0 +1,50 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Effects +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class ContrastTest : FileTestBase + { + public static readonly TheoryData ContrastValues + = new TheoryData + { + 50, + -50 + }; + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(ContrastValues), DefaultPixelType)] + public void ImageShouldApplyContrastFilter(TestImageProvider provider, int value) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Contrast(value) + .DebugSave(provider, value, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(ContrastValues), DefaultPixelType)] + public void ImageShouldApplyContrastFilterInBox(TestImageProvider provider, int value) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.Contrast(value, bounds) + .DebugSave(provider, value, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Effects/InvertTest.cs b/tests/ImageSharp.Tests/Processing/Effects/InvertTest.cs new file mode 100644 index 000000000..80e345092 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Effects/InvertTest.cs @@ -0,0 +1,43 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Effects +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class InvertTest : FileTestBase + { + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyInvertFilter(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Invert() + .DebugSave(provider, null, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyInvertFilterInBox(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.Invert(bounds) + .DebugSave(provider, null, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Effects/OilPaintTest.cs b/tests/ImageSharp.Tests/Processing/Effects/OilPaintTest.cs new file mode 100644 index 000000000..7d02ace3d --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Effects/OilPaintTest.cs @@ -0,0 +1,50 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class OilPaintTest : FileTestBase + { + public static readonly TheoryData OilPaintValues + = new TheoryData + { + { 15, 10 }, + { 6, 5 } + }; + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(OilPaintValues), DefaultPixelType)] + public void ImageShouldApplyOilPaintFilter(TestImageProvider provider, int levels, int brushSize) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.OilPaint(levels, brushSize) + .DebugSave(provider, string.Join("-", levels, brushSize), Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(OilPaintValues), DefaultPixelType)] + public void ImageShouldApplyOilPaintFilterInBox(TestImageProvider provider, int levels, int brushSize) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.OilPaint(levels, brushSize, bounds) + .DebugSave(provider, string.Join("-", levels, brushSize), Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds, 0.001F); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Effects/PixelateTest.cs b/tests/ImageSharp.Tests/Processing/Effects/PixelateTest.cs new file mode 100644 index 000000000..740b78c55 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Effects/PixelateTest.cs @@ -0,0 +1,84 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Effects +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class PixelateTest : FileTestBase + { + public static readonly TheoryData PixelateValues + = new TheoryData + { + 4 , + 8 + }; + + [Theory] + [WithTestPatternImages(nameof(PixelateValues), 320, 240, PixelTypes.Rgba32)] + public void ImageShouldApplyPixelateFilter(TestImageProvider provider, int value) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Pixelate(value) + .DebugSave(provider, value, Extensions.Bmp); + + // Test the neigbouring pixels + for (int y = 0; y < image.Height; y += value) + { + for (int x = 0; x < image.Width; x += value) + { + TPixel source = image[x, y]; + for (int pixY = y; pixY < y + value && pixY < image.Height; pixY++) + { + for (int pixX = x; pixX < x + value && pixX < image.Width; pixX++) + { + Assert.Equal(source, image[pixX, pixY]); + } + } + } + } + } + } + + [Theory] + [WithTestPatternImages(nameof(PixelateValues), 320, 240, PixelTypes.Rgba32)] + public void ImageShouldApplyPixelateFilterInBox(TestImageProvider provider, int value) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2); + + image.Pixelate(value, bounds) + .DebugSave(provider, value, Extensions.Bmp); + + for (int y = 0; y < image.Height; y++) + { + for (int x = 0; x < image.Width; x++) + { + int tx = x; + int ty = y; + TPixel sourceColor = source[tx, ty]; + if (bounds.Contains(tx, ty)) + { + int sourceX = tx - ((tx - bounds.Left) % value) + (value / 2); + int sourceY = ty - ((ty - bounds.Top) % value) + (value / 2); + + sourceColor = image[sourceX, sourceY]; + } + Assert.Equal(sourceColor, image[tx, ty]); + } + } + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Overlays/GlowTest.cs b/tests/ImageSharp.Tests/Processing/Overlays/GlowTest.cs new file mode 100644 index 000000000..a233e204c --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Overlays/GlowTest.cs @@ -0,0 +1,67 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Overlays +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class GlowTest : FileTestBase + { + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyGlowFilter(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Glow() + .DebugSave(provider, null, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyGlowFilterColor(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Glow(NamedColors.Orange) + .DebugSave(provider, null, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyGlowFilterRadius(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Glow(image.Width / 4F) + .DebugSave(provider, null, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyGlowFilterInBox(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.Glow(bounds) + .DebugSave(provider, null, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Overlays/VignetteTest.cs b/tests/ImageSharp.Tests/Processing/Overlays/VignetteTest.cs new file mode 100644 index 000000000..85ccfca6f --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Overlays/VignetteTest.cs @@ -0,0 +1,67 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Overlays +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class VignetteTest : FileTestBase + { + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyVignetteFilter(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Vignette() + .DebugSave(provider, null, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyVignetteFilterColor(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Vignette(NamedColors.Orange) + .DebugSave(provider, null, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyVignetteFilterRadius(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Vignette(image.Width / 4F, image.Height / 4F) + .DebugSave(provider, null, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldApplyVignetteFilterInBox(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image source = provider.GetImage()) + using (var image = new Image(source)) + { + var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + + image.Vignette(bounds) + .DebugSave(provider, null, Extensions.Bmp); + + ImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/AutoOrientTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AutoOrientTests.cs similarity index 56% rename from tests/ImageSharp.Tests/Processors/Filters/AutoOrientTests.cs rename to tests/ImageSharp.Tests/Processing/Transforms/AutoOrientTests.cs index 470e7150b..7bc0c8bb5 100644 --- a/tests/ImageSharp.Tests/Processors/Filters/AutoOrientTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AutoOrientTests.cs @@ -1,19 +1,19 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageSharp.Tests +namespace ImageSharp.Tests.Processing.Transforms { - using System.IO; - using ImageSharp.PixelFormats; + using ImageSharp.Processing; - using Processing; using Xunit; public class AutoOrientTests : FileTestBase { + public static readonly string[] FlipFiles = { TestImages.Bmp.F }; + public static readonly TheoryData OrientationValues = new TheoryData { @@ -29,23 +29,19 @@ namespace ImageSharp.Tests }; [Theory] - [MemberData(nameof(OrientationValues))] - public void ImageShouldFlip(RotateType rotateType, FlipType flipType, ushort orientation) + [WithFileCollection(nameof(FlipFiles), nameof(OrientationValues), DefaultPixelType)] + public void ImageShouldAutoRotate(TestImageProvider provider, RotateType rotateType, FlipType flipType, ushort orientation) + where TPixel : struct, IPixel { - string path = this.CreateOutputDirectory("AutoOrient"); - - TestFile file = TestFile.Create(TestImages.Bmp.F); - - using (Image image = file.CreateImage()) + using (Image image = provider.GetImage()) { image.MetaData.ExifProfile = new ExifProfile(); image.MetaData.ExifProfile.SetValue(ExifTag.Orientation, orientation); - using (FileStream before = File.OpenWrite($"{path}/before-{file.FileName}")) - using (FileStream after = File.OpenWrite($"{path}/after-{file.FileName}")) - { - image.RotateFlip(rotateType, flipType).Save(before).AutoOrient().Save(after); - } + image.RotateFlip(rotateType, flipType) + .DebugSave(provider, string.Join("_", rotateType, flipType, orientation, "1_before"), Extensions.Bmp) + .AutoOrient() + .DebugSave(provider, string.Join("_", rotateType, flipType, orientation, "2_after"), Extensions.Bmp); } } } diff --git a/tests/ImageSharp.Tests/Processing/Transforms/CropTest.cs b/tests/ImageSharp.Tests/Processing/Transforms/CropTest.cs new file mode 100644 index 000000000..ca20abf79 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Transforms/CropTest.cs @@ -0,0 +1,26 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Transforms +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class CropTest : FileTestBase + { + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldCrop(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Crop(image.Width / 2, image.Height / 2) + .DebugSave(provider, null, Extensions.Bmp); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Transforms/EntropyCropTest.cs b/tests/ImageSharp.Tests/Processing/Transforms/EntropyCropTest.cs new file mode 100644 index 000000000..24febd5b2 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Transforms/EntropyCropTest.cs @@ -0,0 +1,33 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Transforms +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class EntropyCropTest : FileTestBase + { + public static readonly TheoryData EntropyCropValues + = new TheoryData + { + .25F, + .75F + }; + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(EntropyCropValues), DefaultPixelType)] + public void ImageShouldEntropyCrop(TestImageProvider provider, float value) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.EntropyCrop(value) + .DebugSave(provider, value, Extensions.Bmp); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Transforms/FlipTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/FlipTests.cs new file mode 100644 index 000000000..45ab1e5f8 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Transforms/FlipTests.cs @@ -0,0 +1,37 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Transforms +{ + using ImageSharp.PixelFormats; + using ImageSharp.Processing; + + using Xunit; + + public class FlipTests : FileTestBase + { + public static readonly string[] FlipFiles = { TestImages.Bmp.F }; + + public static readonly TheoryData FlipValues + = new TheoryData + { + { FlipType.None }, + { FlipType.Vertical }, + { FlipType.Horizontal }, + }; + + [Theory] + [WithFileCollection(nameof(FlipFiles), nameof(FlipValues), DefaultPixelType)] + public void ImageShouldFlip(TestImageProvider provider, FlipType flipType) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Flip(flipType) + .DebugSave(provider, flipType, Extensions.Bmp); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Transforms/PadTest.cs b/tests/ImageSharp.Tests/Processing/Transforms/PadTest.cs new file mode 100644 index 000000000..666f3df78 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Transforms/PadTest.cs @@ -0,0 +1,35 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Transforms +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class PadTest : FileTestBase + { + [Theory] + [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] + public void ImageShouldPad(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Pad(image.Width + 50, image.Height + 50) + .DebugSave(provider, null, Extensions.Bmp); + + // Check pixels are empty + for (int y = 0; y < 25; y++) + { + for (int x = 0; x < 25; x++) + { + Assert.Equal(image[x, y], default(TPixel)); + } + } + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/ResizeProfilingBenchmarks.cs b/tests/ImageSharp.Tests/Processing/Transforms/ResizeProfilingBenchmarks.cs similarity index 69% rename from tests/ImageSharp.Tests/Processors/Filters/ResizeProfilingBenchmarks.cs rename to tests/ImageSharp.Tests/Processing/Transforms/ResizeProfilingBenchmarks.cs index a743665d4..8b57586f4 100644 --- a/tests/ImageSharp.Tests/Processors/Filters/ResizeProfilingBenchmarks.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ResizeProfilingBenchmarks.cs @@ -1,9 +1,14 @@ -namespace ImageSharp.Tests +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Transforms { + using System; using System.IO; using System.Text; - using ImageSharp.PixelFormats; using ImageSharp.Processing; using ImageSharp.Processing.Processors; @@ -27,7 +32,7 @@ namespace ImageSharp.Tests this.Measure(this.ExecutionCount, () => { - using (Image image = new Image(width, height)) + using (var image = new Image(width, height)) { image.Resize(width / 4, height / 4); } @@ -37,26 +42,28 @@ namespace ImageSharp.Tests // [Fact] public void PrintWeightsData() { - ResizeProcessor proc = new ResizeProcessor(new BicubicResampler(), 200, 200); + var proc = new ResizeProcessor(new BicubicResampler(), 200, 200); ResamplingWeightedProcessor.WeightsBuffer weights = proc.PrecomputeWeights(200, 500); - StringBuilder bld = new StringBuilder(); + var bld = new StringBuilder(); foreach (ResamplingWeightedProcessor.WeightsWindow window in weights.Weights) { + Span span = window.GetWindowSpan(); for (int i = 0; i < window.Length; i++) { - float value = window.Span[i]; + float value = span[i]; bld.Append(value); bld.Append("| "); } + bld.AppendLine(); } File.WriteAllText("BicubicWeights.MD", bld.ToString()); - //this.Output.WriteLine(bld.ToString()); + // this.Output.WriteLine(bld.ToString()); } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs new file mode 100644 index 000000000..008d041e7 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs @@ -0,0 +1,273 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Transforms +{ + using ImageSharp.PixelFormats; + using ImageSharp.Processing; + + using Xunit; + + public class ResizeTests : FileTestBase + { + public static readonly string[] ResizeFiles = { TestImages.Jpeg.Baseline.Calliphora }; + + public static readonly TheoryData ReSamplers = + new TheoryData + { + { "Bicubic", new BicubicResampler() }, + { "Triangle", new TriangleResampler() }, + { "NearestNeighbor", new NearestNeighborResampler() }, + { "Box", new BoxResampler() }, + { "Lanczos3", new Lanczos3Resampler() }, + { "Lanczos5", new Lanczos5Resampler() }, + { "MitchellNetravali", new MitchellNetravaliResampler() }, + { "Lanczos8", new Lanczos8Resampler() }, + { "Hermite", new HermiteResampler() }, + { "Spline", new SplineResampler() }, + { "Robidoux", new RobidouxResampler() }, + { "RobidouxSharp", new RobidouxSharpResampler() }, + { "Welch", new WelchResampler() } + }; + + [Theory] + [WithFileCollection(nameof(ResizeFiles), nameof(ReSamplers), DefaultPixelType)] + public void ImageShouldResize(TestImageProvider provider, string name, IResampler sampler) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Resize(image.Width / 2, image.Height / 2, sampler, true) + .DebugSave(provider, name, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(ResizeFiles), nameof(ReSamplers), DefaultPixelType)] + public void ImageShouldResizeFromSourceRectangle(TestImageProvider provider, string name, IResampler sampler) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + var sourceRectangle = new Rectangle(image.Width / 8, image.Height / 8, image.Width / 4, image.Height / 4); + var destRectangle = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2); + + image.Resize(image.Width, image.Height, sampler, sourceRectangle, destRectangle, false) + .DebugSave(provider, name, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(ResizeFiles), nameof(ReSamplers), DefaultPixelType)] + public void ImageShouldResizeWidthAndKeepAspect(TestImageProvider provider, string name, IResampler sampler) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Resize(image.Width / 3, 0, sampler, false) + .DebugSave(provider, name, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(ResizeFiles), nameof(ReSamplers), DefaultPixelType)] + public void ImageShouldResizeHeightAndKeepAspect(TestImageProvider provider, string name, IResampler sampler) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Resize(0, image.Height / 3, sampler, false) + .DebugSave(provider, name, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(ResizeFiles), nameof(ReSamplers), DefaultPixelType)] + public void ImageShouldResizeWithCropWidthMode(TestImageProvider provider, string name, IResampler sampler) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + var options = new ResizeOptions + { + Sampler = sampler, + Size = new Size(image.Width / 2, image.Height) + }; + + image.Resize(options) + .DebugSave(provider, name, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(ResizeFiles), nameof(ReSamplers), DefaultPixelType)] + public void ImageShouldResizeWithCropHeightMode(TestImageProvider provider, string name, IResampler sampler) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + var options = new ResizeOptions + { + Sampler = sampler, + Size = new Size(image.Width, image.Height / 2) + }; + + image.Resize(options) + .DebugSave(provider, name, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(ResizeFiles), nameof(ReSamplers), DefaultPixelType)] + public void ImageShouldResizeWithPadMode(TestImageProvider provider, string name, IResampler sampler) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + var options = new ResizeOptions + { + Sampler = sampler, + Size = new Size(image.Width + 200, image.Height), + Mode = ResizeMode.Pad + }; + + image.Resize(options) + .DebugSave(provider, name, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(ResizeFiles), nameof(ReSamplers), DefaultPixelType)] + public void ImageShouldResizeWithBoxPadMode(TestImageProvider provider, string name, IResampler sampler) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + var options = new ResizeOptions + { + Sampler = sampler, + Size = new Size(image.Width + 200, image.Height + 200), + Mode = ResizeMode.BoxPad + }; + + image.Resize(options) + .DebugSave(provider, name, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(ResizeFiles), nameof(ReSamplers), DefaultPixelType)] + public void ImageShouldResizeWithMaxMode(TestImageProvider provider, string name, IResampler sampler) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + var options = new ResizeOptions + { + Sampler = sampler, + Size = new Size(300, 300), + Mode = ResizeMode.Max + }; + + image.Resize(options) + .DebugSave(provider, name, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(ResizeFiles), nameof(ReSamplers), DefaultPixelType)] + public void ImageShouldResizeWithMinMode(TestImageProvider provider, string name, IResampler sampler) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + var options = new ResizeOptions + { + Sampler = sampler, + Size = new Size((int)MathF.Round(image.Width * .75F), (int)MathF.Round(image.Height * .95F)), + Mode = ResizeMode.Min + }; + + image.Resize(options) + .DebugSave(provider, name, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(ResizeFiles), nameof(ReSamplers), DefaultPixelType)] + public void ImageShouldResizeWithStretchMode(TestImageProvider provider, string name, IResampler sampler) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + var options = new ResizeOptions + { + Sampler = sampler, + Size = new Size(image.Width / 2, image.Height), + Mode = ResizeMode.Stretch + }; + + image.Resize(options) + .DebugSave(provider, name, Extensions.Bmp); + } + } + + [Theory] + [InlineData(-2, 0)] + [InlineData(-1, 0)] + [InlineData(0, 1)] + [InlineData(1, 0)] + [InlineData(2, 0)] + public static void BicubicWindowOscillatesCorrectly(float x, float expected) + { + var sampler = new BicubicResampler(); + float result = sampler.GetValue(x); + + Assert.Equal(result, expected); + } + + [Theory] + [InlineData(-2, 0)] + [InlineData(-1, 0)] + [InlineData(0, 1)] + [InlineData(1, 0)] + [InlineData(2, 0)] + public static void TriangleWindowOscillatesCorrectly(float x, float expected) + { + var sampler = new TriangleResampler(); + float result = sampler.GetValue(x); + + Assert.Equal(result, expected); + } + + [Theory] + [InlineData(-2, 0)] + [InlineData(-1, 0)] + [InlineData(0, 1)] + [InlineData(1, 0)] + [InlineData(2, 0)] + public static void Lanczos3WindowOscillatesCorrectly(float x, float expected) + { + var sampler = new Lanczos3Resampler(); + float result = sampler.GetValue(x); + + Assert.Equal(result, expected); + } + + [Theory] + [InlineData(-4, 0)] + [InlineData(-2, 0)] + [InlineData(0, 1)] + [InlineData(2, 0)] + [InlineData(4, 0)] + public static void Lanczos5WindowOscillatesCorrectly(float x, float expected) + { + var sampler = new Lanczos5Resampler(); + float result = sampler.GetValue(x); + + Assert.Equal(result, expected); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Transforms/RotateFlipTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/RotateFlipTests.cs new file mode 100644 index 000000000..f85ef6f13 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Transforms/RotateFlipTests.cs @@ -0,0 +1,39 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Transforms +{ + using ImageSharp.PixelFormats; + using ImageSharp.Processing; + + using Xunit; + + public class RotateFlipTests : FileTestBase + { + public static readonly string[] FlipFiles = { TestImages.Bmp.F }; + + public static readonly TheoryData RotateFlipValues + = new TheoryData + { + { RotateType.None, FlipType.Vertical }, + { RotateType.None, FlipType.Horizontal }, + { RotateType.Rotate90, FlipType.None }, + { RotateType.Rotate180, FlipType.None }, + { RotateType.Rotate270, FlipType.None }, + }; + + [Theory] + [WithFileCollection(nameof(FlipFiles), nameof(RotateFlipValues), DefaultPixelType)] + public void ImageShouldRotateFlip(TestImageProvider provider, RotateType rotateType, FlipType flipType) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.RotateFlip(rotateType, flipType) + .DebugSave(provider, string.Join("_", rotateType, flipType), Extensions.Bmp); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Transforms/RotateTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/RotateTests.cs new file mode 100644 index 000000000..1f1856429 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Transforms/RotateTests.cs @@ -0,0 +1,55 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Transforms +{ + using ImageSharp.PixelFormats; + using ImageSharp.Processing; + + using Xunit; + + public class RotateTests : FileTestBase + { + public static readonly TheoryData RotateFloatValues + = new TheoryData + { + 170, + -170 + }; + + public static readonly TheoryData RotateEnumValues + = new TheoryData + { + RotateType.None, + RotateType.Rotate90, + RotateType.Rotate180, + RotateType.Rotate270 + }; + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(RotateFloatValues), DefaultPixelType)] + public void ImageShouldRotate(TestImageProvider provider, float value) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Rotate(value) + .DebugSave(provider, value, Extensions.Bmp); + } + } + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(RotateEnumValues), DefaultPixelType)] + public void ImageShouldRotateEnum(TestImageProvider provider, RotateType value) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Rotate(value) + .DebugSave(provider, value, Extensions.Bmp); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Transforms/SkewTest.cs b/tests/ImageSharp.Tests/Processing/Transforms/SkewTest.cs new file mode 100644 index 000000000..f2c2d7cbd --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Transforms/SkewTest.cs @@ -0,0 +1,33 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Processing.Transforms +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class SkewTest : FileTestBase + { + public static readonly TheoryData SkewValues + = new TheoryData + { + { 20, 10 }, + { -20, -10 } + }; + + [Theory] + [WithFileCollection(nameof(DefaultFiles), nameof(SkewValues), DefaultPixelType)] + public void ImageShouldSkew(TestImageProvider provider, float x, float y) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + image.Skew(x, y) + .DebugSave(provider, string.Join("_", x, y), Extensions.Bmp); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/AlphaTest.cs b/tests/ImageSharp.Tests/Processors/Filters/AlphaTest.cs deleted file mode 100644 index 401ac916b..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/AlphaTest.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class AlphaTest : FileTestBase - { - public static readonly TheoryData AlphaValues - = new TheoryData - { - 20/100f , - 80/100f - }; - - [Theory] - [MemberData(nameof(AlphaValues))] - public void ImageShouldApplyAlphaFilter(float value) - { - string path = this.CreateOutputDirectory("Alpha"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Alpha(value).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(AlphaValues))] - public void ImageShouldApplyAlphaFilterInBox(float value) - { - string path = this.CreateOutputDirectory("Alpha"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value + "-InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Alpha(value, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/BackgroundColorTest.cs b/tests/ImageSharp.Tests/Processors/Filters/BackgroundColorTest.cs deleted file mode 100644 index d7ca78d1b..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/BackgroundColorTest.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class BackgroundColorTest : FileTestBase - { - [Fact] - public void ImageShouldApplyBackgroundColorFilter() - { - string path = this.CreateOutputDirectory("BackgroundColor"); - - foreach (TestFile file in Files) - { - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{file.FileName}")) - { - image.BackgroundColor(Rgba32.HotPink).Save(output); - } - } - } - - [Fact] - public void ImageShouldApplyBackgroundColorFilterInBox() - { - string path = this.CreateOutputDirectory("BackgroundColor"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName("-InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.BackgroundColor(Rgba32.HotPink, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/BinaryThresholdTest.cs b/tests/ImageSharp.Tests/Processors/Filters/BinaryThresholdTest.cs deleted file mode 100644 index 4e5e8a82e..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/BinaryThresholdTest.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class BinaryThresholdTest : FileTestBase - { - public static readonly TheoryData BinaryThresholdValues - = new TheoryData - { - .25f , - .75f , - }; - - [Theory] - [MemberData(nameof(BinaryThresholdValues))] - public void ImageShouldApplyBinaryThresholdFilter(float value) - { - string path = this.CreateOutputDirectory("BinaryThreshold"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.BinaryThreshold(value).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(BinaryThresholdValues))] - public void ImageShouldApplyBinaryThresholdInBox(float value) - { - string path = this.CreateOutputDirectory("BinaryThreshold"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value + "-InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.BinaryThreshold(value, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/BlackWhiteTest.cs b/tests/ImageSharp.Tests/Processors/Filters/BlackWhiteTest.cs deleted file mode 100644 index d10698a99..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/BlackWhiteTest.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class BlackWhiteTest : FileTestBase - { - [Fact] - public void ImageShouldApplyBlackWhiteFilter() - { - string path = this.CreateOutputDirectory("BlackWhite"); - - foreach (TestFile file in Files) - { - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{file.FileName}")) - { - image.BlackWhite().Save(output); - } - } - } - - [Fact] - public void ImageShouldApplyBlackWhiteFilterInBox() - { - string path = this.CreateOutputDirectory("BlackWhite"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName("-InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.BlackWhite(new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/BoxBlurTest.cs b/tests/ImageSharp.Tests/Processors/Filters/BoxBlurTest.cs deleted file mode 100644 index 03226a961..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/BoxBlurTest.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class BoxBlurTest : FileTestBase - { - public static readonly TheoryData BoxBlurValues - = new TheoryData - { - 3 , - 5 , - }; - - [Theory] - [MemberData(nameof(BoxBlurValues))] - public void ImageShouldApplyBoxBlurFilter(int value) - { - string path = this.CreateOutputDirectory("BoxBlur"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.BoxBlur(value).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(BoxBlurValues))] - public void ImageShouldApplyBoxBlurFilterInBox(int value) - { - string path = this.CreateOutputDirectory("BoxBlur"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value + "-InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.BoxBlur(value, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/BrightnessTest.cs b/tests/ImageSharp.Tests/Processors/Filters/BrightnessTest.cs deleted file mode 100644 index ce434d734..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/BrightnessTest.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class BrightnessTest : FileTestBase - { - public static readonly TheoryData BrightnessValues - = new TheoryData - { - 50 , - -50 , - }; - - [Theory] - [MemberData(nameof(BrightnessValues))] - public void ImageShouldApplyBrightnessFilter(int value) - { - string path = this.CreateOutputDirectory("Brightness"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Brightness(value).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(BrightnessValues))] - public void ImageShouldApplyBrightnessFilterInBox(int value) - { - string path = this.CreateOutputDirectory("Brightness"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value + "-InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Brightness(value, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/ColorBlindnessTest.cs b/tests/ImageSharp.Tests/Processors/Filters/ColorBlindnessTest.cs deleted file mode 100644 index c28732253..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/ColorBlindnessTest.cs +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using Processing; - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class ColorBlindnessTest : FileTestBase - { - public static readonly TheoryData ColorBlindnessFilters - = new TheoryData - { - ColorBlindness.Achromatomaly, - ColorBlindness.Achromatopsia, - ColorBlindness.Deuteranomaly, - ColorBlindness.Deuteranopia, - ColorBlindness.Protanomaly, - ColorBlindness.Protanopia, - ColorBlindness.Tritanomaly, - ColorBlindness.Tritanopia - }; - - [Theory] - [MemberData(nameof(ColorBlindnessFilters))] - public void ImageShouldApplyColorBlindnessFilter(ColorBlindness colorBlindness) - { - string path = this.CreateOutputDirectory("ColorBlindness"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(colorBlindness); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.ColorBlindness(colorBlindness).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(ColorBlindnessFilters))] - public void ImageShouldApplyBrightnessFilterInBox(ColorBlindness colorBlindness) - { - string path = this.CreateOutputDirectory("ColorBlindness"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(colorBlindness + "-InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.ColorBlindness(colorBlindness, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/ContrastTest.cs b/tests/ImageSharp.Tests/Processors/Filters/ContrastTest.cs deleted file mode 100644 index 4626fbb6e..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/ContrastTest.cs +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class ContrastTest : FileTestBase - { - public static readonly TheoryData ContrastValues - = new TheoryData - { - 50 , - -50 , - }; - - [Theory] - [MemberData(nameof(ContrastValues))] - public void ImageShouldApplyContrastFilter(int value) - { - string path = this.CreateOutputDirectory("Contrast"); - - foreach (TestFile file in Files) - { - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{file.FileName}")) - { - image.Contrast(value).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(ContrastValues))] - public void ImageShouldApplyContrastFilterInBox(int value) - { - string path = this.CreateOutputDirectory("Contrast"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value + "-InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Contrast(value, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/CropTest.cs b/tests/ImageSharp.Tests/Processors/Filters/CropTest.cs deleted file mode 100644 index 6713d0d38..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/CropTest.cs +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class CropTest : FileTestBase - { - [Fact] - public void ImageShouldApplyCropSampler() - { - string path = this.CreateOutputDirectory("Crop"); - - foreach (TestFile file in Files) - { - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{file.FileName}")) - { - image.Crop(image.Width / 2, image.Height / 2).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/DetectEdgesTest.cs b/tests/ImageSharp.Tests/Processors/Filters/DetectEdgesTest.cs deleted file mode 100644 index 00440e8a5..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/DetectEdgesTest.cs +++ /dev/null @@ -1,67 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using Processing; - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class DetectEdgesTest : FileTestBase - { - public static readonly TheoryData DetectEdgesFilters - = new TheoryData - { - EdgeDetection.Kayyali, - EdgeDetection.Kirsch, - EdgeDetection.Lapacian3X3, - EdgeDetection.Lapacian5X5, - EdgeDetection.LaplacianOfGaussian, - EdgeDetection.Prewitt, - EdgeDetection.RobertsCross, - EdgeDetection.Robinson, - EdgeDetection.Scharr, - EdgeDetection.Sobel - }; - - [Theory] - [MemberData(nameof(DetectEdgesFilters))] - public void ImageShouldApplyDetectEdgesFilter(EdgeDetection detector) - { - string path = this.CreateOutputDirectory("DetectEdges"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(detector); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.DetectEdges(detector).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(DetectEdgesFilters))] - public void ImageShouldApplyDetectEdgesFilterInBox(EdgeDetection detector) - { - string path = this.CreateOutputDirectory("DetectEdges"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(detector + "-InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.DetectEdges(detector, new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2)) - .Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/DitherTest.cs b/tests/ImageSharp.Tests/Processors/Filters/DitherTest.cs deleted file mode 100644 index 066e2d134..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/DitherTest.cs +++ /dev/null @@ -1,104 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.Dithering; - using ImageSharp.Dithering.Ordered; - using ImageSharp.PixelFormats; - - using Xunit; - - public class DitherTest : FileTestBase - { - public static readonly TheoryData Ditherers = new TheoryData - { - { "Ordered", new Ordered() }, - { "Bayer", new Bayer() } - }; - - public static readonly TheoryData ErrorDiffusers = new TheoryData - { - { "Atkinson", new Atkinson() }, - { "Burks", new Burks() }, - { "FloydSteinberg", new FloydSteinberg() }, - { "JarvisJudiceNinke", new JarvisJudiceNinke() }, - { "Sierra2", new Sierra2() }, - { "Sierra3", new Sierra3() }, - { "SierraLite", new SierraLite() }, - { "Stucki", new Stucki() }, - }; - - [Theory] - [MemberData(nameof(Ditherers))] - public void ImageShouldApplyDitherFilter(string name, IOrderedDither ditherer) - { - string path = this.CreateOutputDirectory("Dither", "Dither"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(name); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Dither(ditherer).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(Ditherers))] - public void ImageShouldApplyDitherFilterInBox(string name, IOrderedDither ditherer) - { - string path = this.CreateOutputDirectory("Dither", "Dither"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName($"{name}-InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Dither(ditherer, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(ErrorDiffusers))] - public void ImageShouldApplyDiffusionFilter(string name, IErrorDiffuser diffuser) - { - string path = this.CreateOutputDirectory("Dither", "Diffusion"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(name); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Dither(diffuser, .5F).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(ErrorDiffusers))] - public void ImageShouldApplyDiffusionFilterInBox(string name, IErrorDiffuser diffuser) - { - string path = this.CreateOutputDirectory("Dither", "Diffusion"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName($"{name}-InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Dither(diffuser, .5F, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/EntropyCropTest.cs b/tests/ImageSharp.Tests/Processors/Filters/EntropyCropTest.cs deleted file mode 100644 index 710e23e37..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/EntropyCropTest.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class EntropyCropTest : FileTestBase - { - public static readonly TheoryData EntropyCropValues - = new TheoryData - { - .25f , - .75f , - }; - - [Theory] - [MemberData(nameof(EntropyCropValues))] - public void ImageShouldApplyEntropyCropSampler(float value) - { - string path = this.CreateOutputDirectory("EntropyCrop"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.EntropyCrop(value).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/FlipTests.cs b/tests/ImageSharp.Tests/Processors/Filters/FlipTests.cs deleted file mode 100644 index 87f5e1025..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/FlipTests.cs +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Processing; - using Xunit; - - public class FlipTests : FileTestBase - { - public static readonly TheoryData FlipValues - = new TheoryData - { - { FlipType.None }, - { FlipType.Vertical }, - { FlipType.Horizontal }, - }; - - [Theory] - [MemberData(nameof(FlipValues))] - public void ImageShouldFlip(FlipType flipType) - { - string path = this.CreateOutputDirectory("Flip"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(flipType); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Flip(flipType).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/GlowTest.cs b/tests/ImageSharp.Tests/Processors/Filters/GlowTest.cs deleted file mode 100644 index 43e45f9ca..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/GlowTest.cs +++ /dev/null @@ -1,80 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class GlowTest : FileTestBase - { - [Fact] - public void ImageShouldApplyGlowFilter() - { - string path = this.CreateOutputDirectory("Glow"); - - foreach (TestFile file in Files) - { - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{file.FileName}")) - { - image.Glow().Save(output); - } - } - } - - [Fact] - public void ImageShouldApplyGlowFilterColor() - { - string path = this.CreateOutputDirectory("Glow"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName("Color"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Glow(Rgba32.HotPink).Save(output); - } - } - } - - [Fact] - public void ImageShouldApplyGlowFilterRadius() - { - string path = this.CreateOutputDirectory("Glow"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName("Radius"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Glow(image.Width / 4F).Save(output); - } - } - } - - [Fact] - public void ImageShouldApplyGlowFilterInBox() - { - string path = this.CreateOutputDirectory("Glow"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName("InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Glow(new Rectangle(image.Width / 8, image.Height / 8, image.Width / 2, image.Height / 2)) - .Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/HueTest.cs b/tests/ImageSharp.Tests/Processors/Filters/HueTest.cs deleted file mode 100644 index 488433931..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/HueTest.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class HueTest : FileTestBase - { - public static readonly TheoryData HueValues - = new TheoryData - { - 180 , - -180 , - }; - - [Theory] - [MemberData(nameof(HueValues))] - public void ImageShouldApplyHueFilter(int value) - { - string path = this.CreateOutputDirectory("Hue"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Hue(value).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(HueValues))] - public void ImageShouldApplyHueFilterInBox(int value) - { - string path = this.CreateOutputDirectory("Hue"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value + "-InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Hue(value, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/InvertTest.cs b/tests/ImageSharp.Tests/Processors/Filters/InvertTest.cs deleted file mode 100644 index 6d375d09a..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/InvertTest.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class InvertTest : FileTestBase - { - [Fact] - public void ImageShouldApplyInvertFilter() - { - string path = this.CreateOutputDirectory("Invert"); - foreach (TestFile file in Files) - { - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{file.FileName}")) - { - image.Invert().Save(output); - } - } - } - - [Fact] - public void ImageShouldApplyInvertFilterInBox() - { - string path = this.CreateOutputDirectory("Invert"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName("InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Invert(new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/KodachromeTest.cs b/tests/ImageSharp.Tests/Processors/Filters/KodachromeTest.cs deleted file mode 100644 index 29a459f97..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/KodachromeTest.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class KodachromeTest : FileTestBase - { - [Fact] - public void ImageShouldApplyKodachromeFilter() - { - string path = this.CreateOutputDirectory("Kodachrome"); - - foreach (TestFile file in Files) - { - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{file.FileName}")) - { - image.Kodachrome().Save(output); - } - } - } - - [Fact] - public void ImageShouldApplyKodachromeFilterInBox() - { - string path = this.CreateOutputDirectory("Kodachrome"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName("InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Kodachrome(new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/LomographTest.cs b/tests/ImageSharp.Tests/Processors/Filters/LomographTest.cs deleted file mode 100644 index 6ceedecbd..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/LomographTest.cs +++ /dev/null @@ -1,48 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class LomographTest : FileTestBase - { - [Fact] - public void ImageShouldApplyLomographFilter() - { - string path = this.CreateOutputDirectory("Lomograph"); - - foreach (TestFile file in Files) - { - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{file.FileName}")) - { - image.Lomograph().Save(output); - } - } - } - - [Fact] - public void ImageShouldApplyLomographFilterInBox() - { - string path = this.CreateOutputDirectory("Lomograph"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName("InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Lomograph(new Rectangle(image.Width / 4, image.Width / 4, image.Width / 2, image.Height / 2)) - .Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs b/tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs deleted file mode 100644 index 5facee346..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs +++ /dev/null @@ -1,66 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System; - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class OilPaintTest : FileTestBase - { - public static readonly TheoryData> OilPaintValues - = new TheoryData> - { - new Tuple(15, 10), - new Tuple(6, 5) - }; - - [Theory] - [MemberData(nameof(OilPaintValues))] - public void ImageShouldApplyOilPaintFilter(Tuple value) - { - string path = this.CreateOutputDirectory("OilPaint"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - if (image.Width > value.Item2 && image.Height > value.Item2) - { - image.OilPaint(value.Item1, value.Item2).Save(output); - } - } - } - } - - [Theory] - [MemberData(nameof(OilPaintValues))] - public void ImageShouldApplyOilPaintFilterInBox(Tuple value) - { - string path = this.CreateOutputDirectory("OilPaint"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value + "-InBox"); - using (Image image = file.CreateImage()) - { - if (image.Width > value.Item2 && image.Height > value.Item2) - { - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.OilPaint(value.Item1, value.Item2, new Rectangle(image.Width / 4, image.Width / 4, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/PadTest.cs b/tests/ImageSharp.Tests/Processors/Filters/PadTest.cs deleted file mode 100644 index 6095410a9..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/PadTest.cs +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class PadTest : FileTestBase - { - [Fact] - public void ImageShouldApplyPadSampler() - { - string path = this.CreateOutputDirectory("Pad"); - - foreach (TestFile file in Files) - { - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{file.FileName}")) - { - image.Pad(image.Width + 50, image.Height + 50).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/PixelateTest.cs b/tests/ImageSharp.Tests/Processors/Filters/PixelateTest.cs deleted file mode 100644 index b21a8c969..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/PixelateTest.cs +++ /dev/null @@ -1,94 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - using ImageSharp.PixelFormats; - using Xunit; - - public class PixelateTest - { - public static readonly TheoryData PixelateValues - = new TheoryData - { - 4 , - 8 - }; - - [Theory] - [WithTestPatternImages(nameof(PixelateValues), 320, 240, PixelTypes.StandardImageClass)] - public void ImageShouldApplyPixelateFilter(TestImageProvider provider, int value) - where TPixel : struct, IPixel - { - using (Image image = provider.GetImage()) - { - image.Pixelate(value) - .DebugSave(provider, new - { - size = value - }); - - using (PixelAccessor pixels = image.Lock()) - { - for (int y = 0; y < pixels.Height; y += value) - { - for (int x = 0; x < pixels.Width; x += value) - { - TPixel source = pixels[x, y]; - for (int pixY = y; pixY < y + value && pixY < pixels.Height; pixY++) - { - for (int pixX = x; pixX < x + value && pixX < pixels.Width; pixX++) - { - Assert.Equal(source, pixels[pixX, pixY]); - } - } - } - } - } - } - } - - [Theory] - [WithTestPatternImages(nameof(PixelateValues), 320, 240, PixelTypes.StandardImageClass)] - public void ImageShouldApplyPixelateFilterInBox(TestImageProvider provider, int value) - where TPixel : struct, IPixel - { - using (Image source = provider.GetImage()) - using (Image image = new Image(source)) - { - Rectangle rect = new Rectangle(image.Width/4, image.Height / 4, image.Width / 2, image.Height / 2); - - image.Pixelate(value, rect) - .DebugSave(provider, new - { - size = value - }); - - using (PixelAccessor pixels = image.Lock()) - using (PixelAccessor sourcePixels = source.Lock()) - { - for (int y = 0; y < pixels.Height; y++) - { - for (int x = 0; x < pixels.Width; x++) - { - var tx = x; - var ty = y; - TPixel sourceColor = sourcePixels[tx, ty]; - if (rect.Contains(tx, ty)) - { - var sourceX = tx - ((tx - rect.Left) % value) + (value / 2); - var sourceY = ty - ((ty - rect.Top) % value) + (value / 2); - - sourceColor = pixels[sourceX, sourceY]; - } - Assert.Equal(sourceColor, pixels[tx, ty]); - } - } - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/PolaroidTest.cs b/tests/ImageSharp.Tests/Processors/Filters/PolaroidTest.cs deleted file mode 100644 index df3803255..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/PolaroidTest.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class PolaroidTest : FileTestBase - { - [Fact] - public void ImageShouldApplyPolaroidFilter() - { - string path = this.CreateOutputDirectory("Polaroid"); - - foreach (TestFile file in Files) - { - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{file.FileName}")) - { - image.Polaroid().Save(output); - } - } - } - - [Fact] - public void ImageShouldApplyPolaroidFilterInBox() - { - string path = this.CreateOutputDirectory("Polaroid"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName("InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Polaroid(new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/ResizeTests.cs b/tests/ImageSharp.Tests/Processors/Filters/ResizeTests.cs deleted file mode 100644 index 31f4020b6..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/ResizeTests.cs +++ /dev/null @@ -1,350 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// -namespace ImageSharp.Tests -{ - using System; - using System.IO; - - using ImageSharp.PixelFormats; - - using Processing; - using Xunit; - - public class ResizeTests : FileTestBase - { - public static readonly TheoryData ReSamplers = - new TheoryData - { - { "Bicubic", new BicubicResampler() }, - { "Triangle", new TriangleResampler() }, - { "NearestNeighbor", new NearestNeighborResampler() }, - - // Perf: Enable for local testing only - // { "Box", new BoxResampler() }, - // { "Lanczos3", new Lanczos3Resampler() }, - // { "Lanczos5", new Lanczos5Resampler() }, - { "MitchellNetravali", new MitchellNetravaliResampler() }, - - // { "Lanczos8", new Lanczos8Resampler() }, - // { "Hermite", new HermiteResampler() }, - // { "Spline", new SplineResampler() }, - // { "Robidoux", new RobidouxResampler() }, - // { "RobidouxSharp", new RobidouxSharpResampler() }, - // { "RobidouxSoft", new RobidouxSoftResampler() }, - // { "Welch", new WelchResampler() } - }; - - [Theory] - [MemberData(nameof(ReSamplers))] - public void ImageShouldResize(string name, IResampler sampler) - { - string path = this.CreateOutputDirectory("Resize"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(name); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Resize(image.Width / 2, image.Height / 2, sampler, true).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(ReSamplers))] - public void ImageShouldResizeFromSourceRectangle(string name, IResampler sampler) - { - name = $"{name}-SourceRect"; - - string path = this.CreateOutputDirectory("Resize"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(name); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - Rectangle sourceRectangle = new Rectangle(image.Width / 8, image.Height / 8, image.Width / 4, image.Height / 4); - Rectangle destRectangle = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2); - image.Resize(image.Width, image.Height, sampler, sourceRectangle, destRectangle, false).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(ReSamplers))] - public void ImageShouldResizeWidthAndKeepAspect(string name, IResampler sampler) - { - name = $"{name}-FixedWidth"; - - string path = this.CreateOutputDirectory("Resize"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(name); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Resize(image.Width / 3, 0, sampler, false).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(ReSamplers))] - public void ImageShouldResizeHeightAndKeepAspect(string name, IResampler sampler) - { - name = $"{name}-FixedHeight"; - - string path = this.CreateOutputDirectory("Resize"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(name); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Resize(0, image.Height / 3, sampler, false).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(ReSamplers))] - public void ImageShouldResizeWithCropWidthMode(string name, IResampler sampler) - { - name = $"{name}-CropWidth"; - - string path = this.CreateOutputDirectory("Resize"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(name); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - ResizeOptions options = new ResizeOptions - { - Sampler = sampler, - Size = new Size(image.Width / 2, image.Height) - }; - - image.Resize(options).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(ReSamplers))] - public void ImageShouldResizeWithCropHeightMode(string name, IResampler sampler) - { - name = $"{name}-CropHeight"; - - string path = this.CreateOutputDirectory("Resize"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(name); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - ResizeOptions options = new ResizeOptions - { - Sampler = sampler, - Size = new Size(image.Width, image.Height / 2) - }; - - image.Resize(options).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(ReSamplers))] - public void ImageShouldResizeWithPadMode(string name, IResampler sampler) - { - name = $"{name}-Pad"; - - string path = this.CreateOutputDirectory("Resize"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(name); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - ResizeOptions options = new ResizeOptions - { - Size = new Size(image.Width + 200, image.Height), - Mode = ResizeMode.Pad - }; - - image.Resize(options).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(ReSamplers))] - public void ImageShouldResizeWithBoxPadMode(string name, IResampler sampler) - { - name = $"{name}-BoxPad"; - - string path = this.CreateOutputDirectory("Resize"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(name); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - ResizeOptions options = new ResizeOptions - { - Sampler = sampler, - Size = new Size(image.Width + 200, image.Height + 200), - Mode = ResizeMode.BoxPad - }; - - image.Resize(options).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(ReSamplers))] - public void ImageShouldResizeWithMaxMode(string name, IResampler sampler) - { - name = $"{name}Max"; - - string path = this.CreateOutputDirectory("Resize"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(name); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - ResizeOptions options = new ResizeOptions - { - Sampler = sampler, - Size = new Size(300, 300), - Mode = ResizeMode.Max - }; - - image.Resize(options).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(ReSamplers))] - public void ImageShouldResizeWithMinMode(string name, IResampler sampler) - { - name = $"{name}-Min"; - - string path = this.CreateOutputDirectory("Resize"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(name); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - ResizeOptions options = new ResizeOptions - { - Sampler = sampler, - Size = new Size((int)Math.Round(image.Width * .75F), (int)Math.Round(image.Height * .95F)), - Mode = ResizeMode.Min - }; - - image.Resize(options).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(ReSamplers))] - public void ImageShouldResizeWithStretchMode(string name, IResampler sampler) - { - name = $"{name}Stretch"; - - string path = this.CreateOutputDirectory("Resize"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(name); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - ResizeOptions options = new ResizeOptions - { - Sampler = sampler, - Size = new Size(image.Width / 2, image.Height), - Mode = ResizeMode.Stretch - }; - - image.Resize(options).Save(output); - } - } - } - - [Theory] - [InlineData(-2, 0)] - [InlineData(-1, 0)] - [InlineData(0, 1)] - [InlineData(1, 0)] - [InlineData(2, 0)] - public static void BicubicWindowOscillatesCorrectly(float x, float expected) - { - BicubicResampler sampler = new BicubicResampler(); - float result = sampler.GetValue(x); - - Assert.Equal(result, expected); - } - - [Theory] - [InlineData(-2, 0)] - [InlineData(-1, 0)] - [InlineData(0, 1)] - [InlineData(1, 0)] - [InlineData(2, 0)] - public static void TriangleWindowOscillatesCorrectly(float x, float expected) - { - TriangleResampler sampler = new TriangleResampler(); - float result = sampler.GetValue(x); - - Assert.Equal(result, expected); - } - - [Theory] - [InlineData(-2, 0)] - [InlineData(-1, 0)] - [InlineData(0, 1)] - [InlineData(1, 0)] - [InlineData(2, 0)] - public static void Lanczos3WindowOscillatesCorrectly(float x, float expected) - { - Lanczos3Resampler sampler = new Lanczos3Resampler(); - float result = sampler.GetValue(x); - - Assert.Equal(result, expected); - } - - [Theory] - [InlineData(-4, 0)] - [InlineData(-2, 0)] - [InlineData(0, 1)] - [InlineData(2, 0)] - [InlineData(4, 0)] - public static void Lanczos5WindowOscillatesCorrectly(float x, float expected) - { - Lanczos5Resampler sampler = new Lanczos5Resampler(); - float result = sampler.GetValue(x); - - Assert.Equal(result, expected); - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/RotateFlipTest.cs b/tests/ImageSharp.Tests/Processors/Filters/RotateFlipTest.cs deleted file mode 100644 index c4c4fa8d7..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/RotateFlipTest.cs +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Processing; - using Xunit; - - public class RotateFlipTest : FileTestBase - { - public static readonly TheoryData RotateFlipValues - = new TheoryData - { - { RotateType.None, FlipType.Vertical }, - { RotateType.None, FlipType.Horizontal }, - { RotateType.Rotate90, FlipType.None }, - { RotateType.Rotate180, FlipType.None }, - { RotateType.Rotate270, FlipType.None }, - }; - - [Theory] - [MemberData(nameof(RotateFlipValues))] - public void ImageShouldRotateFlip(RotateType rotateType, FlipType flipType) - { - string path = this.CreateOutputDirectory("RotateFlip"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(rotateType + "-" + flipType); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.RotateFlip(rotateType, flipType).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/RotateTest.cs b/tests/ImageSharp.Tests/Processors/Filters/RotateTest.cs deleted file mode 100644 index b30c795ad..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/RotateTest.cs +++ /dev/null @@ -1,67 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Processing; - using Xunit; - - public class RotateTest : FileTestBase - { - public static readonly TheoryData RotateFloatValues - = new TheoryData - { - 170 , - -170 , - }; - - public static readonly TheoryData RotateEnumValues - = new TheoryData - { - RotateType.None, - RotateType.Rotate90, - RotateType.Rotate180, - RotateType.Rotate270 - }; - - [Theory] - [MemberData(nameof(RotateFloatValues))] - public void ImageShouldApplyRotateSampler(float value) - { - string path = this.CreateOutputDirectory("Rotate"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Rotate(value).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(RotateEnumValues))] - public void ImageShouldApplyRotateSampler(RotateType value) - { - string path = this.CreateOutputDirectory("Rotate"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Rotate(value).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/SaturationTest.cs b/tests/ImageSharp.Tests/Processors/Filters/SaturationTest.cs deleted file mode 100644 index e28847fa3..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/SaturationTest.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class SaturationTest : FileTestBase - { - public static readonly TheoryData SaturationValues - = new TheoryData - { - 50 , - -50 , - }; - - [Theory] - [MemberData(nameof(SaturationValues))] - public void ImageShouldApplySaturationFilter(int value) - { - string path = CreateOutputDirectory("Saturation"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Saturation(value).Save(output); - } - } - } - - [Theory] - [MemberData(nameof(SaturationValues))] - public void ImageShouldApplySaturationFilterInBox(int value) - { - string path = this.CreateOutputDirectory("Saturation"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value + "-InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Saturation(value, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/SepiaTest.cs b/tests/ImageSharp.Tests/Processors/Filters/SepiaTest.cs deleted file mode 100644 index 490213ce7..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/SepiaTest.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class SepiaTest : FileTestBase - { - [Fact] - public void ImageShouldApplySepiaFilter() - { - string path = CreateOutputDirectory("Sepia"); - - foreach (TestFile file in Files) - { - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{file.FileName}")) - { - image.Sepia().Save(output); - } - } - } - - [Fact] - public void ImageShouldApplySepiaFilterInBox() - { - string path = this.CreateOutputDirectory("Sepia"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName("InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Sepia(new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/SkewTest.cs b/tests/ImageSharp.Tests/Processors/Filters/SkewTest.cs deleted file mode 100644 index d096b3913..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/SkewTest.cs +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class SkewTest : FileTestBase - { - public static readonly TheoryData SkewValues - = new TheoryData - { - { 20, 10 }, - { -20, -10 } - }; - - [Theory] - [MemberData(nameof(SkewValues))] - public void ImageShouldApplySkewSampler(float x, float y) - { - string path = this.CreateOutputDirectory("Skew"); - - // Matches live example - // http://www.w3schools.com/css/tryit.asp?filename=trycss3_transform_skew - foreach (TestFile file in Files) - { - string filename = file.GetFileName(x + "-" + y); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Skew(x, y).Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/VignetteTest.cs b/tests/ImageSharp.Tests/Processors/Filters/VignetteTest.cs deleted file mode 100644 index 4191ae8fa..000000000 --- a/tests/ImageSharp.Tests/Processors/Filters/VignetteTest.cs +++ /dev/null @@ -1,80 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using ImageSharp.PixelFormats; - - using Xunit; - - public class VignetteTest : FileTestBase - { - [Fact] - public void ImageShouldApplyVignetteFilter() - { - string path = this.CreateOutputDirectory("Vignette"); - - foreach (TestFile file in Files) - { - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{file.FileName}")) - { - image.Vignette().Save(output); - } - } - } - - [Fact] - public void ImageShouldApplyVignetteFilterColor() - { - string path = this.CreateOutputDirectory("Vignette"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName("Color"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Vignette(Rgba32.HotPink).Save(output); - } - } - } - - [Fact] - public void ImageShouldApplyVignetteFilterRadius() - { - string path = this.CreateOutputDirectory("Vignette"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName("Radius"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Vignette(image.Width / 4F, image.Height / 4F).Save(output); - } - } - } - - [Fact] - public void ImageShouldApplyVignetteFilterInBox() - { - string path = this.CreateOutputDirectory("Vignette"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName("InBox"); - using (Image image = file.CreateImage()) - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Vignette(new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2)) - .Save(output); - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 44c8c34ee..471d61abb 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -36,9 +36,20 @@ namespace ImageSharp.Tests // Filter changing per scanline public const string FilterVar = "Png/filterVar.png"; - // Odd chunk lengths - public const string ChunkLength1 = "Png/chunklength1.png"; - public const string ChunkLength2 = "Png/chunklength2.png"; + public static class Bad + { + // Odd chunk lengths + public const string ChunkLength1 = "Png/chunklength1.png"; + public const string ChunkLength2 = "Png/chunklength2.png"; + } + + public static readonly string[] All = + { + P1, Pd, Blur, Splash, Cross, + Powerpoint, SplashInterlaced, Interlaced, + Filter0, Filter1, Filter2, Filter3, Filter4, + FilterVar + }; } public static class Jpeg @@ -105,6 +116,8 @@ namespace ImageSharp.Tests public const string Giphy = "Gif/giphy.gif"; public const string Cheers = "Gif/cheers.gif"; public const string Trans = "Gif/trans.gif"; + + public static readonly string[] All = { Rings, Giphy, Cheers, Trans }; } } } diff --git a/tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs b/tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs index 379ce3d05..05e8c6136 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs @@ -21,25 +21,40 @@ namespace ImageSharp.Tests protected readonly PixelTypes PixelTypes; + /// + /// Initializes a new instance of the class. + /// + /// + /// + /// protected ImageDataAttributeBase(string memberName, PixelTypes pixelTypes, object[] additionalParameters) { this.PixelTypes = pixelTypes; this.AdditionalParameters = additionalParameters; this.MemberName = memberName; - } - public string MemberName { get; private set; } + /// + /// Gets the member name + /// + public string MemberName { get; } + /// + /// Gets the member type + /// public Type MemberType { get; set; } + /// Returns the data to be used to test the theory. + /// The method that is being tested + /// One or more sets of theory data. Each invocation of the test method + /// is represented by a single object array. public override IEnumerable GetData(MethodInfo testMethod) { - IEnumerable addedRows = Enumerable.Empty(); + IEnumerable addedRows = Enumerable.Empty().ToArray(); if (!string.IsNullOrWhiteSpace(this.MemberName)) { Type type = this.MemberType ?? testMethod.DeclaringType; - Func accessor = GetPropertyAccessor(type) ?? GetFieldAccessor(type);// ?? GetMethodAccessor(type); + Func accessor = this.GetPropertyAccessor(type) ?? this.GetFieldAccessor(type); if (accessor != null) { @@ -49,7 +64,7 @@ namespace ImageSharp.Tests addedRows = memberItems.Select(x => x as object[]); if (addedRows.Any(x => x == null)) { - throw new ArgumentException($"Property {MemberName} on {MemberType ?? testMethod.DeclaringType} yielded an item that is not an object[]"); + throw new ArgumentException($"Property {this.MemberName} on {this.MemberType ?? testMethod.DeclaringType} yielded an item that is not an object[]"); } } } @@ -60,18 +75,20 @@ namespace ImageSharp.Tests addedRows = new[] { new object[0] }; } - bool firstIsprovider = FirstIsProvider(testMethod); - IEnumerable dataItems = Enumerable.Empty(); + bool firstIsprovider = this.FirstIsProvider(testMethod); if (firstIsprovider) { - return InnerGetData(testMethod, addedRows); - } - else - { - return addedRows.Select(x => x.Concat(this.AdditionalParameters).ToArray()); + return this.InnerGetData(testMethod, addedRows); } + + return addedRows.Select(x => x.Concat(this.AdditionalParameters).ToArray()); } + /// + /// Returns a value indicating whether the first parameter of the method is a test provider. + /// + /// + /// private bool FirstIsProvider(MethodInfo testMethod) { TypeInfo dataType = testMethod.GetParameters().First().ParameterType.GetTypeInfo(); @@ -106,25 +123,45 @@ namespace ImageSharp.Tests } } + /// + /// Generates the collection of method arguments from the given test as a generic enumerable. + /// + /// The test method + /// The test image provider factory type + /// The protected virtual IEnumerable GetAllFactoryMethodArgs(MethodInfo testMethod, Type factoryType) { object[] args = this.GetFactoryMethodArgs(testMethod, factoryType); return Enumerable.Repeat(args, 1); } + /// + /// Generates the collection of method arguments from the given test. + /// + /// The test method + /// The test image provider factory type + /// The protected virtual object[] GetFactoryMethodArgs(MethodInfo testMethod, Type factoryType) { throw new InvalidOperationException("Semi-abstract method"); } + /// + /// Generates the method name from the given test method. + /// + /// The test method + /// The protected abstract string GetFactoryMethodName(MethodInfo testMethod); + /// + /// Gets the field accessor for the given type. + /// Func GetFieldAccessor(Type type) { FieldInfo fieldInfo = null; for (Type reflectionType = type; reflectionType != null; reflectionType = reflectionType.GetTypeInfo().BaseType) { - fieldInfo = reflectionType.GetRuntimeField(MemberName); + fieldInfo = reflectionType.GetRuntimeField(this.MemberName); if (fieldInfo != null) break; } @@ -135,39 +172,27 @@ namespace ImageSharp.Tests return () => fieldInfo.GetValue(null); } - //Func GetMethodAccessor(Type type) - //{ - // MethodInfo methodInfo = null; - // var parameterTypes = Parameters == null ? new Type[0] : Parameters.Select(p => p?.GetType()).ToArray(); - // for (var reflectionType = type; reflectionType != null; reflectionType = reflectionType.GetTypeInfo().BaseType) - // { - // methodInfo = reflectionType.GetRuntimeMethods() - // .FirstOrDefault(m => m.Name == MemberName && ParameterTypesCompatible(m.GetParameters(), parameterTypes)); - // if (methodInfo != null) - // break; - // } - - // if (methodInfo == null || !methodInfo.IsStatic) - // return null; - - // return () => methodInfo.Invoke(null, Parameters); - //} - + /// + /// Gets the property accessor for the given type. + /// Func GetPropertyAccessor(Type type) { PropertyInfo propInfo = null; for (Type reflectionType = type; reflectionType != null; reflectionType = reflectionType.GetTypeInfo().BaseType) { - propInfo = reflectionType.GetRuntimeProperty(MemberName); + propInfo = reflectionType.GetRuntimeProperty(this.MemberName); if (propInfo != null) + { break; + } } - if (propInfo == null || propInfo.GetMethod == null || !propInfo.GetMethod.IsStatic) + if (propInfo?.GetMethod == null || !propInfo.GetMethod.IsStatic) + { return null; + } return () => propInfo.GetValue(null, null); } - } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithBlankImageAttribute.cs b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithBlankImageAttribute.cs index 32278d755..72be5abc2 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithBlankImageAttribute.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithBlankImageAttribute.cs @@ -31,6 +31,7 @@ namespace ImageSharp.Tests /// /// Triggers passing an that produces a blank image of size width * height /// + /// The member data /// The required width /// The required height /// The requested parameter diff --git a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileCollectionAttribute.cs b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileCollectionAttribute.cs index df8f8d090..1b37c45a9 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileCollectionAttribute.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileCollectionAttribute.cs @@ -16,55 +16,62 @@ namespace ImageSharp.Tests /// public class WithFileCollectionAttribute : ImageDataAttributeBase { - private readonly string enumeratorMemberName; + private readonly string fileEnumeratorMemberName; /// /// Triggers passing instances which read an image for each file being enumerated by the (static) test class field/property defined by enumeratorMemberName /// instances will be passed for each the pixel format defined by the pixelTypes parameter /// - /// The name of the static test class field/property enumerating the files + /// The name of the static test class field/property enumerating the files /// The requested pixel types /// Additional theory parameter values public WithFileCollectionAttribute( - string enumeratorMemberName, + string fileEnumeratorMemberName, PixelTypes pixelTypes, params object[] additionalParameters) : base(null, pixelTypes, additionalParameters) { - this.enumeratorMemberName = enumeratorMemberName; + this.fileEnumeratorMemberName = fileEnumeratorMemberName; } - /// + /// /// Triggers passing instances which read an image for each file being enumerated by the (static) test class field/property defined by enumeratorMemberName /// instances will be passed for each the pixel format defined by the pixelTypes parameter /// /// The name of the static test class field/property enumerating the files + /// The member name for enumerating method parameters /// The requested pixel types /// Additional theory parameter values public WithFileCollectionAttribute( string enumeratorMemberName, - string DataMemberName, + string memberName, PixelTypes pixelTypes, params object[] additionalParameters) - : base(DataMemberName, pixelTypes, additionalParameters) + : base(memberName, pixelTypes, additionalParameters) { - this.enumeratorMemberName = enumeratorMemberName; + this.fileEnumeratorMemberName = enumeratorMemberName; } + /// + /// Generates the collection of method arguments from the given test. + /// + /// The test method + /// The test image provider factory type + /// The protected override IEnumerable GetAllFactoryMethodArgs(MethodInfo testMethod, Type factoryType) { Func accessor = this.GetPropertyAccessor(testMethod.DeclaringType); - accessor = accessor ?? this.GetFieldAccessor(testMethod.DeclaringType); - IEnumerable files = (IEnumerable)accessor(); + var files = (IEnumerable)accessor(); return files.Select(f => new object[] { f }); } + /// protected override string GetFactoryMethodName(MethodInfo testMethod) => "File"; /// - /// Based on MemberData implementation + /// Gets the field accessor for the given type. /// private Func GetFieldAccessor(Type type) { @@ -73,17 +80,23 @@ namespace ImageSharp.Tests reflectionType != null; reflectionType = reflectionType.GetTypeInfo().BaseType) { - fieldInfo = reflectionType.GetRuntimeField(this.enumeratorMemberName); - if (fieldInfo != null) break; + fieldInfo = reflectionType.GetRuntimeField(this.fileEnumeratorMemberName); + if (fieldInfo != null) + { + break; + } } - if (fieldInfo == null || !fieldInfo.IsStatic) return null; + if (fieldInfo == null || !fieldInfo.IsStatic) + { + return null; + } return () => fieldInfo.GetValue(null); } /// - /// Based on MemberData implementation + /// Gets the property accessor for the given type. /// private Func GetPropertyAccessor(Type type) { @@ -92,11 +105,14 @@ namespace ImageSharp.Tests reflectionType != null; reflectionType = reflectionType.GetTypeInfo().BaseType) { - propInfo = reflectionType.GetRuntimeProperty(this.enumeratorMemberName); + propInfo = reflectionType.GetRuntimeProperty(this.fileEnumeratorMemberName); if (propInfo != null) break; } - if (propInfo == null || propInfo.GetMethod == null || !propInfo.GetMethod.IsStatic) return null; + if (propInfo?.GetMethod == null || !propInfo.GetMethod.IsStatic) + { + return null; + } return () => propInfo.GetValue(null, null); } diff --git a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithTestPatternImageAttribute.cs b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithTestPatternImageAttribute.cs index 77c60a943..f6ab65f71 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithTestPatternImageAttribute.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithTestPatternImageAttribute.cs @@ -29,6 +29,7 @@ namespace ImageSharp.Tests /// /// Triggers passing an that produces a test pattern image of size width * height /// + /// The member data to apply to theories /// The required width /// The required height /// The requested parameter @@ -40,7 +41,14 @@ namespace ImageSharp.Tests this.Height = height; } + /// + /// Gets the width + /// public int Width { get; } + + /// + /// Gets the height + /// public int Height { get; } protected override string GetFactoryMethodName(MethodInfo testMethod) => "TestPattern"; diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs index 4217d52b0..16eecd2fc 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs @@ -17,8 +17,8 @@ namespace ImageSharp.Tests { private class FileProvider : TestImageProvider, IXunitSerializable { - // Need PixelTypes in the dictionary key, because result images of TestImageProvider.FileProvider - // are shared between PixelTypes.Color & PixelTypes.StandardImageClass + // Need PixelTypes in the dictionary key, because result images of TestImageProvider.FileProvider + // are shared between PixelTypes.Color & PixelTypes.Rgba32 private class Key : Tuple { public Key(PixelTypes item1, string item2) @@ -27,8 +27,7 @@ namespace ImageSharp.Tests } } - private static ConcurrentDictionary> cache = - new ConcurrentDictionary>(); + private static readonly ConcurrentDictionary> cache = new ConcurrentDictionary>(); private string filePath; diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs index bf30d4847..03a685d34 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs @@ -107,12 +107,12 @@ namespace ImageSharp.Tests this.TypeName = typeName; this.MethodName = methodName; - if (pixelTypeOverride == PixelTypes.StandardImageClass) + if (pixelTypeOverride == PixelTypes.Rgba32) { this.Factory = new ImageFactory() as GenericFactory; } - this.Utility = new ImagingTestCaseUtility() + this.Utility = new ImagingTestCaseUtility { SourceFileOrDescription = this.SourceFileOrDescription, PixelTypeName = this.PixelType.ToString() diff --git a/tests/ImageSharp.Tests/TestUtilities/MeasureFixture.cs b/tests/ImageSharp.Tests/TestUtilities/MeasureFixture.cs index 1dadc4884..1a6bf5d8b 100644 --- a/tests/ImageSharp.Tests/TestUtilities/MeasureFixture.cs +++ b/tests/ImageSharp.Tests/TestUtilities/MeasureFixture.cs @@ -1,4 +1,9 @@ -namespace ImageSharp.Tests +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests { using System; using System.Diagnostics; @@ -24,8 +29,12 @@ /// The name of the operation to print to the output public void Measure(int times, Action action, [CallerMemberName] string operationName = null) { - if (this.EnablePrinting) this.Output?.WriteLine($"{operationName} X {times} ..."); - Stopwatch sw = Stopwatch.StartNew(); + if (this.EnablePrinting) + { + this.Output?.WriteLine($"{operationName} X {times} ..."); + } + + var sw = Stopwatch.StartNew(); for (int i = 0; i < times; i++) { @@ -33,7 +42,10 @@ } sw.Stop(); - if (this.EnablePrinting) this.Output?.WriteLine($"{operationName} finished in {sw.ElapsedMilliseconds} ms"); + if (this.EnablePrinting) + { + this.Output?.WriteLine($"{operationName} finished in {sw.ElapsedMilliseconds} ms"); + } } /// diff --git a/tests/ImageSharp.Tests/TestUtilities/PixelTypes.cs b/tests/ImageSharp.Tests/TestUtilities/PixelTypes.cs index f64b77271..5c676d07c 100644 --- a/tests/ImageSharp.Tests/TestUtilities/PixelTypes.cs +++ b/tests/ImageSharp.Tests/TestUtilities/PixelTypes.cs @@ -52,11 +52,6 @@ namespace ImageSharp.Tests Short4 = 1 << 17, - /// - /// Triggers instantiating the subclass of - /// - StandardImageClass = 1 << 29, - // TODO: Add multi-flag entries by rules defined in PackedPixelConverterHelper // "All" is handled as a separate, individual case instead of using bitwise OR diff --git a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs index dbd316423..bb97daaa4 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs @@ -1,35 +1,61 @@ - +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + namespace ImageSharp.Tests { using System; using System.Collections.Generic; using System.Linq; using System.Reflection; - using System.Text; using ImageSharp.PixelFormats; public static class TestImageExtensions { - public static void DebugSave(this Image img, ITestImageProvider provider, object settings = null, string extension = "png") - where TPixel : struct, IPixel + /// + /// Saves the image only when not running in the CI server. + /// + /// The pixel format + /// The image + /// The image provider + /// The settings + /// The extension + public static Image DebugSave(this Image image, ITestImageProvider provider, object settings = null, string extension = "png") + where TPixel : struct, IPixel { + if (bool.TryParse(Environment.GetEnvironmentVariable("CI"), out bool isCi) && isCi) + { + return image; + } + + // We are running locally then we want to save it out string tag = null; - if (settings is string) + string s = settings as string; + + if (s != null) { - tag = (string)settings; + tag = s; } else if (settings != null) { - var properties = settings.GetType().GetRuntimeProperties(); + Type type = settings.GetType(); + TypeInfo info = type.GetTypeInfo(); + if (info.IsPrimitive || info.IsEnum || type == typeof(decimal)) + { + tag = settings.ToString(); + } + else + { + IEnumerable properties = settings.GetType().GetRuntimeProperties(); - tag = string.Join("_", properties.ToDictionary(x => x.Name, x => x.GetValue(settings)).Select(x => $"{x.Key}-{x.Value}")); - } - if(!bool.TryParse(Environment.GetEnvironmentVariable("CI"), out bool isCI) || !isCI) - { - // we are running locally then we want to save it out - provider.Utility.SaveTestOutputFile(img, extension, tag: tag); + tag = string.Join("_", properties.ToDictionary(x => x.Name, x => x.GetValue(settings)).Select(x => $"{x.Key}-{x.Value}")); + } } + + provider.Utility.SaveTestOutputFile(image, extension, tag: tag); + return image; } } } diff --git a/tests/ImageSharp.Tests/TestUtilities/TestUtilityExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestUtilityExtensions.cs index dfaf1c052..e42cbe193 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestUtilityExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestUtilityExtensions.cs @@ -38,14 +38,13 @@ namespace ImageSharp.Tests // Add PixelFormat types string nameSpace = typeof(Alpha8).FullName; nameSpace = nameSpace.Substring(0, nameSpace.Length - typeof(Alpha8).Name.Length - 1); - foreach (PixelTypes pt in AllConcretePixelTypes.Where(pt => pt != PixelTypes.StandardImageClass && pt != PixelTypes.Rgba32)) + foreach (PixelTypes pt in AllConcretePixelTypes.Where(pt => pt != PixelTypes.Rgba32)) { string typeName = $"{nameSpace}.{pt}"; Type t = ImageSharpAssembly.GetType(typeName); PixelTypes2ClrTypes[pt] = t ?? throw new InvalidOperationException($"Could not find: {typeName}"); ClrTypes2PixelTypes[t] = pt; } - PixelTypes2ClrTypes[PixelTypes.StandardImageClass] = defaultPixelFormatType; } public static bool HasFlag(this PixelTypes pixelTypes, PixelTypes flag) => (pixelTypes & flag) == flag; @@ -106,6 +105,11 @@ namespace ImageSharp.Tests public static Type ToType(this PixelTypes pixelType) => PixelTypes2ClrTypes[pixelType]; + /// + /// Returns the enumerations for the given type. + /// + /// + /// public static PixelTypes GetPixelType(this Type colorStructClrType) => ClrTypes2PixelTypes[colorStructClrType]; public static IEnumerable> ExpandAllTypes(this PixelTypes pixelTypes) diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs index 4d3a0d991..6bd5b392d 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs @@ -50,7 +50,7 @@ namespace ImageSharp.Tests [Theory] [WithBlankImages(1, 1, PixelTypes.Rgba32, PixelTypes.Rgba32)] [WithBlankImages(1, 1, PixelTypes.Alpha8, PixelTypes.Alpha8)] - [WithBlankImages(1, 1, PixelTypes.StandardImageClass, PixelTypes.StandardImageClass)] + [WithBlankImages(1, 1, PixelTypes.Rgba32, PixelTypes.Rgba32)] public void PixelType_PropertyValueIsCorrect(TestImageProvider provider, PixelTypes expected) where TPixel : struct, IPixel { @@ -58,8 +58,8 @@ namespace ImageSharp.Tests } [Theory] - [WithBlankImages(1, 1, PixelTypes.StandardImageClass)] - [WithFile(TestImages.Bmp.F, PixelTypes.StandardImageClass)] + [WithBlankImages(1, 1, PixelTypes.Rgba32)] + [WithFile(TestImages.Bmp.F, PixelTypes.Rgba32)] public void PixelTypes_ColorWithDefaultImageClass_TriggersCreatingTheNonGenericDerivedImageClass( TestImageProvider provider) where TPixel : struct, IPixel @@ -144,7 +144,7 @@ namespace ImageSharp.Tests { Image img = provider.GetImage(); Assert.Equal(img.Width, 3); - if (provider.PixelType == PixelTypes.StandardImageClass) + if (provider.PixelType == PixelTypes.Rgba32) { Assert.IsType>(img); } diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs index 9ff0ca64e..a35c73aef 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs @@ -89,7 +89,7 @@ namespace ImageSharp.Tests [InlineData(PixelTypes.Rgba32, typeof(Rgba32))] [InlineData(PixelTypes.Argb32, typeof(Argb32))] [InlineData(PixelTypes.HalfVector4, typeof(HalfVector4))] - [InlineData(PixelTypes.StandardImageClass, typeof(Rgba32))] + [InlineData(PixelTypes.Rgba32, typeof(Rgba32))] public void ToType(PixelTypes pt, Type expectedType) { Assert.Equal(pt.ToType(), expectedType); @@ -114,17 +114,16 @@ namespace ImageSharp.Tests [Fact] public void ToTypes() { - PixelTypes pixelTypes = PixelTypes.Alpha8 | PixelTypes.Bgr565 | PixelTypes.Rgba32 | PixelTypes.HalfVector2 | PixelTypes.StandardImageClass; + PixelTypes pixelTypes = PixelTypes.Alpha8 | PixelTypes.Bgr565 | PixelTypes.HalfVector2 | PixelTypes.Rgba32; IEnumerable> expanded = pixelTypes.ExpandAllTypes(); - Assert.Equal(expanded.Count(), 5); + Assert.Equal(expanded.Count(), 4); AssertContainsPixelType(PixelTypes.Alpha8, expanded); AssertContainsPixelType(PixelTypes.Bgr565, expanded); - AssertContainsPixelType(PixelTypes.Rgba32, expanded); AssertContainsPixelType(PixelTypes.HalfVector2, expanded); - AssertContainsPixelType(PixelTypes.StandardImageClass, expanded); + AssertContainsPixelType(PixelTypes.Rgba32, expanded); } [Fact] @@ -134,7 +133,7 @@ namespace ImageSharp.Tests Assert.True(expanded.Length >= TestUtilityExtensions.GetAllPixelTypes().Length - 2); AssertContainsPixelType(PixelTypes.Rgba32, expanded); - AssertContainsPixelType(PixelTypes.StandardImageClass, expanded); + AssertContainsPixelType(PixelTypes.Rgba32, expanded); } } }