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