Browse Source

One method to rule them all.

Former-commit-id: 0410a102603bdf7911fc5f02a5b660540a45b525
Former-commit-id: c6d66869a91cd30afae4ae28993716fa67a9c1f4
Former-commit-id: 31b7fdd178103ba89133976d86788e5c4de6f20c
pull/17/head
James Jackson-South 10 years ago
parent
commit
2ee0e8bbe6
  1. 9
      src/ImageProcessor/Filters/Contrast.cs
  2. 29
      src/ImageProcessor/IImageProcessor.cs
  3. 44
      src/ImageProcessor/ImageExtensions.cs
  4. 3
      src/ImageProcessor/ImageProcessor.csproj
  5. 33
      src/ImageProcessor/ParallelImageProcessor.cs
  6. 4
      src/ImageProcessor/Samplers/Lanczos5Resampler.cs
  7. 24
      src/ImageProcessor/Samplers/Resize.cs
  8. 63
      tests/ImageProcessor.Tests/Formats/EncoderDecoderTests.cs
  9. 7
      tests/ImageProcessor.Tests/ImageProcessor.Tests.csproj
  10. 7
      tests/ImageProcessor.Tests/ImageProcessor.Tests.csproj.DotSettings
  11. 16
      tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs
  12. 63
      tests/ImageProcessor.Tests/Processors/Formats/EncoderDecoderTests.cs
  13. 32
      tests/ImageProcessor.Tests/Processors/ProcessorTestBase.cs
  14. 27
      tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs
  15. BIN
      tests/ImageProcessor.Tests/TestImages/Formats/Gif/a.gif

9
src/ImageProcessor/Filters/Contrast.cs

