diff --git a/src/ImageProcessor/Filters/Contrast.cs b/src/ImageProcessor/Filters/Contrast.cs
index 752bef018..30823a8f5 100644
--- a/src/ImageProcessor/Filters/Contrast.cs
+++ b/src/ImageProcessor/Filters/Contrast.cs
@@ -8,9 +8,9 @@ namespace ImageProcessor.Filters
using System;
///
- /// An to change the contrast of an .
+ /// An to change the contrast of an .
///
- public class Contrast : ParallelImageFilter
+ public class Contrast : ParallelImageProcessor
{
///
/// Initializes a new instance of the class.
diff --git a/src/ImageProcessor/Filters/IImageFilter.cs b/src/ImageProcessor/Filters/IImageFilter.cs
deleted file mode 100644
index 11843d021..000000000
--- a/src/ImageProcessor/Filters/IImageFilter.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-namespace ImageProcessor.Filters
-{
- ///
- /// Image processing filter interface.
- ///
- ///
- /// The interface defines the set of methods, which should be
- /// provided by all image processing filters. Methods of this interface
- /// manipulate the original image.
- ///
- public interface IImageFilter
- {
- ///
- /// Apply filter to an image at the area of the specified rectangle.
- ///
- /// Target image to apply filter to.
- /// The source image. Cannot be null.
- /// The rectangle, which defines the area of the
- /// image where the filter should be applied to.
- /// The method keeps the source image unchanged and returns the
- /// the result of image processing filter as new image.
- ///
- ///
- /// is null.
- /// - or -
- ///
- /// is null.
- ///
- ///
- /// doesnt fit the dimension of the image.
- ///
- void Apply(ImageBase target, ImageBase source, Rectangle rectangle);
- }
-}
diff --git a/src/ImageProcessor/Filters/ImageFilterExtensions.cs b/src/ImageProcessor/Filters/ImageFilterExtensions.cs
index c97500a23..674f4f0e4 100644
--- a/src/ImageProcessor/Filters/ImageFilterExtensions.cs
+++ b/src/ImageProcessor/Filters/ImageFilterExtensions.cs
@@ -5,77 +5,17 @@
namespace ImageProcessor.Filters
{
- using System;
-
///
- /// Exstension methods for performing filtering methods again an image.
+ /// Exstensions methods for to apply filters to the image.
///
public static class ImageFilterExtensions
{
- ///
- /// Applies the collection of filters to the image.
- ///
- /// The image this method extends.
- /// Any filters to apply to the image.
- /// The .
- public static Image Filter(this Image source, params IImageFilter[] filters) => Filter(source, source.Bounds, filters);
-
- ///
- /// Applies the collection of filters to the image.
- ///
- /// The image this method extends.
- ///
- /// The rectangle defining the bounds of the pixels the image filter with adjust.
- /// Any filters to apply to the image.
- /// The .
- public static Image Filter(this Image source, Rectangle rectangle, params IImageFilter[] filters)
- {
- // ReSharper disable once LoopCanBeConvertedToQuery
- foreach (IImageFilter filter in filters)
- {
- source = PerformAction(source, true, (sourceImage, targetImage) => filter.Apply(targetImage, sourceImage, rectangle));
- }
-
- return source;
- }
-
///
/// Alters the contrast component of the image.
///
/// The image this method extends.
/// The new contrast of the image. Must be between -100 and 100.
/// The .
- public static Image Contrast(this Image source, int amount) => source.Filter(new Contrast(amount));
-
- ///
- /// Performs the given action on the source image.
- ///
- /// The image to perform the action against.
- /// Whether to clone the image.
- /// The to perform against the image.
- /// The .
- private static Image PerformAction(Image source, bool clone, Action action)
- {
- Image transformedImage = clone ? new Image(source) : new Image(source.Width, source.Height);
- action(source, transformedImage);
-
- for (int i = 0; i < source.Frames.Count; i++)
- {
- ImageFrame frame = source.Frames[i];
- ImageFrame tranformedFrame = new ImageFrame(frame);
- action(frame, tranformedFrame);
-
- if (!clone)
- {
- transformedImage.Frames.Add(tranformedFrame);
- }
- else
- {
- transformedImage.Frames[i] = tranformedFrame;
- }
- }
-
- return transformedImage;
- }
+ public static Image Contrast(this Image source, int amount) => source.Process(new Contrast(amount));
}
}
diff --git a/src/ImageProcessor/IImage.cs b/src/ImageProcessor/IImage.cs
index 82c9710ec..58f3380bd 100644
--- a/src/ImageProcessor/IImage.cs
+++ b/src/ImageProcessor/IImage.cs
@@ -85,7 +85,7 @@ namespace ImageProcessor
void Save(Stream stream);
///
- /// Saves the image to the given stream using the currently loaded image format.
+ /// Saves the image to the given stream using the given image format.
///
/// The stream to save the image to.
/// The format to save the image as.
diff --git a/src/ImageProcessor/IImageProcessor.cs b/src/ImageProcessor/IImageProcessor.cs
new file mode 100644
index 000000000..667f1ae30
--- /dev/null
+++ b/src/ImageProcessor/IImageProcessor.cs
@@ -0,0 +1,33 @@
+//
+// Copyright © James South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageProcessor
+{
+ ///
+ /// Encapsulates methods to alter the pixels of an image.
+ ///
+ public interface IImageProcessor
+ {
+ ///
+ /// Apply a process to an image to alter the pixels at the area of the specified rectangle.
+ ///
+ /// Target image to apply the process to.
+ /// The source image. Cannot be null.
+ ///
+ /// The rectangle, which defines the area of the image where the process should be applied to.
+ ///
+ ///
+ /// The method keeps the source image unchanged and returns the
+ /// the result of image processing filter as new image.
+ ///
+ ///
+ /// is null or is null.
+ ///
+ ///
+ /// doesnt fit the dimension of the image.
+ ///
+ void Apply(ImageBase target, ImageBase source, Rectangle rectangle);
+ }
+}
diff --git a/src/ImageProcessor/Image.cs b/src/ImageProcessor/Image.cs
index a75364ae2..d141568ee 100644
--- a/src/ImageProcessor/Image.cs
+++ b/src/ImageProcessor/Image.cs
@@ -1,13 +1,7 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Copyright © James South and contributors.
-// Licensed under the Apache License, Version 2.0.
+//
+// Copyright © James South and contributors.
+// Licensed under the Apache License, Version 2.0.
//
-//
-// Image class which stores the pixels and provides common functionality
-// such as loading images from files and streams or operation like resizing or cropping.
-//
-// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor
{
@@ -187,7 +181,7 @@ namespace ImageProcessor
public IList Properties { get; } = new List();
///
- public IImageFormat CurrentImageFormat { get; private set; }
+ public IImageFormat CurrentImageFormat { get; internal set; }
///
public void Save(Stream stream)
diff --git a/src/ImageProcessor/ImageBase.cs b/src/ImageProcessor/ImageBase.cs
index 890f6c861..7996cebc0 100644
--- a/src/ImageProcessor/ImageBase.cs
+++ b/src/ImageProcessor/ImageBase.cs
@@ -1,13 +1,7 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Copyright © James South and contributors.
-// Licensed under the Apache License, Version 2.0.
+//
+// Copyright © James South and contributors.
+// Licensed under the Apache License, Version 2.0.
//
-//
-// The base class of all images. Encapsulates all the properties and methods
-// required to manipulate images.
-//
-// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor
{
@@ -168,7 +162,6 @@ namespace ImageProcessor
throw new ArgumentOutOfRangeException(nameof(y), "Value cannot be less than zero or greater than the bitmap height.");
}
#endif
-
int start = ((y * this.Width) + x) * 4;
this.Pixels[start + 0] = value.B;
diff --git a/src/ImageProcessor/ImageExtensions.cs b/src/ImageProcessor/ImageExtensions.cs
new file mode 100644
index 000000000..2298f8785
--- /dev/null
+++ b/src/ImageProcessor/ImageExtensions.cs
@@ -0,0 +1,111 @@
+//
+// Copyright © James South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageProcessor
+{
+ using System;
+ using System.IO;
+
+ using Formats;
+
+ ///
+ /// Exstension methods for the type.
+ ///
+ public static class ImageExtensions
+ {
+ ///
+ /// Saves the image to the given stream with the bmp format.
+ ///
+ /// The image this method extends.
+ /// The stream to save the image to.
+ /// Thrown if the stream is null.
+ public static void SaveAsBmp(this ImageBase source, Stream stream) => new BmpEncoder().Encode(source, stream);
+
+ ///
+ /// Saves the image to the given stream with the png format.
+ ///
+ /// The image this method extends.
+ /// The stream to save the image to.
+ /// Thrown if the stream is null.
+ public static void SaveAsPng(this ImageBase source, Stream stream) => new PngEncoder().Encode(source, stream);
+
+ ///
+ /// Saves the image to the given stream with the jpeg format.
+ ///
+ /// The image this method extends.
+ /// The stream to save the image to.
+ /// The quality to save the image to. Between 1 and 100.
+ /// Thrown if the stream is null.
+ public static void SaveAsJpeg(this ImageBase source, Stream stream, int quality = 80) => new JpegEncoder { Quality = quality }.Encode(source, stream);
+
+ ///
+ /// Saves the image to the given stream with the gif format.
+ ///
+ /// The image this method extends.
+ /// The stream to save the image to.
+ /// The quality to save the image to representing the number of colors. Between 1 and 100.
+ /// Thrown if the stream is null.
+ public static void SaveAsGif(this ImageBase source, Stream stream, int quality = 256) => new GifEncoder() { Quality = quality }.Encode(source, stream);
+
+ ///
+ /// Applies the collection of processors to the image.
+ ///
+ /// The image this method extends.
+ /// Any processors to apply to the image.
+ /// The .
+ public static Image Process(this Image source, params IImageProcessor[] processors) => Process(source, source.Bounds, processors);
+
+ ///
+ /// Applies the collection of processors to the image.
+ ///
+ /// The image this method extends.
+ ///
+ /// The rectangle defining the bounds of the pixels the image filter with adjust.
+ /// Any processors to apply to the image.
+ /// The .
+ public static Image Process(this Image source, Rectangle rectangle, params IImageProcessor[] processors)
+ {
+ // ReSharper disable once LoopCanBeConvertedToQuery
+ foreach (IImageProcessor filter in processors)
+ {
+ source = PerformAction(source, true, (sourceImage, targetImage) => filter.Apply(targetImage, sourceImage, rectangle));
+ }
+
+ return source;
+ }
+
+ ///
+ /// Performs the given action on the source image.
+ ///
+ /// The image to perform the action against.
+ /// Whether to clone the image.
+ /// The to perform against the image.
+ /// The .
+ private static Image PerformAction(Image source, bool clone, Action action)
+ {
+ Image transformedImage = clone ? new Image(source) : new Image();
+ transformedImage.CurrentImageFormat = source.CurrentImageFormat;
+ action(source, transformedImage);
+
+ for (int i = 0; i < source.Frames.Count; i++)
+ {
+ ImageFrame sourceFrame = source.Frames[i];
+ ImageFrame tranformedFrame = clone ? new ImageFrame(sourceFrame) : new ImageFrame();
+ action(sourceFrame, tranformedFrame);
+
+ if (!clone)
+ {
+ transformedImage.Frames.Add(tranformedFrame);
+ }
+ else
+ {
+ transformedImage.Frames[i] = tranformedFrame;
+ }
+ }
+
+ return transformedImage;
+ }
+ }
+}
diff --git a/src/ImageProcessor/ImageFrame.cs b/src/ImageProcessor/ImageFrame.cs
index b2d4f5235..84166507a 100644
--- a/src/ImageProcessor/ImageFrame.cs
+++ b/src/ImageProcessor/ImageFrame.cs
@@ -1,12 +1,7 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Copyright © James South and contributors.
-// Licensed under the Apache License, Version 2.0.
+//
+// Copyright © James South and contributors.
+// Licensed under the Apache License, Version 2.0.
//
-//
-// Represents a single frame in a animation.
-//
-// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor
{
diff --git a/src/ImageProcessor/ImageProcessor.csproj b/src/ImageProcessor/ImageProcessor.csproj
index 377b7c363..8e779c1c2 100644
--- a/src/ImageProcessor/ImageProcessor.csproj
+++ b/src/ImageProcessor/ImageProcessor.csproj
@@ -13,7 +13,7 @@
en-US
512
{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Profile78
+ Profile259
v4.5
..\..\
true
@@ -38,12 +38,14 @@
+
-
-
+
+
+
@@ -177,7 +179,6 @@
-
diff --git a/src/ImageProcessor/Filters/ParallelImageFilter.cs b/src/ImageProcessor/ParallelImageProcessor.cs
similarity index 52%
rename from src/ImageProcessor/Filters/ParallelImageFilter.cs
rename to src/ImageProcessor/ParallelImageProcessor.cs
index 647e32515..3bc28e15d 100644
--- a/src/ImageProcessor/Filters/ParallelImageFilter.cs
+++ b/src/ImageProcessor/ParallelImageProcessor.cs
@@ -1,15 +1,20 @@
-namespace ImageProcessor.Filters
+//
+// Copyright © James South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageProcessor
{
using System;
using System.Threading.Tasks;
///
- /// Allows the application of filters using prallel processing.
+ /// Allows the application of processors using parallel processing.
///
- public abstract class ParallelImageFilter : IImageFilter
+ public abstract class ParallelImageProcessor : IImageProcessor
{
///
- /// Gets or sets the count of workers to run the filter in parallel.
+ /// Gets or sets the count of workers to run the process in parallel.
///
public int Parallelism { get; set; } = Environment.ProcessorCount;
@@ -46,12 +51,26 @@
}
///
- /// This method is called before the filter is applied to prepare the filter.
+ /// This method is called before the process is applied to prepare the processor.
///
protected virtual void OnApply()
{
}
+ ///
+ /// Apply a process to an image to alter the pixels at the area of the specified rectangle.
+ ///
+ /// Target image to apply the process to.
+ /// The source image. Cannot be null.
+ ///
+ /// The rectangle, which defines the area of the image where the process should be applied to.
+ ///
+ /// The index of the row within the image to start processing.
+ /// The index of the row within the image to end processing.
+ ///
+ /// The method keeps the source image unchanged and returns the
+ /// the result of image processing filter as new image.
+ ///
protected abstract void Apply(ImageBase target, ImageBase source, Rectangle rectangle, int startY, int endY);
}
}
diff --git a/src/ImageProcessor/Samplers/IImageSampler.cs b/src/ImageProcessor/Samplers/IImageSampler.cs
deleted file mode 100644
index 24e815ef6..000000000
--- a/src/ImageProcessor/Samplers/IImageSampler.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright © James South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessor.Samplers
-{
- ///
- /// Encapsulates the methods required for all image sampling (resizing) algorithms.
- ///
- public interface IImageSampler
- {
- ///
- /// Resizes the specified source image by creating a new image with
- /// the specified size which is a resized version of the passed image.
- ///
- /// The source image.
- /// The target image.
- /// The width.
- /// The height.
- void Sample(ImageBase source, ImageBase target, int width, int height);
- }
-}
diff --git a/tests/ImageProcessor.Tests/Filters/FilterTests.cs b/tests/ImageProcessor.Tests/Filters/FilterTests.cs
index e6b7b4944..a6452d37a 100644
--- a/tests/ImageProcessor.Tests/Filters/FilterTests.cs
+++ b/tests/ImageProcessor.Tests/Filters/FilterTests.cs
@@ -23,7 +23,7 @@ namespace ImageProcessor.Tests.Filters
//{ "../../TestImages/Formats/Gif/giphy.gif" },
};
- public static readonly TheoryData Filters = new TheoryData
+ public static readonly TheoryData Filters = new TheoryData
{
{ "Contrast-50", new Contrast(50) },
{ "Contrast--50", new Contrast(-50) },
@@ -31,7 +31,7 @@ namespace ImageProcessor.Tests.Filters
[Theory]
[MemberData("Filters")]
- public void FilterImage(string name, IImageFilter filter)
+ public void FilterImage(string name, IImageProcessor processor)
{
if (!Directory.Exists("Filtered"))
{
@@ -47,7 +47,7 @@ namespace ImageProcessor.Tests.Filters
string filename = Path.GetFileNameWithoutExtension(file) + "-" + name + Path.GetExtension(file);
using (FileStream output = File.OpenWrite($"Filtered/{ Path.GetFileName(filename) }"))
{
- image.Filter(filter).Save(output);
+ image.Process(processor).Save(output);
}
Trace.WriteLine($"{ name }: { watch.ElapsedMilliseconds}ms");
diff --git a/tests/ImageProcessor.Tests/Formats/EncoderDecoderTests.cs b/tests/ImageProcessor.Tests/Formats/EncoderDecoderTests.cs
index 713adf60d..74c8ab304 100644
--- a/tests/ImageProcessor.Tests/Formats/EncoderDecoderTests.cs
+++ b/tests/ImageProcessor.Tests/Formats/EncoderDecoderTests.cs
@@ -31,29 +31,10 @@
string encodedFilename = "Encoded/" + Path.GetFileName(filename);
- //if (!image.IsAnimated)
- //{
using (FileStream output = File.OpenWrite(encodedFilename))
{
image.Save(output);
}
- //}
- //else
- //{
- // using (var output = File.OpenWrite(
- // string.Format("Encoded/{ Path.GetFileNameWithoutExtension(filename) }.jpg"))
- // {
- // image.SaveAsJpeg(output, 40);
- // }
-
- // for (int i = 0; i < image.Frames.Count; i++)
- // {
- // using (var output = File.OpenWrite($"Encoded/{ i }_{ Path.GetFileNameWithoutExtension(filename) }.png"))
- // {
- // image.Frames[i].SaveAsPng(output);
- // }
- // }
- //}
Trace.WriteLine($"{filename} : {watch.ElapsedMilliseconds}ms");
}
@@ -75,7 +56,7 @@
using (FileStream output = File.OpenWrite($"Quantized/{ Path.GetFileName(filename) }"))
{
- quantizedImage.ToImage().Save(output, image.CurrentImageFormat);
+ quantizedImage.ToImage().Save(output);
}
}
}