Browse Source

Refactoring filters to not require ImageFactory

Former-commit-id: 79da6e8a53cc8f4b79007db15218ebf77a942050
pull/17/head
James South 12 years ago
parent
commit
f9e7fd1f08
  1. 47
      src/ImageProcessor.UnitTests/ImageFactoryUnitTests.cs
  2. 2
      src/ImageProcessor.Web.UnitTests/RegularExpressionUnitTests.cs
  3. 2
      src/ImageProcessor.Web/Processors/Filter.cs
  4. 4
      src/ImageProcessor.sln
  5. 4
      src/ImageProcessor/ImageFactory.cs
  6. 48
      src/ImageProcessor/ImageProcessor.csproj
  7. 3
      src/ImageProcessor/Imaging/Filters/Binarization/BinaryThreshold.cs
  8. 9
      src/ImageProcessor/Imaging/Filters/EdgeDetection/ConvolutionFilter.cs
  9. 2
      src/ImageProcessor/Imaging/Filters/EdgeDetection/IEdgeFilter.cs
  10. 2
      src/ImageProcessor/Imaging/Filters/EdgeDetection/KayyaliEdgeFilter.cs
  11. 2
      src/ImageProcessor/Imaging/Filters/EdgeDetection/KirschEdgeFilter.cs
  12. 2
      src/ImageProcessor/Imaging/Filters/EdgeDetection/PrewittEdgeFilter.cs
  13. 2
      src/ImageProcessor/Imaging/Filters/EdgeDetection/RobertsCrossEdgeFilter.cs
  14. 2
      src/ImageProcessor/Imaging/Filters/EdgeDetection/ScharrEdgeFilter.cs
  15. 2
      src/ImageProcessor/Imaging/Filters/EdgeDetection/SobelEdgeFilter.cs
  16. 12
      src/ImageProcessor/Imaging/Filters/Photo/BlackWhiteMatrixFilter.cs
  17. 2
      src/ImageProcessor/Imaging/Filters/Photo/ColorMatrixes.cs
  18. 10
      src/ImageProcessor/Imaging/Filters/Photo/ComicMatrixFilter.cs
  19. 24
      src/ImageProcessor/Imaging/Filters/Photo/GothamMatrixFilter.cs
  20. 12
      src/ImageProcessor/Imaging/Filters/Photo/GreyScaleMatrixFilter.cs
  21. 12
      src/ImageProcessor/Imaging/Filters/Photo/HiSatchMatrixFilter.cs
  22. 12
      src/ImageProcessor/Imaging/Filters/Photo/IMatrixFilter.cs
  23. 12
      src/ImageProcessor/Imaging/Filters/Photo/InvertMatrixFilter.cs
  24. 12
      src/ImageProcessor/Imaging/Filters/Photo/LoSatchMatrixFilter.cs
  25. 19
      src/ImageProcessor/Imaging/Filters/Photo/LomographMatrixFilter.cs
  26. 11
      src/ImageProcessor/Imaging/Filters/Photo/MatrixFilterBase.cs
  27. 2
      src/ImageProcessor/Imaging/Filters/Photo/MatrixFilters.cs
  28. 69
      src/ImageProcessor/Imaging/Filters/Photo/PolaroidMatrixFilter.cs
  29. 12
      src/ImageProcessor/Imaging/Filters/Photo/SepiaMatrixFilter.cs
  30. 99
      src/ImageProcessor/Imaging/Filters/PolaroidMatrixFilter.cs
  31. 126
      src/ImageProcessor/Imaging/Helpers/Adjustments.cs
  32. 112
      src/ImageProcessor/Imaging/Helpers/Effects.cs
  33. 38
      src/ImageProcessor/Processors/Brightness.cs
  34. 36
      src/ImageProcessor/Processors/Contrast.cs
  35. 2
      src/ImageProcessor/Processors/DetectEdges.cs
  36. 23
      src/ImageProcessor/Processors/EntropyCrop.cs
  37. 4
      src/ImageProcessor/Processors/Filter.cs
  38. 53
      src/ImageProcessor/Processors/Vignette.cs
  39. 4
      src/ImageProcessorConsole/ImageProcessor.Playground.csproj
  40. 13
      src/ImageProcessorConsole/Program.cs
  41. 1
      src/ImageProcessorConsole/images/input/new-york.jpg.REMOVED.git-id
  42. 1
      src/ImageProcessorConsole/images/output/monster-whitebg.png.REMOVED.git-id

47
src/ImageProcessor.UnitTests/ImageFactoryUnitTests.cs