@ -30,19 +30,14 @@ namespace ImageProcessor.Filters
/// </summary>
public int Value { get; }
protected override void Apply(ImageBase source, ImageBase target, Rectangle sourceRectangle, Rectangle targetRectangle, int startY, int endY)
{
throw new NotImplementedException();
}
/// <inheritdoc/>
protected override void Apply(ImageBase target, ImageBase source, Rectangle rectangle, int startY, int endY)
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
double contrast = (100.0 + this.Value) / 100.0;
for (int y = startY; y < endY; y++)
{
for (int x = rectangle.X; x < rectangle.Right; x++)
for (int x = sourceRectangle.X; x < sourceRectangle.Right; x++)
{
Bgra color = source[x, y];

29
src/ImageProcessor/IImageProcessor.cs

@ -11,12 +11,12 @@ namespace ImageProcessor
public interface IImageProcessor
{
/// <summary>
/// Apply a process to an image to alter the pixels at the area of the specified rectangle.
/// Applies the process to the specified portion of the specified <see cref="ImageBase"/>.
/// </summary>
/// <param name="target">Target image to apply the process to.</param>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="rectangle">
/// The rectangle, which defines the area of the image where the process should be applied to.
/// <param name="sourceRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
/// </param>
/// <remarks>
/// The method keeps the source image unchanged and returns the
@ -26,10 +26,29 @@ namespace ImageProcessor
/// <paramref name="target"/> is null or <paramref name="source"/> is null.
/// </exception>
/// <exception cref="System.ArgumentException">
/// <paramref name="rectangle"/> doesnt fit the dimension of the image.
/// <paramref name="sourceRectangle"/> doesnt fit the dimension of the image.
/// </exception>
void Apply(ImageBase target, ImageBase source, Rectangle rectangle);
void Apply(ImageBase target, ImageBase source, Rectangle sourceRectangle);
/// <summary>
/// Applies the process to the specified portion of the specified <see cref="ImageBase"/> at the specified
/// location and with the specified size.
/// </summary>
/// <param name="target">Target image to apply the process to.</param>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="width">The target width.</param>
/// <param name="height">The target height.</param>
/// <param name="targetRectangle">
/// The <see cref="Rectangle"/> structure that specifies the location and size of the drawn image.
/// The image is scaled to fit the rectangle.
/// </param>
/// <param name="sourceRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
/// </param>
/// <remarks>
/// The method keeps the source image unchanged and returns the
/// the result of image process as new image.
/// </remarks>
void Apply(ImageBase target, ImageBase source, int width, int height, Rectangle targetRectangle, Rectangle sourceRectangle);
}
}

44
src/ImageProcessor/ImageExtensions.cs

@ -55,22 +55,26 @@ namespace ImageProcessor
/// <param name="source">The image this method extends.</param>
/// <param name="processors">Any processors to apply to the image.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Process(this Image source, params IImageProcessor[] processors) => Process(source, source.Bounds, processors);
public static Image Process(this Image source, params IImageProcessor[] processors)
{
return Process(source, source.Bounds, processors);
}
/// <summary>
/// Applies the collection of processors to the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="rectangle">
/// The rectangle defining the bounds of the pixels the image filter with adjust.</param>
/// <param name="sourceRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
/// </param>
/// <param name="processors">Any processors to apply to the image.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Process(this Image source, Rectangle rectangle, params IImageProcessor[] processors)
public static Image Process(this Image source, Rectangle sourceRectangle, params IImageProcessor[] processors)
{
// ReSharper disable once LoopCanBeConvertedToQuery
foreach (IImageProcessor filter in processors)
{
source = PerformAction(source, true, (sourceImage, targetImage) => filter.Apply(targetImage, sourceImage, rectangle));
source = PerformAction(source, true, (sourceImage, targetImage) => filter.Apply(targetImage, sourceImage, sourceRectangle));
}
return source;
@ -79,13 +83,29 @@ namespace ImageProcessor
/// <summary>
/// Applies the collection of processors to the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="rectangle">
/// The rectangle defining the bounds of the pixels the image filter with adjust.</param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="sourceRectangle"></param>
/// <param name="targetRectangle"></param>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image width.</param>
/// <param name="processors">Any processors to apply to the image.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Process(this Image source, int width, int height, params IImageProcessor[] processors)
{
return Process(source, width, height, source.Bounds, default(Rectangle), processors);
}
/// <summary>
/// Applies the collection of processors to the image.
/// </summary>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image width.</param>
/// <param name="sourceRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
/// </param>
/// <param name="targetRectangle">
/// The <see cref="Rectangle"/> structure that specifies the location and size of the drawn image.
/// The image is scaled to fit the rectangle.
/// </param>
/// <param name="processors">Any processors to apply to the image.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Process(this Image source, int width, int height, Rectangle sourceRectangle, Rectangle targetRectangle, params IImageProcessor[] processors)

3
src/ImageProcessor/ImageProcessor.csproj

@ -180,7 +180,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Numerics\Rectangle.cs" />
<Compile Include="Numerics\Size.cs" />
<Compile Include="Samplers\Lanczos3Resampler.cs" />
<Compile Include="Samplers\Lanczos5Resampler.cs" />
<Compile Include="Samplers\BicubicResampler.cs" />
<Compile Include="Samplers\ImageSampleExtensions.cs" />
<Compile Include="Samplers\IResampler.cs" />
@ -196,6 +196,7 @@
<None Include="Formats\Gif\README.md" />
<None Include="Formats\Jpg\README.md" />
<None Include="packages.config" />
<AdditionalFiles Include="stylecop.json" />
</ItemGroup>
<ItemGroup>
<None Include="Formats\Bmp\README.md" />

33
src/ImageProcessor/ParallelImageProcessor.cs

@ -19,7 +19,7 @@ namespace ImageProcessor
public int Parallelism { get; set; } = Environment.ProcessorCount;
/// <inheritdoc/>
public void Apply(ImageBase target, ImageBase source, Rectangle rectangle)
public void Apply(ImageBase target, ImageBase source, Rectangle sourceRectangle)
{
this.OnApply();
@ -34,11 +34,11 @@ namespace ImageProcessor
int current = p;
tasks[p] = Task.Run(() =>
{
int batchSize = rectangle.Height / partitionCount;
int yStart = rectangle.Y + (current * batchSize);
int yEnd = current == partitionCount - 1 ? rectangle.Bottom : yStart + batchSize;
int batchSize = sourceRectangle.Height / partitionCount;
int yStart = sourceRectangle.Y + (current * batchSize);
int yEnd = current == partitionCount - 1 ? sourceRectangle.Bottom : yStart + batchSize;
this.Apply(target, source, rectangle, yStart, yEnd);
this.Apply(target, source, target.Bounds, sourceRectangle, yStart, yEnd);
});
}
@ -46,7 +46,7 @@ namespace ImageProcessor
}
else
{
this.Apply(target, source, rectangle, rectangle.Y, rectangle.Bottom);
this.Apply(target, source, target.Bounds, sourceRectangle, sourceRectangle.Y, sourceRectangle.Bottom);
}
}
@ -102,22 +102,25 @@ namespace ImageProcessor
{
}
protected abstract void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY);
/// <summary>
/// Apply a process to an image to alter the pixels at the area of the specified rectangle.
/// Applies the process to the specified portion of the specified <see cref="ImageBase"/> at the specified location
/// and with the specified size.
/// </summary>
/// <param name="target">Target image to apply the process to.</param>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="rectangle">
/// The rectangle, which defines the area of the image where the process should be applied to.
/// <param name="targetRectangle">
/// The <see cref="Rectangle"/> structure that specifies the location and size of the drawn image.
/// The image is scaled to fit the rectangle.
/// </param>
/// <param name="startY">The index of the row within the image to start processing.</param>
/// <param name="endY">The index of the row within the image to end processing.</param>
/// <param name="sourceRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
/// </param>
/// <param name="startY">The index of the row within the source image to start processing.</param>
/// <param name="endY">The index of the row within the source image to end processing.</param>
/// <remarks>
/// The method keeps the source image unchanged and returns the
/// the result of image processing filter as new image.
/// the result of image process as new image.
/// </remarks>
protected abstract void Apply(ImageBase target, ImageBase source, Rectangle rectangle, int startY, int endY);
protected abstract void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY);
}
}

