diff --git a/README.md b/README.md index d2e251b41..e8e05ae90 100644 --- a/README.md +++ b/README.md @@ -51,13 +51,14 @@ git clone https://github.com/JimBobSquarePants/ImageProcessor ###What works so far/ What is planned? - Encoding/decoding of image formats (plugable), progressive required - - [x] jpeg (Includes Subsampling, Progressive required) - - [x] bmp (More bmp format saving support required, 24bit just now) - - [x] png (Need updating for saving indexed support) - - [x] gif + - [x] Jpeg (Includes Subsampling. Progressive writing required) + - [x] Bmp (Read: 32bit, 24bit, 16 bit. Write: 32bit, 24bit just now) + - [x] Png (Read: TrueColor, Grayscale, Indexed. Write: True color, Indexed just now) + - [x] Gif (Includes animated) + - [ ] Tiff - Quantizers (IQuantizer with alpha channel support + thresholding) - [x] Octree - - [x] Wu + - [x] Xiaolin Wu - [x] Palette - Basic color structs with implicit operators. Vector backed. [#260](https://github.com/JimBobSquarePants/ImageProcessor/issues/260) - [x] Color - Float based, premultiplied alpha, No limit to r, g, b, a values allowing for a fuller color range. @@ -68,8 +69,8 @@ git clone https://github.com/JimBobSquarePants/ImageProcessor - [x] HSV - [x] HSL - [x] YCbCr -- Basic shape primitives (Unfinished and could possible be updated by using Vector2, Vector3, etc) - - [x] Rectangle +- Basic shape primitives (Vector backed) + - [x] Rectangle (Doesn't contain all System.Drawing methods) - [x] Size - [x] Point - [x] Ellipse @@ -122,7 +123,7 @@ git clone https://github.com/JimBobSquarePants/ImageProcessor - [x] RobertsCross - [x] Scharr - [x] Sobel -- Blurring/ Sharpening +- Blurring/Sharpening - [x] Gaussian blur - [x] Gaussian sharpening - [x] Box Blur @@ -143,10 +144,11 @@ git clone https://github.com/JimBobSquarePants/ImageProcessor - [ ] Pattern brush (Need help) [#264](https://github.com/JimBobSquarePants/ImageProcessor/issues/264) - [ ] Elliptical brush (Need help) [#264](https://github.com/JimBobSquarePants/ImageProcessor/issues/264) - [ ] Gradient brush (vignette? Need help) [#264](https://github.com/JimBobSquarePants/ImageProcessor/issues/264) +- Metadata + - [ ] EXIF (In progress but there's a lot of quirks in parsing EXIF. [#78](https://github.com/JimBobSquarePants/ImageProcessor/issues/78)) - Other stuff I haven't thought of. ###What might never happen -- Exif manipulation - There's a lot of quirks in parsing EXIF and I'd need a ton of help to get it all coded. [#78](https://github.com/JimBobSquarePants/ImageProcessor/issues/78) - Font support (Depends on new System.Text stuff) I don't know where to start coding this so if you have any pointers please chip in. ###API Changes diff --git a/src/ImageProcessorCore/Formats/Bmp/BmpBitsPerPixel.cs b/src/ImageProcessorCore/Formats/Bmp/BmpBitsPerPixel.cs new file mode 100644 index 000000000..e7de3bc29 --- /dev/null +++ b/src/ImageProcessorCore/Formats/Bmp/BmpBitsPerPixel.cs @@ -0,0 +1,23 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageProcessorCore.Formats +{ + /// + /// Enumerates the available bits per pixel for bitmap. + /// + public enum BmpBitsPerPixel + { + /// + /// 24 bits per pixel. Each pixel consists of 3 bytes. + /// + Pixel24 = 3, + + /// + /// 32 bits per pixel. Each pixel consists of 4 bytes. + /// + Pixel32 = 4, + } +} diff --git a/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs b/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs index 6ee30900d..55ec63f8c 100644 --- a/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs @@ -12,7 +12,7 @@ namespace ImageProcessorCore.Formats /// /// Performs the bmp decoding operation. /// - internal class BmpDecoderCore + internal sealed class BmpDecoderCore { /// /// The mask for the red part of the color for 16 bit rgb bitmaps. diff --git a/src/ImageProcessorCore/Formats/Bmp/BmpEncoder.cs b/src/ImageProcessorCore/Formats/Bmp/BmpEncoder.cs index 1080daf0e..944154df2 100644 --- a/src/ImageProcessorCore/Formats/Bmp/BmpEncoder.cs +++ b/src/ImageProcessorCore/Formats/Bmp/BmpEncoder.cs @@ -26,6 +26,11 @@ namespace ImageProcessorCore.Formats /// public string Extension => "bmp"; + /// + /// Gets or sets the number of bits per pixel. + /// + public BmpBitsPerPixel BitsPerPixel { get; set; } = BmpBitsPerPixel.Pixel24; + /// public bool IsSupportedFileExtension(string extension) { @@ -40,127 +45,8 @@ namespace ImageProcessorCore.Formats /// public void Encode(ImageBase image, Stream stream) { - Guard.NotNull(image, nameof(image)); - Guard.NotNull(stream, nameof(stream)); - - int rowWidth = image.Width; - - int amount = (image.Width * 3) % 4; - if (amount != 0) - { - rowWidth += 4 - amount; - } - - using (BinaryWriter writer = new BinaryWriter(stream)) - { - BmpFileHeader fileHeader = new BmpFileHeader - { - Type = 19778, // BM - Offset = 54, - FileSize = 54 + (image.Height * rowWidth * 3) - }; - - WriteHeader(writer, fileHeader); - - BmpInfoHeader infoHeader = new BmpInfoHeader - { - HeaderSize = 40, - Height = image.Height, - Width = image.Width, - BitsPerPixel = 24, - Planes = 1, - Compression = BmpCompression.RGB, - ImageSize = image.Height * rowWidth * 3, - ClrUsed = 0, - ClrImportant = 0 - }; - - WriteInfo(writer, infoHeader); - - this.WriteImage(writer, image); - - writer.Flush(); - } - } - - /// - /// Writes the pixel data to the binary stream. - /// - /// - /// The containing the stream to write to. - /// - /// - /// The containing pixel data. - /// - private void WriteImage(BinaryWriter writer, ImageBase image) - { - // TODO: Add more compression formats. - int amount = (image.Width * 3) % 4; - if (amount != 0) - { - amount = 4 - amount; - } - - for (int y = image.Height - 1; y >= 0; y--) - { - for (int x = 0; x < image.Width; x++) - { - // Limit the output range and multiply out from our floating point. - // Convert back to b-> g-> r-> a order. - // Convert to non-premultiplied color. - Bgra32 color = Color.ToNonPremultiplied(image[x, y]); - - // Allocate 1 array instead of allocating 3. - writer.Write(new[] { color.B, color.G, color.R }); - } - - // Pad - for (int i = 0; i < amount; i++) - { - writer.Write((byte)0); - } - } - } - - /// - /// Writes the bitmap header data to the binary stream. - /// - /// - /// The containing the stream to write to. - /// - /// - /// The containing the header data. - /// - private static void WriteHeader(BinaryWriter writer, BmpFileHeader fileHeader) - { - writer.Write(fileHeader.Type); - writer.Write(fileHeader.FileSize); - writer.Write(fileHeader.Reserved); - writer.Write(fileHeader.Offset); - } - - /// - /// Writes the bitmap information to the binary stream. - /// - /// - /// The containing the stream to write to. - /// - /// - /// The containing the detailed information about the image. - /// - private static void WriteInfo(BinaryWriter writer, BmpInfoHeader infoHeader) - { - writer.Write(infoHeader.HeaderSize); - writer.Write(infoHeader.Width); - writer.Write(infoHeader.Height); - writer.Write(infoHeader.Planes); - writer.Write(infoHeader.BitsPerPixel); - writer.Write((int)infoHeader.Compression); - writer.Write(infoHeader.ImageSize); - writer.Write(infoHeader.XPelsPerMeter); - writer.Write(infoHeader.YPelsPerMeter); - writer.Write(infoHeader.ClrUsed); - writer.Write(infoHeader.ClrImportant); + BmpEncoderCore encoder = new BmpEncoderCore(); + encoder.Encode(image, stream, this.BitsPerPixel); } } } diff --git a/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs b/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs new file mode 100644 index 000000000..0c1e740af --- /dev/null +++ b/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs @@ -0,0 +1,205 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageProcessorCore.Formats +{ + using System; + using System.IO; + + using ImageProcessorCore.IO; + + /// + /// Image encoder for writing an image to a stream as a Windows bitmap. + /// + /// The encoder can currently only write 24-bit rgb images to streams. + internal sealed class BmpEncoderCore + { + /// + /// The number of bits per pixel. + /// + private BmpBitsPerPixel bmpBitsPerPixel; + + /// + /// Encodes the image to the specified stream from the . + /// + /// The to encode from. + /// The to encode the image data to. + /// The + public void Encode(ImageBase image, Stream stream, BmpBitsPerPixel bitsPerPixel) + { + Guard.NotNull(image, nameof(image)); + Guard.NotNull(stream, nameof(stream)); + + this.bmpBitsPerPixel = bitsPerPixel; + + int rowWidth = image.Width; + + int amount = (image.Width * (int)this.bmpBitsPerPixel) % 4; + if (amount != 0) + { + rowWidth += 4 - amount; + } + + using (EndianBinaryWriter writer = new EndianBinaryWriter(EndianBitConverter.Little, stream)) + { + int bpp = (int)this.bmpBitsPerPixel; + + BmpFileHeader fileHeader = new BmpFileHeader + { + Type = 19778, // BM + Offset = 54, + FileSize = 54 + (image.Height * rowWidth * bpp) + }; + + BmpInfoHeader infoHeader = new BmpInfoHeader + { + HeaderSize = 40, + Height = image.Height, + Width = image.Width, + BitsPerPixel = (short)(8 * bpp), + Planes = 1, + ImageSize = image.Height * rowWidth * bpp, + ClrUsed = 0, + ClrImportant = 0 + }; + + WriteHeader(writer, fileHeader); + this.WriteInfo(writer, infoHeader); + this.WriteImage(writer, image); + + writer.Flush(); + } + } + + /// + /// Writes the bitmap header data to the binary stream. + /// + /// + /// The containing the stream to write to. + /// + /// + /// The containing the header data. + /// + private static void WriteHeader(EndianBinaryWriter writer, BmpFileHeader fileHeader) + { + writer.Write(fileHeader.Type); + writer.Write(fileHeader.FileSize); + writer.Write(fileHeader.Reserved); + writer.Write(fileHeader.Offset); + } + + /// + /// Writes the bitmap information to the binary stream. + /// + /// + /// The containing the stream to write to. + /// + /// + /// The containing the detailed information about the image. + /// + private void WriteInfo(EndianBinaryWriter writer, BmpInfoHeader infoHeader) + { + writer.Write(infoHeader.HeaderSize); + writer.Write(infoHeader.Width); + writer.Write(infoHeader.Height); + writer.Write(infoHeader.Planes); + writer.Write(infoHeader.BitsPerPixel); + writer.Write((int)infoHeader.Compression); + writer.Write(infoHeader.ImageSize); + writer.Write(infoHeader.XPelsPerMeter); + writer.Write(infoHeader.YPelsPerMeter); + writer.Write(infoHeader.ClrUsed); + writer.Write(infoHeader.ClrImportant); + } + + /// + /// Writes the pixel data to the binary stream. + /// + /// + /// The containing the stream to write to. + /// + /// + /// The containing pixel data. + /// + private void WriteImage(EndianBinaryWriter writer, ImageBase image) + { + // TODO: Add more compression formats. + int amount = (image.Width * (int)this.bmpBitsPerPixel) % 4; + if (amount != 0) + { + amount = 4 - amount; + } + + switch (this.bmpBitsPerPixel) + { + case BmpBitsPerPixel.Pixel32: + this.Write32bit(writer, image, amount); + break; + + case BmpBitsPerPixel.Pixel24: + this.Write24bit(writer, image, amount); + break; + } + } + + /// + /// Writes the 32bit color palette to the stream. + /// + /// The containing the stream to write to. + /// The containing pixel data. + /// The amount to pad each row by. + private void Write32bit(EndianBinaryWriter writer, ImageBase image, int amount) + { + for (int y = image.Height - 1; y >= 0; y--) + { + for (int x = 0; x < image.Width; x++) + { + // Limit the output range and multiply out from our floating point. + // Convert back to b-> g-> r-> a order. + // Convert to non-premultiplied color. + Bgra32 color = Color.ToNonPremultiplied(image[x, y]); + + // We can take advantage of BGRA here + writer.Write(color.Bgra); + } + + // Pad + for (int i = 0; i < amount; i++) + { + writer.Write((byte)0); + } + } + } + + /// + /// Writes the 24bit color palette to the stream. + /// + /// The containing the stream to write to. + /// The containing pixel data. + /// The amount to pad each row by. + private void Write24bit(EndianBinaryWriter writer, ImageBase image, int amount) + { + for (int y = image.Height - 1; y >= 0; y--) + { + for (int x = 0; x < image.Width; x++) + { + // Limit the output range and multiply out from our floating point. + // Convert back to b-> g-> r-> a order. + // Convert to non-premultiplied color. + Bgra32 color = Color.ToNonPremultiplied(image[x, y]); + + // Allocate 1 array instead of allocating 3. + writer.Write(new[] { color.B, color.G, color.R }); + } + + // Pad + for (int i = 0; i < amount; i++) + { + writer.Write((byte)0); + } + } + } + } +} diff --git a/src/ImageProcessorCore/IImage.cs b/src/ImageProcessorCore/IImage.cs index 48236a245..008be3ddb 100644 --- a/src/ImageProcessorCore/IImage.cs +++ b/src/ImageProcessorCore/IImage.cs @@ -91,5 +91,13 @@ namespace ImageProcessorCore /// The format to save the image as. /// Thrown if the stream is null. void Save(Stream stream, IImageFormat format); + + /// + /// Saves the image to the given stream using the given image encoder. + /// + /// The stream to save the image to. + /// The encoder to save the image with. + /// Thrown if the stream is null. + void Save(Stream stream, IImageEncoder encoder); } } \ No newline at end of file diff --git a/src/ImageProcessorCore/Image.cs b/src/ImageProcessorCore/Image.cs index a660df468..0edbfb756 100644 --- a/src/ImageProcessorCore/Image.cs +++ b/src/ImageProcessorCore/Image.cs @@ -216,6 +216,13 @@ namespace ImageProcessorCore format.Encoder.Encode(this, stream); } + /// + public void Save(Stream stream, IImageEncoder encoder) + { + Guard.NotNull(stream, nameof(stream)); + encoder.Encode(this, stream); + } + /// /// Loads the image from the given stream. /// diff --git a/tests/ImageProcessorCore.Tests/Colors/ColorConversionTests.cs b/tests/ImageProcessorCore.Tests/Colors/ColorConversionTests.cs index deb6eb011..c7a252b03 100644 --- a/tests/ImageProcessorCore.Tests/Colors/ColorConversionTests.cs +++ b/tests/ImageProcessorCore.Tests/Colors/ColorConversionTests.cs @@ -1,12 +1,7 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// Copyright © James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. // -// -// Test conversion between the various color structs. -// -// -------------------------------------------------------------------------------------------------------------------- namespace ImageProcessorCore.Tests { diff --git a/tests/ImageProcessorCore.Tests/Colors/ColorSpacialTransformTests.cs b/tests/ImageProcessorCore.Tests/Colors/ColorSpacialTransformTests.cs index c2a8ac902..a4371cf54 100644 --- a/tests/ImageProcessorCore.Tests/Colors/ColorSpacialTransformTests.cs +++ b/tests/ImageProcessorCore.Tests/Colors/ColorSpacialTransformTests.cs @@ -1,3 +1,8 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + namespace ImageProcessorCore.Tests { using Xunit; diff --git a/tests/ImageProcessorCore.Tests/Colors/ColorTests.cs b/tests/ImageProcessorCore.Tests/Colors/ColorTests.cs index 0ff680b18..e7d86012d 100644 --- a/tests/ImageProcessorCore.Tests/Colors/ColorTests.cs +++ b/tests/ImageProcessorCore.Tests/Colors/ColorTests.cs @@ -1,12 +1,7 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// Copyright © James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. // -// -// Tests the struct. -// -// -------------------------------------------------------------------------------------------------------------------- using System.Numerics; diff --git a/tests/ImageProcessorCore.Tests/Processors/ProcessorTestBase.cs b/tests/ImageProcessorCore.Tests/FileTestBase.cs similarity index 69% rename from tests/ImageProcessorCore.Tests/Processors/ProcessorTestBase.cs rename to tests/ImageProcessorCore.Tests/FileTestBase.cs index 6c79efa43..d5471f429 100644 --- a/tests/ImageProcessorCore.Tests/Processors/ProcessorTestBase.cs +++ b/tests/ImageProcessorCore.Tests/FileTestBase.cs @@ -1,9 +1,7 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// Copyright © James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. // -// -------------------------------------------------------------------------------------------------------------------- namespace ImageProcessorCore.Tests { @@ -12,14 +10,14 @@ namespace ImageProcessorCore.Tests using Xunit; /// - /// The processor test base. + /// The test base class for reading and writing to files. /// - public abstract class ProcessorTestBase + public abstract class FileTestBase { /// /// The collection of image files to test against. /// - public static readonly List Files = new List + protected static readonly List Files = new List { //"TestImages/Formats/Jpg/Floorplan.jpeg", // Perf: Enable for local testing only "TestImages/Formats/Jpg/Calliphora.jpg", diff --git a/tests/ImageProcessorCore.Tests/Formats/BitmapTests.cs b/tests/ImageProcessorCore.Tests/Formats/BitmapTests.cs new file mode 100644 index 000000000..92589ee88 --- /dev/null +++ b/tests/ImageProcessorCore.Tests/Formats/BitmapTests.cs @@ -0,0 +1,51 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageProcessorCore.Tests +{ + using System.Diagnostics; + using System.IO; + + using Formats; + + using Xunit; + + public class BitmapTests : FileTestBase + { + [Fact] + public void BitmapCanEncodeDifferentBitRates() + { + if (!Directory.Exists("TestOutput/Encode/Bitmap")) + { + Directory.CreateDirectory("TestOutput/Encode/Bitmap"); + } + + foreach (string file in Files) + { + using (FileStream stream = File.OpenRead(file)) + { + Stopwatch watch = Stopwatch.StartNew(); + Image image = new Image(stream); + + string encodeFilename = "TestOutput/Encode/Bitmap/" + "24-" + Path.GetFileNameWithoutExtension(file) + ".bmp"; + + using (FileStream output = File.OpenWrite(encodeFilename)) + { + image.Save(output, new BmpEncoder { BitsPerPixel = BmpBitsPerPixel.Pixel24 }); + } + + encodeFilename = "TestOutput/Encode/Bitmap/" + "32-" + Path.GetFileNameWithoutExtension(file) + ".bmp"; + + using (FileStream output = File.OpenWrite(encodeFilename)) + { + image.Save(output, new BmpEncoder { BitsPerPixel = BmpBitsPerPixel.Pixel32 }); + } + + Trace.WriteLine($"{file} : {watch.ElapsedMilliseconds}ms"); + } + } + } + } +} \ No newline at end of file diff --git a/tests/ImageProcessorCore.Tests/Processors/Formats/EncoderDecoderTests.cs b/tests/ImageProcessorCore.Tests/Formats/EncoderDecoderTests.cs similarity index 84% rename from tests/ImageProcessorCore.Tests/Processors/Formats/EncoderDecoderTests.cs rename to tests/ImageProcessorCore.Tests/Formats/EncoderDecoderTests.cs index f5cf32a4d..0b19d1b1a 100644 --- a/tests/ImageProcessorCore.Tests/Processors/Formats/EncoderDecoderTests.cs +++ b/tests/ImageProcessorCore.Tests/Formats/EncoderDecoderTests.cs @@ -1,4 +1,9 @@ -namespace ImageProcessorCore.Tests +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageProcessorCore.Tests { using System.Diagnostics; using System.IO; @@ -10,7 +15,7 @@ using ImageProcessorCore.Quantizers; - public class EncoderDecoderTests : ProcessorTestBase + public class EncoderDecoderTests : FileTestBase { [Fact] public void DecodeThenEncodeImageFromStreamShouldSucceed() @@ -20,11 +25,6 @@ Directory.CreateDirectory("TestOutput/Encode"); } - //foreach (FileInfo file in new DirectoryInfo("TestOutput/Encode").GetFiles()) - //{ - // file.Delete(); - //} - foreach (string file in Files) { using (FileStream stream = File.OpenRead(file)) @@ -85,29 +85,6 @@ } } - [Fact] - public void ImageCanSaveIndexedPng() - { - if (!Directory.Exists("TestOutput/Indexed")) - { - Directory.CreateDirectory("TestOutput/Indexed"); - } - - foreach (string file in Files) - { - using (FileStream stream = File.OpenRead(file)) - { - Image image = new Image(stream); - - using (FileStream output = File.OpenWrite($"TestOutput/Indexed/{Path.GetFileNameWithoutExtension(file)}.png")) - { - image.Quality = 256; - image.Save(output, new PngFormat()); - } - } - } - } - [Fact] public void ImageCanConvertFormat() { diff --git a/tests/ImageProcessorCore.Tests/Formats/PngTests.cs b/tests/ImageProcessorCore.Tests/Formats/PngTests.cs new file mode 100644 index 000000000..6c7029c85 --- /dev/null +++ b/tests/ImageProcessorCore.Tests/Formats/PngTests.cs @@ -0,0 +1,39 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageProcessorCore.Tests +{ + using System.IO; + + using Formats; + + using Xunit; + + public class PngTests : FileTestBase + { + [Fact] + public void ImageCanSaveIndexedPng() + { + if (!Directory.Exists("TestOutput/Encode/Png")) + { + Directory.CreateDirectory("TestOutput/Encode/Png"); + } + + foreach (string file in Files) + { + using (FileStream stream = File.OpenRead(file)) + { + Image image = new Image(stream); + + using (FileStream output = File.OpenWrite($"TestOutput/Encode/Png/{Path.GetFileNameWithoutExtension(file)}.png")) + { + image.Quality = 256; + image.Save(output, new PngFormat()); + } + } + } + } + } +} \ No newline at end of file diff --git a/tests/ImageProcessorCore.Tests/Processors/Filters/FilterTests.cs b/tests/ImageProcessorCore.Tests/Processors/Filters/FilterTests.cs index 577f07a2c..4e3fd103d 100644 --- a/tests/ImageProcessorCore.Tests/Processors/Filters/FilterTests.cs +++ b/tests/ImageProcessorCore.Tests/Processors/Filters/FilterTests.cs @@ -8,7 +8,7 @@ namespace ImageProcessorCore.Tests using Xunit; - public class FilterTests : ProcessorTestBase + public class FilterTests : FileTestBase { public static readonly TheoryData Filters = new TheoryData { diff --git a/tests/ImageProcessorCore.Tests/Processors/Samplers/SamplerTests.cs b/tests/ImageProcessorCore.Tests/Processors/Samplers/SamplerTests.cs index 678e9fd07..925d1340b 100644 --- a/tests/ImageProcessorCore.Tests/Processors/Samplers/SamplerTests.cs +++ b/tests/ImageProcessorCore.Tests/Processors/Samplers/SamplerTests.cs @@ -8,7 +8,7 @@ using Xunit; using Filters; - public class SamplerTests : ProcessorTestBase + public class SamplerTests : FileTestBase { public static readonly TheoryData ReSamplers = new TheoryData