@ -3,11 +3,7 @@
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Unit tests for the ImageFactory (loading of images)
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.UnitTests
{
using System;
@ -17,6 +13,7 @@ namespace ImageProcessor.UnitTests
using System.Linq;
using ImageProcessor.Imaging;
using ImageProcessor.Imaging.Filters.Photo;
using NUnit.Framework;
@ -249,9 +246,9 @@ namespace ImageProcessor.UnitTests
Image original = (Image)imageFactory.Image.Clone();
imageFactory.Watermark(new TextLayer
{
FontFamily = new FontFamily("Arial"),
FontSize = 10,
Position = new Point(10, 10),
FontFamily = new FontFamily("Arial"),
FontSize = 10,
Position = new Point(10, 10),
Text = "Lorem ipsum dolor"
});
Assert.AreNotEqual(original, imageFactory.Image);
@ -344,43 +341,43 @@ namespace ImageProcessor.UnitTests
imageFactory.Load(file.FullName);
Image original = (Image)imageFactory.Image.Clone();
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.BlackWhite);
imageFactory.Filter(MatrixFilters.BlackWhite);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.Comic);
imageFactory.Filter(MatrixFilters.Comic);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.Gotham);
imageFactory.Filter(MatrixFilters.Gotham);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.GreyScale);
imageFactory.Filter(MatrixFilters.GreyScale);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.HiSatch);
imageFactory.Filter(MatrixFilters.HiSatch);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.Invert);
imageFactory.Filter(MatrixFilters.Invert);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.Lomograph);
imageFactory.Filter(MatrixFilters.Lomograph);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.LoSatch);
imageFactory.Filter(MatrixFilters.LoSatch);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.Polaroid);
imageFactory.Filter(MatrixFilters.Polaroid);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.Sepia);
imageFactory.Filter(MatrixFilters.Sepia);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
}
@ -552,10 +549,18 @@ namespace ImageProcessor.UnitTests
/// <summary>
/// Gets the files matching the given extensions.
/// </summary>
/// <param name="dir">The <see cref="System.IO.DirectoryInfo"/>.</param>
/// <param name="extensions">The extensions.</param>
/// <returns>A collection of <see cref="System.IO.FileInfo"/></returns>
/// <exception cref="System.ArgumentNullException">The extensions variable is null.</exception>
/// <param name="dir">
/// The <see cref="System.IO.DirectoryInfo"/>.
/// </param>
/// <param name="extensions">
/// The extensions.
/// </param>
/// <returns>
/// A collection of <see cref="System.IO.FileInfo"/>
/// </returns>
/// <exception cref="System.ArgumentNullException">
/// The extensions variable is null.
/// </exception>
private static IEnumerable<FileInfo> GetFilesByExtensions(DirectoryInfo dir, params string[] extensions)
{
if (extensions == null)

2
src/ImageProcessor.Web.UnitTests/RegularExpressionUnitTests.cs

@ -14,7 +14,7 @@ namespace ImageProcessor.Web.UnitTests
using System.Collections.Generic;
using System.Drawing;
using ImageProcessor.Imaging;
using ImageProcessor.Imaging.Filters;
using ImageProcessor.Imaging.Filters.Photo;
using ImageProcessor.Imaging.Formats;
using ImageProcessor.Plugins.WebP.Imaging.Formats;

2
src/ImageProcessor.Web/Processors/Filter.cs

@ -16,7 +16,7 @@ namespace ImageProcessor.Web.Processors
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using ImageProcessor.Imaging.Filters;
using ImageProcessor.Imaging.Filters.Photo;
using ImageProcessor.Processors;
/// <summary>

4
src/ImageProcessor.sln

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.30501.0
VisualStudioVersion = 12.0.30723.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C427A497-74DC-49B1-8420-D6E68354F29B}"
ProjectSection(SolutionItems) = preProject
@ -22,7 +22,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Web", "Image
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Plugins.WebP", "Plugins\ImageProcessor\ImageProcessor.Plugins.WebP\ImageProcessor.Plugins.WebP.csproj", "{2CF69699-959A-44DC-A281-4E2596C25043}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessorConsole", "ImageProcessorConsole\ImageProcessorConsole.csproj", "{7BF5274B-56A7-4B62-8105-E9BDF25BAFE7}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Playground", "ImageProcessorConsole\ImageProcessor.Playground.csproj", "{7BF5274B-56A7-4B62-8105-E9BDF25BAFE7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Web.UnitTests", "ImageProcessor.Web.UnitTests\ImageProcessor.Web.UnitTests.csproj", "{961340C8-8C93-401D-A0A2-FF9EC61E5260}"
EndProject

4
src/ImageProcessor/ImageFactory.cs

@ -20,8 +20,8 @@ namespace ImageProcessor
using ImageProcessor.Common.Exceptions;
using ImageProcessor.Imaging;
using ImageProcessor.Imaging.EdgeDetection;
using ImageProcessor.Imaging.Filters;
using ImageProcessor.Imaging.Filters.EdgeDetection;
using ImageProcessor.Imaging.Filters.Photo;
using ImageProcessor.Imaging.Formats;
using ImageProcessor.Processors;
#endregion

48
src/ImageProcessor/ImageProcessor.csproj

@ -76,14 +76,14 @@
<Compile Include="Imaging\Colors\HslaColor.cs" />
<Compile Include="Imaging\Colors\RgbaColor.cs" />
<Compile Include="Imaging\Colors\YCbCrColor.cs" />
<Compile Include="Imaging\EdgeDetection\ConvolutionFilter.cs" />
<Compile Include="Imaging\EdgeDetection\IEdgeFilter.cs" />
<Compile Include="Imaging\EdgeDetection\KirschEdgeFilter.cs" />
<Compile Include="Imaging\EdgeDetection\ScharrEdgeFilter.cs" />
<Compile Include="Imaging\EdgeDetection\RobertsCrossEdgeFilter.cs" />
<Compile Include="Imaging\EdgeDetection\PrewittEdgeFilter.cs" />
<Compile Include="Imaging\EdgeDetection\KayyaliEdgeFilter.cs" />
<Compile Include="Imaging\EdgeDetection\SobelEdgeFilter.cs" />
<Compile Include="Imaging\Filters\EdgeDetection\ConvolutionFilter.cs" />
<Compile Include="Imaging\Filters\EdgeDetection\IEdgeFilter.cs" />
<Compile Include="Imaging\Filters\EdgeDetection\KirschEdgeFilter.cs" />
<Compile Include="Imaging\Filters\EdgeDetection\ScharrEdgeFilter.cs" />
<Compile Include="Imaging\Filters\EdgeDetection\RobertsCrossEdgeFilter.cs" />
<Compile Include="Imaging\Filters\EdgeDetection\PrewittEdgeFilter.cs" />
<Compile Include="Imaging\Filters\EdgeDetection\KayyaliEdgeFilter.cs" />
<Compile Include="Imaging\Filters\EdgeDetection\SobelEdgeFilter.cs" />
<Compile Include="Imaging\FastBitmap.cs">
<SubType>Code</SubType>
</Compile>
@ -97,8 +97,8 @@
<Compile Include="Imaging\CropLayer.cs" />
<Compile Include="Imaging\CropMode.cs" />
<Compile Include="Imaging\ExifPropertyTag.cs" />
<Compile Include="Imaging\Filters\MatrixFilterBase.cs" />
<Compile Include="Imaging\Filters\MatrixFilters.cs" />
<Compile Include="Imaging\Filters\Photo\MatrixFilterBase.cs" />
<Compile Include="Imaging\Filters\Photo\MatrixFilters.cs" />
<Compile Include="Imaging\Formats\BitmapFormat.cs" />
<Compile Include="Imaging\Formats\TiffFormat.cs" />
<Compile Include="Imaging\Formats\PngFormat.cs" />
@ -110,21 +110,23 @@
<Compile Include="Imaging\GaussianLayer.cs" />
<Compile Include="Imaging\Formats\GifEncoder.cs" />
<Compile Include="Imaging\Formats\GifFrame.cs" />
<Compile Include="Imaging\Helpers\Adjustments.cs" />
<Compile Include="Imaging\Helpers\Effects.cs" />
<Compile Include="Imaging\PixelData.cs" />
<Compile Include="Imaging\Quantizer.cs" />
<Compile Include="Imaging\ResizeLayer.cs" />
<Compile Include="Imaging\Filters\BlackWhiteMatrixFilter.cs" />
<Compile Include="Imaging\Filters\ColorMatrixes.cs" />
<Compile Include="Imaging\Filters\ComicMatrixFilter.cs" />
<Compile Include="Imaging\Filters\LoSatchMatrixFilter.cs" />
<Compile Include="Imaging\Filters\HiSatchMatrixFilter.cs" />
<Compile Include="Imaging\Filters\InvertMatrixFilter.cs" />
<Compile Include="Imaging\Filters\GothamMatrixFilter.cs" />
<Compile Include="Imaging\Filters\GreyScaleMatrixFilter.cs" />
<Compile Include="Imaging\Filters\LomographMatrixFilter.cs" />
<Compile Include="Imaging\Filters\PolaroidMatrixFilter.cs" />
<Compile Include="Imaging\Filters\SepiaMatrixFilter.cs" />
<Compile Include="Imaging\Filters\IMatrixFilter.cs" />
<Compile Include="Imaging\Filters\Photo\BlackWhiteMatrixFilter.cs" />
<Compile Include="Imaging\Filters\Photo\ColorMatrixes.cs" />
<Compile Include="Imaging\Filters\Photo\ComicMatrixFilter.cs" />
<Compile Include="Imaging\Filters\Photo\LoSatchMatrixFilter.cs" />
<Compile Include="Imaging\Filters\Photo\HiSatchMatrixFilter.cs" />
<Compile Include="Imaging\Filters\Photo\InvertMatrixFilter.cs" />
<Compile Include="Imaging\Filters\Photo\GothamMatrixFilter.cs" />
<Compile Include="Imaging\Filters\Photo\GreyScaleMatrixFilter.cs" />
<Compile Include="Imaging\Filters\Photo\LomographMatrixFilter.cs" />
<Compile Include="Imaging\Filters\Photo\PolaroidMatrixFilter.cs" />
<Compile Include="Imaging\Filters\Photo\SepiaMatrixFilter.cs" />
<Compile Include="Imaging\Filters\Photo\IMatrixFilter.cs" />
<Compile Include="Imaging\ResizeMode.cs" />
<Compile Include="Imaging\RoundedCornerLayer.cs" />
<Compile Include="Imaging\TextLayer.cs" />
@ -133,7 +135,7 @@
<Compile Include="Processors\EntropyCrop.cs" />
<Compile Include="Processors\BackgroundColor.cs" />
<Compile Include="Processors\AutoRotate.cs" />
<Compile Include="Imaging\Binarization\BinaryThreshold.cs" />
<Compile Include="Imaging\Filters\Binarization\BinaryThreshold.cs" />
<Compile Include="Processors\DetectEdges.cs" />
<Compile Include="Processors\GaussianBlur.cs" />
<Compile Include="Processors\Brightness.cs" />

3
src/ImageProcessor/Imaging/Binarization/BinaryThreshold.cs → src/ImageProcessor/Imaging/Filters/Binarization/BinaryThreshold.cs

@ -8,10 +8,9 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Binarization
namespace ImageProcessor.Imaging.Filters.Binarization
{
using System.Drawing;
using System.Drawing.Imaging;
/// <summary>
/// Performs binary threshold filtering against a given greyscale image.

9
src/ImageProcessor/Imaging/EdgeDetection/ConvolutionFilter.cs → src/ImageProcessor/Imaging/Filters/EdgeDetection/ConvolutionFilter.cs

@ -8,14 +8,14 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.EdgeDetection
namespace ImageProcessor.Imaging.Filters.EdgeDetection
{
using System;
using System.Drawing;
using System.Drawing.Imaging;
using ImageProcessor.Common.Extensions;
using ImageProcessor.Imaging.Filters;
using ImageProcessor.Imaging.Filters.Photo;
/// <summary>
/// The convolution filter for applying gradient operators to detect edges within an image.
@ -65,7 +65,7 @@ namespace ImageProcessor.Imaging.EdgeDetection
Rectangle rectangle = new Rectangle(0, 0, width, height);
if (this.greyscale)
{
// If it's greyscale apply a colormatix to the image.
// If it's greyscale apply a colormatrix to the image.
using (ImageAttributes attributes = new ImageAttributes())
{
attributes.SetColorMatrix(ColorMatrixes.GreyScale);
@ -170,12 +170,13 @@ namespace ImageProcessor.Imaging.EdgeDetection
input.Dispose();
}
// Draw a black rectangle around the area to ensure that the first row/column in covered.
using (Graphics graphics = Graphics.FromImage(destination))
{
// Draw an edge around the image.
using (Pen blackPen = new Pen(Color.Black))
{
blackPen.Width = 4;
blackPen.Width = 1;
graphics.DrawRectangle(blackPen, new Rectangle(0, 0, destination.Width, destination.Height));
}
}

2
src/ImageProcessor/Imaging/EdgeDetection/IEdgeFilter.cs → src/ImageProcessor/Imaging/Filters/EdgeDetection/IEdgeFilter.cs

@ -8,7 +8,7 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.EdgeDetection
namespace ImageProcessor.Imaging.Filters.EdgeDetection
{
/// <summary>
/// Describes properties for creating edge detection filters.

2
src/ImageProcessor/Imaging/EdgeDetection/KayyaliEdgeFilter.cs → src/ImageProcessor/Imaging/Filters/EdgeDetection/KayyaliEdgeFilter.cs

@ -9,7 +9,7 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.EdgeDetection
namespace ImageProcessor.Imaging.Filters.EdgeDetection
{
/// <summary>
/// The Kayyali operator filter.

2
src/ImageProcessor/Imaging/EdgeDetection/KirschEdgeFilter.cs → src/ImageProcessor/Imaging/Filters/EdgeDetection/KirschEdgeFilter.cs

@ -9,7 +9,7 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.EdgeDetection
namespace ImageProcessor.Imaging.Filters.EdgeDetection
{
/// <summary>
/// The Kirsch operator filter.

2
src/ImageProcessor/Imaging/EdgeDetection/PrewittEdgeFilter.cs → src/ImageProcessor/Imaging/Filters/EdgeDetection/PrewittEdgeFilter.cs

@ -9,7 +9,7 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.EdgeDetection
namespace ImageProcessor.Imaging.Filters.EdgeDetection
{
/// <summary>
/// The Prewitt operator filter.

2
src/ImageProcessor/Imaging/EdgeDetection/RobertsCrossEdgeFilter.cs → src/ImageProcessor/Imaging/Filters/EdgeDetection/RobertsCrossEdgeFilter.cs

@ -9,7 +9,7 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.EdgeDetection
namespace ImageProcessor.Imaging.Filters.EdgeDetection
{
/// <summary>
/// The Roberts Cross operator filter.

2
src/ImageProcessor/Imaging/EdgeDetection/ScharrEdgeFilter.cs → src/ImageProcessor/Imaging/Filters/EdgeDetection/ScharrEdgeFilter.cs

@ -9,7 +9,7 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.EdgeDetection
namespace ImageProcessor.Imaging.Filters.EdgeDetection
{
/// <summary>
/// The Scharr operator filter.

2
src/ImageProcessor/Imaging/EdgeDetection/SobelEdgeFilter.cs → src/ImageProcessor/Imaging/Filters/EdgeDetection/SobelEdgeFilter.cs

@ -9,7 +9,7 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.EdgeDetection
namespace ImageProcessor.Imaging.Filters.EdgeDetection
{
/// <summary>
/// The Sobel operator filter.

12
src/ImageProcessor/Imaging/Filters/BlackWhiteMatrixFilter.cs → src/ImageProcessor/Imaging/Filters/Photo/BlackWhiteMatrixFilter.cs

@ -8,12 +8,10 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Filters
namespace ImageProcessor.Imaging.Filters.Photo
{
#region Using
using System.Drawing;
using System.Drawing.Imaging;
#endregion
/// <summary>
/// Encapsulates methods with which to add a black and white filter to an image.
@ -31,16 +29,12 @@ namespace ImageProcessor.Imaging.Filters
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="factory">
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
/// the image to process.
/// </param>
/// <param name="image">The current image to process</param>
/// <param name="newImage">The new Image to return</param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// The processed image.
/// </returns>
public override Image TransformImage(ImageFactory factory, Image image, Image newImage)
public override Image TransformImage(Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{

2
src/ImageProcessor/Imaging/Filters/ColorMatrixes.cs → src/ImageProcessor/Imaging/Filters/Photo/ColorMatrixes.cs

@ -8,7 +8,7 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Filters
namespace ImageProcessor.Imaging.Filters.Photo
{
using System.Drawing.Imaging;

10
src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs → src/ImageProcessor/Imaging/Filters/Photo/ComicMatrixFilter.cs

@ -8,7 +8,7 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Filters
namespace ImageProcessor.Imaging.Filters.Photo
{
#region Using
using System;
@ -37,16 +37,12 @@ namespace ImageProcessor.Imaging.Filters
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="factory">
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
/// the image to process.
/// </param>
/// <param name="image">The current image to process</param>
/// <param name="newImage">The new Image to return</param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// The processed image.
/// </returns>
public override Image TransformImage(ImageFactory factory, Image image, Image newImage)
public override Image TransformImage(Image image, Image newImage)
{
// Bitmaps for comic pattern
Bitmap highBitmap = null;

24
src/ImageProcessor/Imaging/Filters/GothamMatrixFilter.cs → src/ImageProcessor/Imaging/Filters/Photo/GothamMatrixFilter.cs

@ -8,16 +8,13 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Filters
namespace ImageProcessor.Imaging.Filters.Photo
{
#region Using
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using ImageProcessor.Processors;
#endregion
using ImageProcessor.Imaging.Helpers;
/// <summary>
/// Encapsulates methods with which to add a gotham filter to an image.
@ -35,16 +32,12 @@ namespace ImageProcessor.Imaging.Filters
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="factory">
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
/// the image to process.
/// </param>
/// <param name="image">The current image to process</param>
/// <param name="newImage">The new Image to return</param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// The processed image.
/// </returns>
public override Image TransformImage(ImageFactory factory, Image image, Image newImage)
public override Image TransformImage(Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{
@ -79,13 +72,8 @@ namespace ImageProcessor.Imaging.Filters
}
// Add brightness and contrast to finish the effect.
factory.Image = newImage;
Brightness brightness = new Brightness { DynamicParameter = 5 };
newImage = brightness.ProcessImage(factory);
factory.Image = newImage;
Contrast contrast = new Contrast { DynamicParameter = 85 };
newImage = contrast.ProcessImage(factory);
newImage = Adjustments.Brightness((Bitmap)newImage, 5);
newImage = Adjustments.Contrast((Bitmap)newImage, 85);
// Reassign the image.
image.Dispose();

12
src/ImageProcessor/Imaging/Filters/GreyScaleMatrixFilter.cs → src/ImageProcessor/Imaging/Filters/Photo/GreyScaleMatrixFilter.cs

@ -8,12 +8,10 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Filters
namespace ImageProcessor.Imaging.Filters.Photo
{
#region Using
using System.Drawing;
using System.Drawing.Imaging;
#endregion
/// <summary>
/// Encapsulates methods with which to add a greyscale filter to an image.
@ -31,16 +29,12 @@ namespace ImageProcessor.Imaging.Filters
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="factory">
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
/// the image to process.
/// </param>
/// <param name="image">The current image to process</param>
/// <param name="newImage">The new Image to return</param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// The processed image.
/// </returns>
public override Image TransformImage(ImageFactory factory, Image image, Image newImage)
public override Image TransformImage(Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{

12
src/ImageProcessor/Imaging/Filters/HiSatchMatrixFilter.cs → src/ImageProcessor/Imaging/Filters/Photo/HiSatchMatrixFilter.cs

@ -8,12 +8,10 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Filters
namespace ImageProcessor.Imaging.Filters.Photo
{
#region Using
using System.Drawing;
using System.Drawing.Imaging;
#endregion
/// <summary>
/// Encapsulates methods with which to add a high saturated filter to an image.
@ -31,16 +29,12 @@ namespace ImageProcessor.Imaging.Filters
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="factory">
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
/// the image to process.
/// </param>
/// <param name="image">The current image to process</param>
/// <param name="newImage">The new Image to return</param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// The processed image.
/// </returns>
public override Image TransformImage(ImageFactory factory, Image image, Image newImage)
public override Image TransformImage(Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{

12
src/ImageProcessor/Imaging/Filters/IMatrixFilter.cs → src/ImageProcessor/Imaging/Filters/Photo/IMatrixFilter.cs

@ -8,12 +8,10 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Filters
namespace ImageProcessor.Imaging.Filters.Photo
{
#region Using
using System.Drawing;
using System.Drawing.Imaging;
#endregion
/// <summary>
/// Defines properties and methods for ColorMatrix based filters.
@ -25,20 +23,14 @@ namespace ImageProcessor.Imaging.Filters
/// </summary>
ColorMatrix Matrix { get; }
#region Methods
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="factory">
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
/// the image to process.
/// </param>
/// <param name="image">The current image to process</param>
/// <param name="newImage">The new Image to return</param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
Image TransformImage(ImageFactory factory, Image image, Image newImage);
#endregion
Image TransformImage(Image image, Image newImage);
}
}

12
src/ImageProcessor/Imaging/Filters/InvertMatrixFilter.cs → src/ImageProcessor/Imaging/Filters/Photo/InvertMatrixFilter.cs

@ -8,12 +8,10 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Filters
namespace ImageProcessor.Imaging.Filters.Photo
{
#region Using
using System.Drawing;
using System.Drawing.Imaging;
#endregion
/// <summary>
/// Encapsulates methods with which to add an inverted filter to an image.
@ -31,16 +29,12 @@ namespace ImageProcessor.Imaging.Filters
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="factory">
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
/// the image to process.
/// </param>
/// <param name="image">The current image to process</param>
/// <param name="newImage">The new Image to return</param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// The processed image.
/// </returns>
public override Image TransformImage(ImageFactory factory, Image image, Image newImage)
public override Image TransformImage(Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{

12
src/ImageProcessor/Imaging/Filters/LoSatchMatrixFilter.cs → src/ImageProcessor/Imaging/Filters/Photo/LoSatchMatrixFilter.cs

@ -8,12 +8,10 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Filters
namespace ImageProcessor.Imaging.Filters.Photo
{
#region Using
using System.Drawing;
using System.Drawing.Imaging;
#endregion
/// <summary>
/// Encapsulates methods with which to add a low saturated filter to an image.
@ -31,16 +29,12 @@ namespace ImageProcessor.Imaging.Filters
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="factory">
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
/// the image to process.
/// </param>
/// <param name="image">The current image to process</param>
/// <param name="newImage">The new Image to return</param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// The processed image.
/// </returns>
public override Image TransformImage(ImageFactory factory, Image image, Image newImage)
public override Image TransformImage(Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{

19
src/ImageProcessor/Imaging/Filters/LomographMatrixFilter.cs → src/ImageProcessor/Imaging/Filters/Photo/LomographMatrixFilter.cs

@ -8,13 +8,12 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Filters
namespace ImageProcessor.Imaging.Filters.Photo
{
#region Using
using System.Drawing;
using System.Drawing.Imaging;
using ImageProcessor.Processors;
#endregion
using ImageProcessor.Imaging.Helpers;
/// <summary>
/// Encapsulates methods with which to add a lomograph filter to an image.
@ -32,16 +31,12 @@ namespace ImageProcessor.Imaging.Filters
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="factory">
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
/// the image to process.
/// </param>
/// <param name="image">The current image to process</param>
/// <param name="newImage">The new Image to return</param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// The processed image.
/// </returns>
public override Image TransformImage(ImageFactory factory, Image image, Image newImage)
public override Image TransformImage(Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{
@ -55,9 +50,7 @@ namespace ImageProcessor.Imaging.Filters
}
// Add a vignette to finish the effect.
factory.Image = newImage;
Vignette vignette = new Vignette();
newImage = vignette.ProcessImage(factory);
newImage = Effects.Vignette((Bitmap)newImage, Color.Black);
// Reassign the image.
image.Dispose();

11
src/ImageProcessor/Imaging/Filters/MatrixFilterBase.cs → src/ImageProcessor/Imaging/Filters/Photo/MatrixFilterBase.cs

@ -8,7 +8,7 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Filters
namespace ImageProcessor.Imaging.Filters.Photo
{
using System.Drawing;
using System.Drawing.Imaging;
@ -26,15 +26,12 @@ namespace ImageProcessor.Imaging.Filters
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="factory">The current instance of the
/// <see cref="T:ImageProcessor.ImageFactory" /> class containing
/// the image to process.</param>
/// <param name="image">The current image to process</param>
/// <param name="newImage">The new Image to return</param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory" /> class.
/// The processed image.
/// </returns>
public abstract Image TransformImage(ImageFactory factory, Image image, Image newImage);
public abstract Image TransformImage(Image image, Image newImage);
/// <summary>
/// Determines whether the specified <see cref="IMatrixFilter" />, is equal to this instance.
@ -64,7 +61,7 @@ namespace ImageProcessor.Imaging.Filters
/// </returns>
public override int GetHashCode()
{
return this.GetType().Name.GetHashCode() + this.Matrix.GetHashCode();
return this.GetType().Name.GetHashCode() ^ this.Matrix.GetHashCode();
}
}
}

2
src/ImageProcessor/Imaging/Filters/MatrixFilters.cs → src/ImageProcessor/Imaging/Filters/Photo/MatrixFilters.cs

@ -8,7 +8,7 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Filters
namespace ImageProcessor.Imaging.Filters.Photo
{
using ImageProcessor.Processors;

69
src/ImageProcessor/Imaging/Filters/Photo/PolaroidMatrixFilter.cs

@ -0,0 +1,69 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PolaroidMatrixFilter.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Encapsulates methods with which to add a Polaroid filter to an image.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Filters.Photo
{
using System.Drawing;
using System.Drawing.Imaging;
using ImageProcessor.Imaging.Helpers;
/// <summary>
/// Encapsulates methods with which to add a Polaroid filter to an image.
/// </summary>
internal class PolaroidMatrixFilter : MatrixFilterBase
{
/// <summary>
/// Gets the <see cref="T:System.Drawing.Imaging.ColorMatrix"/> for this filter instance.
/// </summary>
public override ColorMatrix Matrix
{
get { return ColorMatrixes.Polaroid; }
}
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="image">The current image to process</param>
/// <param name="newImage">The new Image to return</param>
/// <returns>
/// The processed image.
/// </returns>
public override Image TransformImage(Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{
using (ImageAttributes attributes = new ImageAttributes())
{
attributes.SetColorMatrix(this.Matrix);
Rectangle rectangle = new Rectangle(0, 0, image.Width, image.Height);
graphics.DrawImage(image, rectangle, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
}
}
// Fade the contrast
newImage = Adjustments.Contrast((Bitmap)newImage, -30);
// Add a glow to the image.
newImage = Effects.Glow((Bitmap)newImage, Color.FromArgb(70, 255, 153, 102));
// Add a vignette to finish the effect.
newImage = Effects.Vignette((Bitmap)newImage, Color.FromArgb(80, 0, 0));
// Reassign the image.
image.Dispose();
image = newImage;
return image;
}
}
}

12
src/ImageProcessor/Imaging/Filters/SepiaMatrixFilter.cs → src/ImageProcessor/Imaging/Filters/Photo/SepiaMatrixFilter.cs

@ -8,12 +8,10 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Filters
namespace ImageProcessor.Imaging.Filters.Photo
{
#region Using
using System.Drawing;
using System.Drawing.Imaging;
#endregion
/// <summary>
/// Encapsulates methods with which to add a sepia filter to an image.
@ -31,16 +29,12 @@ namespace ImageProcessor.Imaging.Filters
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="factory">
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
/// the image to process.
/// </param>
/// <param name="image">The current image to process</param>
/// <param name="newImage">The new Image to return</param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// The processed image.
/// </returns>
public override Image TransformImage(ImageFactory factory, Image image, Image newImage)
public override Image TransformImage(Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{

99
src/ImageProcessor/Imaging/Filters/PolaroidMatrixFilter.cs

@ -1,99 +0,0 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PolaroidMatrixFilter.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Encapsulates methods with which to add a Polaroid filter to an image.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Filters
{
#region Using
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using ImageProcessor.Processors;
#endregion
/// <summary>
/// Encapsulates methods with which to add a Polaroid filter to an image.
/// </summary>
internal class PolaroidMatrixFilter : MatrixFilterBase
{
/// <summary>
/// Gets the <see cref="T:System.Drawing.Imaging.ColorMatrix"/> for this filter instance.
/// </summary>
public override ColorMatrix Matrix
{
get { return ColorMatrixes.Polaroid; }
}
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="factory">
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
/// the image to process.
/// </param>
/// <param name="image">The current image to process</param>
/// <param name="newImage">The new Image to return</param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
public override Image TransformImage(ImageFactory factory, Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{
using (ImageAttributes attributes = new ImageAttributes())
{
attributes.SetColorMatrix(this.Matrix);
Rectangle rectangle = new Rectangle(0, 0, image.Width, image.Height);
graphics.DrawImage(image, rectangle, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
// Add a glow to the image.
using (GraphicsPath path = new GraphicsPath())
{
path.AddEllipse(rectangle);
using (PathGradientBrush brush = new PathGradientBrush(path))
{
// Fill a rectangle with an elliptical gradient brush that goes from orange to transparent.
// This has the effect of painting the far corners transparent and fading in to orange on the
// way in to the centre.
brush.WrapMode = WrapMode.Tile;
brush.CenterColor = Color.FromArgb(70, 255, 153, 102);
brush.SurroundColors = new[] { Color.FromArgb(0, 0, 0, 0) };
Blend blend = new Blend
{
Positions = new[] { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0F },
Factors = new[] { 0.0f, 0.5f, 1f, 1f, 1.0f, 1.0f }
};
brush.Blend = blend;
Region oldClip = graphics.Clip;
graphics.Clip = new Region(rectangle);
graphics.FillRectangle(brush, rectangle);
graphics.Clip = oldClip;
}
}
}
}
// Add a vignette to finish the effect.
factory.Image = newImage;
Vignette vignette = new Vignette();
newImage = vignette.ProcessImage(factory);
// Reassign the image.
image.Dispose();
image = newImage;
return image;
}
}
}

126
src/ImageProcessor/Imaging/Helpers/Adjustments.cs

@ -0,0 +1,126 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Adjustments.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Provides reusable adjustment methods to apply to images.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Helpers
{
using System;
using System.Drawing;
using System.Drawing.Imaging;
/// <summary>
/// Provides reusable adjustment methods to apply to images.
/// </summary>
public static class Adjustments
{
/// <summary>
/// Adjusts the brightness component of the given image.
/// </summary>
/// <param name="source">
/// The <see cref="Bitmap"/> source to adjust.
/// </param>
/// <param name="threshold">
/// The threshold value between -100 and 100 for adjusting the brightness.
/// </param>
/// <param name="rectangle">The rectangle to define the bounds of the area to adjust the brightness.
/// If null then the effect is applied to the entire image.</param>
/// <returns>
/// The <see cref="Bitmap"/> with the brightness adjusted.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException">
/// Thrown if the threshold value falls outside the acceptable range.
/// </exception>
public static Bitmap Brightness(Bitmap source, int threshold, Rectangle? rectangle = null)
{
if (threshold > 100 || threshold < -100)
{
throw new ArgumentOutOfRangeException("threshold", "Threshold should be between -100 and 100.");
}
float brightnessFactor = (float)threshold / 100;
Rectangle bounds = rectangle.HasValue ? rectangle.Value : new Rectangle(0, 0, source.Width, source.Height);
ColorMatrix colorMatrix =
new ColorMatrix(
new[]
{
new float[] { 1, 0, 0, 0, 0 },
new float[] { 0, 1, 0, 0, 0 },
new float[] { 0, 0, 1, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new[] { brightnessFactor, brightnessFactor, brightnessFactor, 0, 1 }
});
using (Graphics graphics = Graphics.FromImage(source))
{
using (ImageAttributes imageAttributes = new ImageAttributes())
{
imageAttributes.SetColorMatrix(colorMatrix);
graphics.DrawImage(source, bounds, 0, 0, source.Width, source.Height, GraphicsUnit.Pixel, imageAttributes);
}
}
return source;
}
/// <summary>
/// Adjusts the contrast component of the given image.
/// </summary>
/// <param name="source">
/// The <see cref="Bitmap"/> source to adjust.
/// </param>
/// <param name="threshold">
/// The threshold value between -100 and 100 for adjusting the contrast.
/// </param>
/// <param name="rectangle">The rectangle to define the bounds of the area to adjust the contrast.
/// If null then the effect is applied to the entire image.</param>
/// <returns>
/// The <see cref="Bitmap"/> with the contrast adjusted.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException">
/// Thrown if the threshold value falls outside the acceptable range.
/// </exception>
public static Bitmap Contrast(Bitmap source, int threshold, Rectangle? rectangle = null)
{
if (threshold > 100 || threshold < -100)
{
throw new ArgumentOutOfRangeException("threshold", "Threshold should be between -100 and 100.");
}
Rectangle bounds = rectangle.HasValue ? rectangle.Value : new Rectangle(0, 0, source.Width, source.Height);
float contrastFactor = (float)threshold / 100;
// Stop at -1 to prevent inversion.
contrastFactor++;
float factorTransform = 0.5f * (1.0f - contrastFactor);
ColorMatrix colorMatrix = new ColorMatrix(
new[]
{
new[] { contrastFactor, 0, 0, 0, 0 },
new[] { 0, contrastFactor, 0, 0, 0 },
new[] { 0, 0, contrastFactor, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new[] { factorTransform, factorTransform, factorTransform, 0, 1 }
});
using (Graphics graphics = Graphics.FromImage(source))
{
using (ImageAttributes imageAttributes = new ImageAttributes())
{
imageAttributes.SetColorMatrix(colorMatrix);
graphics.DrawImage(source, bounds, 0, 0, source.Width, source.Height, GraphicsUnit.Pixel, imageAttributes);
}
}
return source;
}
}
}

112
src/ImageProcessor/Imaging/Helpers/Effects.cs

@ -0,0 +1,112 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Effects.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Provides reusable effect methods to apply to images.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.Helpers
{
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
/// <summary>
/// Provides reusable effect methods to apply to images.
/// </summary>
public static class Effects
{
/// <summary>
/// Adds a vignette effect to the source image based on the given color.
/// </summary>
/// <param name="source">
/// The <see cref="Bitmap"/> source.
/// </param>
/// <param name="baseColor">
/// <see cref="Color"/> to base the vignette on.
/// </param>
/// <param name="rectangle">
/// The rectangle to define the bounds of the area to vignette. If null then the effect is applied
/// to the entire image.
/// </param>
/// <param name="invert">
/// Whether to invert the vignette.
/// </param>
/// <returns>
/// The <see cref="Bitmap"/> with the vignette applied.
/// </returns>
public static Bitmap Vignette(Bitmap source, Color baseColor, Rectangle? rectangle = null, bool invert = false)
{
using (Graphics graphics = Graphics.FromImage(source))
{
Rectangle bounds = rectangle.HasValue ? rectangle.Value : new Rectangle(0, 0, source.Width, source.Height);
Rectangle ellipsebounds = bounds;
// Increase the rectangle size by the difference between the rectangle dimensions and sqrt(2)/2 * the rectangle dimensions.
// Why sqrt(2)/2? Because the point (sqrt(2)/2, sqrt(2)/2) is the 45 degree angle point on a unit circle. Scaling by the width
// and height gives the distance needed to inflate the rectangle to make sure it's fully covered.
ellipsebounds.Offset(-ellipsebounds.X, -ellipsebounds.Y);
int x = ellipsebounds.Width - (int)Math.Floor(.70712 * ellipsebounds.Width);
int y = ellipsebounds.Height - (int)Math.Floor(.70712 * ellipsebounds.Height);
ellipsebounds.Inflate(x, y);
using (GraphicsPath path = new GraphicsPath())
{
path.AddEllipse(ellipsebounds);
using (PathGradientBrush brush = new PathGradientBrush(path))
{
// Fill a rectangle with an elliptical gradient brush that goes from transparent to opaque.
// This has the effect of painting the far corners with the given color and shade less on the way in to the centre.
Color centerColor;
Color edgeColor;
if (invert)
{
centerColor = Color.FromArgb(50, baseColor.R, baseColor.G, baseColor.B);
edgeColor = Color.FromArgb(0, baseColor.R, baseColor.G, baseColor.B);
}
else
{
centerColor = Color.FromArgb(0, baseColor.R, baseColor.G, baseColor.B);
edgeColor = Color.FromArgb(255, baseColor.R, baseColor.G, baseColor.B);
}
brush.WrapMode = WrapMode.Tile;
brush.CenterColor = centerColor;
brush.SurroundColors = new[] { edgeColor };
Blend blend = new Blend
{
Positions = new[] { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0F },
Factors = new[] { 0.0f, 0.5f, 1f, 1f, 1.0f, 1.0f }
};
brush.Blend = blend;
Region oldClip = graphics.Clip;
graphics.Clip = new Region(bounds);
graphics.FillRectangle(brush, ellipsebounds);
graphics.Clip = oldClip;
}
}
}
return source;
}
/// <summary>
/// Adds a diffused glow (inverted vignette) effect to the source image based on the given color.
/// </summary>
/// <param name="source">The <see cref="Bitmap"/> source.</param>
/// <param name="baseColor"><see cref="Color"/> to base the vignette on.</param>
/// <param name="rectangle">The rectangle to define the bounds of the area to vignette. If null then the effect is applied
/// to the entire image.</param>
/// <returns>The <see cref="Bitmap"/> with the vignette applied.</returns>
public static Bitmap Glow(Bitmap source, Color baseColor, Rectangle? rectangle = null)
{
return Vignette(source, baseColor, rectangle, true);
}
}
}

38
src/ImageProcessor/Processors/Brightness.cs

@ -16,6 +16,7 @@ namespace ImageProcessor.Processors
using System.Drawing.Imaging;
using ImageProcessor.Common.Exceptions;
using ImageProcessor.Imaging.Helpers;
/// <summary>
/// Encapsulates methods to change the brightness component of the image.
@ -65,39 +66,12 @@ namespace ImageProcessor.Processors
try
{
float brightnessFactor = (float)this.DynamicParameter / 100;
int threshold = (int)this.DynamicParameter;
newImage = new Bitmap(image);
newImage = Adjustments.Brightness(newImage, threshold);
newImage = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppPArgb);
ColorMatrix colorMatrix =
new ColorMatrix(
new[]
{
new float[] { 1, 0, 0, 0, 0 }, new float[] { 0, 1, 0, 0, 0 },
new float[] { 0, 0, 1, 0, 0 }, new float[] { 0, 0, 0, 1, 0 },
new[] { brightnessFactor, brightnessFactor, brightnessFactor, 0, 1 }
});
using (Graphics graphics = Graphics.FromImage(newImage))
{
using (ImageAttributes imageAttributes = new ImageAttributes())
{
imageAttributes.SetColorMatrix(colorMatrix);
graphics.DrawImage(
image,
new Rectangle(0, 0, image.Width, image.Height),
0,
0,
image.Width,
image.Height,
GraphicsUnit.Pixel,
imageAttributes);
image.Dispose();
image = newImage;
}
}
image.Dispose();
image = newImage;
}
catch (Exception ex)
{

36
src/ImageProcessor/Processors/Contrast.cs

@ -13,9 +13,9 @@ namespace ImageProcessor.Processors
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using ImageProcessor.Common.Exceptions;
using ImageProcessor.Imaging.Helpers;
/// <summary>
/// Encapsulates methods to change the contrast component of the image.
@ -65,36 +65,12 @@ namespace ImageProcessor.Processors
try
{
float contrastFactor = (float)this.DynamicParameter / 100;
int threshold = (int)this.DynamicParameter;
newImage = new Bitmap(image);
newImage = Adjustments.Contrast(newImage, threshold);
// Stop at -1 to prevent inversion.
contrastFactor++;
float factorTransform = 0.5f * (1.0f - contrastFactor);
newImage = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppPArgb);
ColorMatrix colorMatrix = new ColorMatrix(
new[]
{
new[] { contrastFactor, 0, 0, 0, 0 },
new[] { 0, contrastFactor, 0, 0, 0 },
new[] { 0, 0, contrastFactor, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new[] { factorTransform, factorTransform, factorTransform, 0, 1 }
});
using (Graphics graphics = Graphics.FromImage(newImage))
{
using (ImageAttributes imageAttributes = new ImageAttributes())
{
imageAttributes.SetColorMatrix(colorMatrix);
graphics.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imageAttributes);
image.Dispose();
image = newImage;
}
}
image.Dispose();
image = newImage;
}
catch (Exception ex)
{

2
src/ImageProcessor/Processors/DetectEdges.cs

@ -15,7 +15,7 @@ namespace ImageProcessor.Processors
using System.Drawing;
using ImageProcessor.Common.Exceptions;
using ImageProcessor.Imaging.EdgeDetection;
using ImageProcessor.Imaging.Filters.EdgeDetection;
/// <summary>
/// Produces an image with the detected edges highlighted.

23
src/ImageProcessor/Processors/EntropyCrop.cs

@ -14,8 +14,8 @@ namespace ImageProcessor.Processors
using ImageProcessor.Common.Exceptions;
using ImageProcessor.Imaging;
using ImageProcessor.Imaging.Binarization;
using ImageProcessor.Imaging.EdgeDetection;
using ImageProcessor.Imaging.Filters.Binarization;
using ImageProcessor.Imaging.Filters.EdgeDetection;
/// <summary>
/// The auto crop.
@ -62,7 +62,7 @@ namespace ImageProcessor.Processors
grey = new ConvolutionFilter(new SobelEdgeFilter(), true).ProcessFilter((Bitmap)image);
grey = new BinaryThreshold(threshold).ProcessFilter(grey);
Rectangle rectangle = this.FindBox(grey, 0);
Rectangle rectangle = this.FindBoundingBox(grey, 0);
newImage = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb);
using (Graphics graphics = Graphics.FromImage(newImage))
@ -100,7 +100,20 @@ namespace ImageProcessor.Processors
return image;
}
private Rectangle FindBox(Bitmap bitmap, byte componentToRemove)
/// <summary>
/// Finds the bounding rectangle based on the first instance of any color component other
/// than the given one.
/// </summary>
/// <param name="bitmap">
/// The bitmap.
/// </param>
/// <param name="componentToRemove">
/// The color component to remove.
/// </param>
/// <returns>
/// The <see cref="Rectangle"/>.
/// </returns>
private Rectangle FindBoundingBox(Bitmap bitmap, byte componentToRemove)
{
int width = bitmap.Width;
int height = bitmap.Height;
@ -115,8 +128,6 @@ namespace ImageProcessor.Processors
{
for (int x = 0; x < width; x++)
{
Color c = fastBitmap.GetPixel(x, y);
if (fastBitmap.GetPixel(x, y).B != componentToRemove)
{
return y;

4
src/ImageProcessor/Processors/Filter.cs

@ -16,7 +16,7 @@ namespace ImageProcessor.Processors
using System.Drawing.Imaging;
using ImageProcessor.Common.Exceptions;
using ImageProcessor.Imaging.Filters;
using ImageProcessor.Imaging.Filters.Photo;
/// <summary>
/// Encapsulates methods with which to add filters to an image.
@ -71,7 +71,7 @@ namespace ImageProcessor.Processors
if (matrix != null)
{
return matrix.TransformImage(factory, image, newImage);
return matrix.TransformImage(image, newImage);
}
}
catch (Exception ex)

53
src/ImageProcessor/Processors/Vignette.cs

@ -13,9 +13,9 @@ namespace ImageProcessor.Processors
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using ImageProcessor.Common.Exceptions;
using ImageProcessor.Imaging.Helpers;
/// <summary>
/// Encapsulates methods with which to add a vignette image effect to an image.
@ -66,55 +66,14 @@ namespace ImageProcessor.Processors
try
{
Color baseColor = (Color)this.DynamicParameter;
newImage = new Bitmap(image);
using (Graphics graphics = Graphics.FromImage(newImage))
{
Rectangle bounds = new Rectangle(0, 0, newImage.Width, newImage.Height);
Rectangle ellipsebounds = bounds;
// Increase the rectangle size by the difference between the rectangle dimensions and sqrt(2)/2 * the rectangle dimensions.
// Why sqrt(2)/2? Because the point (sqrt(2)/2, sqrt(2)/2) is the 45 degree angle point on a unit circle. Scaling by the width
// and height gives the distance needed to inflate the rect to make sure it's fully covered.
ellipsebounds.Offset(-ellipsebounds.X, -ellipsebounds.Y);
int x = ellipsebounds.Width - (int)Math.Floor(.70712 * ellipsebounds.Width);
int y = ellipsebounds.Height - (int)Math.Floor(.70712 * ellipsebounds.Height);
ellipsebounds.Inflate(x, y);
using (GraphicsPath path = new GraphicsPath())
{
path.AddEllipse(ellipsebounds);
using (PathGradientBrush brush = new PathGradientBrush(path))
{
// Fill a rectangle with an elliptical gradient brush that goes from transparent to opaque.
// This has the effect of painting the far corners with the given color and shade less on the way in to the centre.
Color baseColor = (Color)this.DynamicParameter;
Color centerColor = Color.FromArgb(0, baseColor.R, baseColor.G, baseColor.B);
Color edgeColor = Color.FromArgb(255, baseColor.R, baseColor.G, baseColor.B);
brush.WrapMode = WrapMode.Tile;
brush.CenterColor = centerColor;
brush.SurroundColors = new[] { edgeColor };
Blend blend = new Blend
{
Positions = new[] { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0F },
Factors = new[] { 0.0f, 0.5f, 1f, 1f, 1.0f, 1.0f }
};
newImage = Effects.Vignette(newImage, baseColor);
brush.Blend = blend;
Region oldClip = graphics.Clip;
graphics.Clip = new Region(bounds);
graphics.FillRectangle(brush, ellipsebounds);
graphics.Clip = oldClip;
}
// Reassign the image.
image.Dispose();
image = newImage;
}
}
// Reassign the image.
image.Dispose();
image = newImage;
}
catch (Exception ex)
{

4
src/ImageProcessorConsole/ImageProcessorConsole.csproj → src/ImageProcessorConsole/ImageProcessor.Playground.csproj

@ -7,8 +7,8 @@
<ProjectGuid>{7BF5274B-56A7-4B62-8105-E9BDF25BAFE7}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ImageProcessorConsole</RootNamespace>
<AssemblyName>ImageProcessorConsole</AssemblyName>
<RootNamespace>ImageProcessor.PlayGround</RootNamespace>
<AssemblyName>ImageProcessor.PlayGround</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>

13
src/ImageProcessorConsole/Program.cs

@ -8,7 +8,7 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessorConsole
namespace ImageProcessor.PlayGround
{
using System;
using System.Collections.Generic;
@ -16,12 +16,10 @@ namespace ImageProcessorConsole
using System.Drawing;
using System.IO;
using System.Linq;
using ImageProcessor;
using ImageProcessor.Imaging;
using ImageProcessor.Imaging.EdgeDetection;
using ImageProcessor.Imaging.Filters;
using ImageProcessor.Plugins.Cair;
using ImageProcessor.Plugins.Cair.Imaging;
using ImageProcessor.Imaging.Filters.Photo;
/// <summary>
/// The program.
@ -46,7 +44,7 @@ namespace ImageProcessorConsole
di.Create();
}
IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".png2");
IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".jpg");
//IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".gif", ".webp", ".bmp", ".jpg", ".png", ".tif");
foreach (FileInfo fileInfo in files)
@ -78,7 +76,8 @@ namespace ImageProcessorConsole
//.ReplaceColor(Color.FromArgb(255, 1, 107, 165), Color.FromArgb(255, 1, 165, 13), 80)
//.Resize(layer)
//.DetectEdges(new KirschEdgeFilter())
.EntropyCrop()
//.EntropyCrop()
.Filter(MatrixFilters.Polaroid)
//.Filter(MatrixFilters.Comic)
//.Filter(MatrixFilters.HiSatch)
//.Pixelate(8)

1
src/ImageProcessorConsole/images/input/new-york.jpg.REMOVED.git-id

@ -0,0 +1 @@
d04aa90445e483d5614cf597cbd7caa6d55d9aaa

1
src/ImageProcessorConsole/images/output/monster-whitebg.png.REMOVED.git-id

@ -1 +0,0 @@
e40fa501c49374e25d137627084dfa993931205f
Loading…
Cancel
Save