4
src/ImageProcessor/Samplers/Lanczos3Resampler.cs → src/ImageProcessor/Samplers/Lanczos5Resampler.cs

@ -9,10 +9,10 @@ namespace ImageProcessor.Samplers
/// The function implements the Lanczos kernel algorithm as described on
/// <see href="https://en.wikipedia.org/wiki/Lanczos_resampling#Algorithm">Wikipedia</see>
/// </summary>
public class Lanczos3Resampler : IResampler
public class Lanczos5Resampler : IResampler
{
/// <inheritdoc/>
public double Radius => 3;
public double Radius => 5;
/// <inheritdoc/>
public double GetValue(double x)

24
src/ImageProcessor/Samplers/Resize.cs

@ -1,7 +1,15 @@
using System;
// <copyright file="Resize.cs" company="James South">
// Copyright © James South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageProcessor.Samplers
{
using System;
/// <summary>
/// Provides methods that allow the resizing of images using various resampling algorithms.
/// </summary>
public class Resize : ParallelImageProcessor
{
/// <summary>
@ -23,13 +31,7 @@ namespace ImageProcessor.Samplers
public IResampler Sampler { get; }
/// <inheritdoc/>
protected override void Apply(
ImageBase target,
ImageBase source,
Rectangle targetRectangle,
Rectangle sourceRectangle,
int startY,
int endY)
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
int sourceWidth = source.Width;
int sourceHeight = source.Height;
@ -126,11 +128,5 @@ namespace ImageProcessor.Samplers
}
}
}
/// <inheritdoc/>
protected override void Apply(ImageBase target, ImageBase source, Rectangle rectangle, int startY, int endY)
{
throw new NotImplementedException();
}
}
}

63
tests/ImageProcessor.Tests/Formats/EncoderDecoderTests.cs

@ -1,63 +0,0 @@
namespace ImageProcessor.Tests
{
using System.Diagnostics;
using System.IO;
using Formats;
using Xunit;
public class EncoderDecoderTests
{
[Theory]
[InlineData("../../TestImages/Formats/Jpg/Backdrop.jpg")]
[InlineData("../../TestImages/Formats/Gif/a.gif")]
[InlineData("../../TestImages/Formats/Gif/leaf.gif")]
[InlineData("../../TestImages/Formats/Gif/ani.gif")]
[InlineData("../../TestImages/Formats/Gif/ani2.gif")]
[InlineData("../../TestImages/Formats/Gif/giphy.gif")]
[InlineData("../../TestImages/Formats/Bmp/Car.bmp")]
[InlineData("../../TestImages/Formats/Png/cmyk.png")]
public void DecodeThenEncodeImageFromStreamShouldSucceed(string filename)
{
if (!Directory.Exists("Encoded"))
{
Directory.CreateDirectory("Encoded");
}
FileStream stream = File.OpenRead(filename);
Stopwatch watch = Stopwatch.StartNew();
Image image = new Image(stream);
string encodedFilename = "Encoded/" + Path.GetFileName(filename);
using (FileStream output = File.OpenWrite(encodedFilename))
{
image.Save(output);
}
Trace.WriteLine($"{filename} : {watch.ElapsedMilliseconds}ms");
}
[Theory]
[InlineData("../../TestImages/Formats/Jpg/Backdrop.jpg")]
[InlineData("../../TestImages/Formats/Bmp/Car.bmp")]
[InlineData("../../TestImages/Formats/Png/cmyk.png")]
public void QuantizedImageShouldPreserveMaximumColorPrecision(string filename)
{
if (!Directory.Exists("Quantized"))
{
Directory.CreateDirectory("Quantized");
}
Image image = new Image(File.OpenRead(filename));
IQuantizer quantizer = new OctreeQuantizer();
QuantizedImage quantizedImage = quantizer.Quantize(image);
using (FileStream output = File.OpenWrite($"Quantized/{ Path.GetFileName(filename) }"))
{
quantizedImage.ToImage().Save(output);
}
}
}
}

7
tests/ImageProcessor.Tests/ImageProcessor.Tests.csproj

@ -53,14 +53,15 @@
<ItemGroup>
<Compile Include="Colors\ColorConversionTests.cs" />
<Compile Include="Colors\ColorTests.cs" />
<Compile Include="Filters\FilterTests.cs" />
<Compile Include="Formats\EncoderDecoderTests.cs" />
<Compile Include="Processors\Filters\FilterTests.cs" />
<Compile Include="Processors\Formats\EncoderDecoderTests.cs" />
<Compile Include="Helpers\GuardTests.cs" />
<Compile Include="Numerics\RectangleTests.cs" />
<Compile Include="Numerics\PointTests.cs" />
<Compile Include="Numerics\SizeTests.cs" />
<Compile Include="Processors\ProcessorTestBase.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Samplers\SamplerTests.cs" />
<Compile Include="Processors\Samplers\SamplerTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

7
tests/ImageProcessor.Tests/ImageProcessor.Tests.csproj.DotSettings

@ -1,4 +1,9 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=colors/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=formats/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=numerics/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=helpers/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=numerics/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=processors/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=processors_005Cfilters/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=processors_005Cformats/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=processors_005Csamplers/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

16
tests/ImageProcessor.Tests/Filters/FilterTests.cs → tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs

@ -1,5 +1,5 @@

namespace ImageProcessor.Tests.Filters
namespace ImageProcessor.Tests
{
using System.Collections.Generic;
using System.Diagnostics;
@ -10,20 +10,8 @@ namespace ImageProcessor.Tests.Filters
using Xunit;
public class FilterTests
public class FilterTests : ProcessorTestBase
{
public static readonly List<string> Files = new List<string>
{
//{ "../../TestImages/Formats/Jpg/Backdrop.jpg"},
//{ "../../TestImages/Formats/Bmp/Car.bmp" },
//{ "../../TestImages/Formats/Png/cmyk.png" },
//{ "../../TestImages/Formats/Gif/a.gif" },
//{ "../../TestImages/Formats/Gif/leaf.gif" },
{ "../../TestImages/Formats/Gif/ani.gif" },
//{ "../../TestImages/Formats/Gif/ani2.gif" },
//{ "../../TestImages/Formats/Gif/giphy.gif" },
};
public static readonly TheoryData<string, IImageProcessor> Filters = new TheoryData<string, IImageProcessor>
{
{ "Contrast-50", new Contrast(50) },

63
tests/ImageProcessor.Tests/Processors/Formats/EncoderDecoderTests.cs

@ -0,0 +1,63 @@
namespace ImageProcessor.Tests
{
using System.Diagnostics;
using System.IO;
using Formats;
using Xunit;
public class EncoderDecoderTests : ProcessorTestBase
{
[Fact]
public void DecodeThenEncodeImageFromStreamShouldSucceed()
{
if (!Directory.Exists("Encoded"))
{
Directory.CreateDirectory("Encoded");
}
foreach (string file in Files)
{
using (FileStream stream = File.OpenRead(file))
{
Stopwatch watch = Stopwatch.StartNew();
Image image = new Image(stream);
string encodedFilename = "Encoded/" + Path.GetFileName(file);
using (FileStream output = File.OpenWrite(encodedFilename))
{
image.Save(output);
}
Trace.WriteLine($"{file} : {watch.ElapsedMilliseconds}ms");
}
}
}
[Fact]
public void QuantizedImageShouldPreserveMaximumColorPrecision()
{
if (!Directory.Exists("Quantized"))
{
Directory.CreateDirectory("Quantized");
}
foreach (string file in Files)
{
using (FileStream stream = File.OpenRead(file))
{
Image image = new Image(stream);
IQuantizer quantizer = new OctreeQuantizer();
QuantizedImage quantizedImage = quantizer.Quantize(image);
using (FileStream output = File.OpenWrite($"Quantized/{Path.GetFileName(file)}"))
{
quantizedImage.ToImage().Save(output);
}
}
}
}
}
}

32
tests/ImageProcessor.Tests/Processors/ProcessorTestBase.cs

@ -0,0 +1,32 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ProcessorTestBase.cs" company="James South">
// Copyright © James South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Tests
{
using System.Collections.Generic;
/// <summary>
/// The processor test base.
/// </summary>
public abstract class ProcessorTestBase
{
/// <summary>
/// The collection of image files to test against.
/// </summary>
public static readonly List<string> Files = new List<string>
{
"../../TestImages/Formats/Jpg/Backdrop.jpg",
"../../TestImages/Formats/Bmp/Car.bmp",
"../../TestImages/Formats/Png/cmyk.png",
"../../TestImages/Formats/Gif/leaf.gif"
// { "../../TestImages/Formats/Gif/ani.gif" },
// { "../../TestImages/Formats/Gif/ani2.gif" },
// { "../../TestImages/Formats/Gif/giphy.gif" },
};
}
}

27
tests/ImageProcessor.Tests/Samplers/SamplerTests.cs → tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs

@ -1,38 +1,25 @@

namespace ImageProcessor.Tests.Filters
namespace ImageProcessor.Tests
{
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using Samplers;
using ImageProcessor.Samplers;
using Xunit;
public class SamplerTests
public class SamplerTests : ProcessorTestBase
{
public static readonly List<string> Files = new List<string>
{
{ "../../TestImages/Formats/Jpg/Backdrop.jpg" },
{ "../../TestImages/Formats/Bmp/Car.bmp" },
{ "../../TestImages/Formats/Png/cmyk.png" },
//{ "../../TestImages/Formats/Gif/a.gif" },
{ "../../TestImages/Formats/Gif/leaf.gif" },
//{ "../../TestImages/Formats/Gif/ani.gif" },
//{ "../../TestImages/Formats/Gif/ani2.gif" },
//{ "../../TestImages/Formats/Gif/giphy.gif" },
};
public static readonly TheoryData<string, IResampler> Samplers =
new TheoryData<string, IResampler>
{
{ "Bicubic", new BicubicResampler() },
{ "Lanczos3", new Lanczos3Resampler() }
//{ "Lanczos3", new Lanczos5Resampler() }
};
[Theory]
[MemberData("Samplers")]
public void ResizeImage(string name, IResampler sampler)
public void ImageShouldResize(string name, IResampler sampler)
{
if (!Directory.Exists("Resized"))
{
@ -48,7 +35,7 @@ namespace ImageProcessor.Tests.Filters
string filename = Path.GetFileNameWithoutExtension(file) + "-" + name + Path.GetExtension(file);
using (FileStream output = File.OpenWrite($"Resized/{filename}"))
{
image.Resize(900, 900, sampler).Save(output);
image.Resize(500, 500, sampler).Save(output);
}
Trace.WriteLine($"{name}: {watch.ElapsedMilliseconds}ms");
@ -65,7 +52,7 @@ namespace ImageProcessor.Tests.Filters
[InlineData(2, 0)]
public static void Lanczos3WindowOscillatesCorrectly(double x, double expected)
{
Lanczos3Resampler sampler = new Lanczos3Resampler();
Lanczos5Resampler sampler = new Lanczos5Resampler();
double result = sampler.GetValue(x);
Assert.Equal(result, expected);

BIN
tests/ImageProcessor.Tests/TestImages/Formats/Gif/a.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 B

Loading…
Cancel
Save